新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > AVR片內TWI總線(I2C總線協(xié)議)

        AVR片內TWI總線(I2C總線協(xié)議)

        作者: 時間:2016-12-02 來源:網(wǎng)絡 收藏
        /*本程序為八位共陰極數(shù)碼管且有兩個573控制的動態(tài)掃描*/

        /*此程序為開機記憶,可以每次開機分自動加一。如果加了,說明操作成功*/
        /*本程序把24C08的SCL和SDA分別接在MCU的SCL(PC0第22腳)和SDA(PC1第23腳)*/
        //24C08的第7腳WP接地
        #include
        #include //這里面有BIT(),所以要包含
        #define uchar unsigned char
        #define uint unsigned int
        #pragmadata:code //注code的功能是把后面的數(shù)據(jù)存在程序存貯器中,不用code就放到了隨機存貯器中.
        uchar const table[]={0x3f,0x06,0x5b,0x4f,0x66,
        0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00} ;
        /*如果用uchar table[]就放到了數(shù)據(jù)存貯器中。決不要這樣用,這樣占用空間多。*/
        /*兩個573,段碼PA3,位碼PA4*/
        /****************************
        I2C 狀態(tài)定義
        MT 主方式傳輸 MR 主方式接受
        ***************************/
        #define START 0x08
        #define RE_START 0x10
        #define MT_SLA_ACK 0x18
        #define MT_SLA_NOACK 0x20
        #define MT_DATA_ACK 0x28
        #define MT_DATA_NOACK 0x30
        #define MR_SLA_ACK 0x40
        #define MR_SLA_NOACK 0x48
        #define MR_DATA_ACK 0x50
        #define MR_DATA_NOACK 0x58
        #define RD_24C08_add 0xaf
        //讀24C08的地址,前4位器件固定,后三位看連線(本機全接高),最后1位是1讀指令位
        #define WD_24C08_add 0xae
        //寫24C08的地址,前4位器件固定,后三位看連線(本機全接高),最后1位是0寫指令位
        //上述定義中,MT為主機發(fā)送,MR為主機接收
        //上述定義中,SLA是對地址操作,DATA是對數(shù)據(jù)操作
        /*常用TWI操作(主模式寫和讀)*/
        #define Start() TWCR=(1<#define Stop() TWCR=(1<#define Wait() while(!(TWCR&(1<#define TestAck() TWSR&0xf8 //觀察返回狀態(tài)
        #define SetAck TWCR|=(1<#define SetNoAck TWCR&=~(1<#define Twi() TWCR=(1<#define Write8Bit(x) TWDR=(x);TWCR=(1</*延時子程序*/
        void delay_ms(int time)
        {
        int i;
        for(;time>0;time--)
        for(i=0;i<1000;i++);
        }

        void show(uchar dat,uchar wei)
        {
        DDRA|=BIT(3);//把PA3設為輸出
        DDRA|=BIT(4);//把PA4設為輸出
        DDRB=0XFF;//把PB口設為輸出型,全為高
        PORTA|=BIT(3);
        PORTB=table[dat];
        PORTA&=~BIT(3);

        PORTB=0XFF;
        PORTB&=~BIT(wei);
        PORTA|=BIT(4);
        PORTA&=~BIT(4);
        delay_ms(1);
        }
        void TWI_init()//初始化TWI總線
        {
        TWBR=0X20;//TWIA 工作在主機模式下,TWRB的值不小于10,0X20一定大于10
        TWCR=0X04;//把TWCR中,TWEN使能打開,所以是0X04
        TWSR=0;//只用1分頻就可以了,就是不用分頻,就用晶振頻率
        }

        本文引用地址:http://www.104case.com/article/201612/324679.htm

        /*********************************************
        I2C總線寫一個字節(jié) 返回0:寫成功 返回1:寫失敗
        **********************************************/

        uchar IIC_write(ucharadd,uchar dat)
        {
        Start();//發(fā)送啟始位
        Wait();//等待
        if(TestAck()!=START)//也可寫成if(TestAck!=0X80)
        return 1;
        Write8Bit(WD_24C08_add);//告訴24C08,現(xiàn)在要寫操作,也可寫成Write8bit(0xA0);
        Wait();//等待
        if(TestAck()!=MT_SLA_ACK)//也可寫成if(TestAck!=0X18)
        return 1;
        //LSA是對器件的應答
        Write8Bit(add);//寫入要寫入數(shù)據(jù)的地址
        Wait();//等待
        if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
        return 1;
        //DATA是對數(shù)據(jù)應答
        Write8Bit(dat);
        Wait();//等待
        if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
        return 1;
        Stop();//送出停止信號
        return 0;
        }

        uchar IIC_rd(ucharadd)
        {
        uchar temp;
        Start();//發(fā)送啟始位
        Wait();//等待
        if(TestAck()!=START)//也可寫成if(TestAck!=0X80)
        return 1;
        Write8Bit(WD_24C08_add);//告訴24C08,現(xiàn)在要寫操作,也可寫成Write8bit(0xA0);
        Wait();//等待
        if(TestAck()!=MT_SLA_ACK)//也可寫成if(TestAck!=0X18)
        return 1;
        //SLA是對器件的應答

        Write8Bit(add);//寫入要讀出數(shù)據(jù)的地址
        Wait();//等待
        if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
        return 1;
        //DATA是對數(shù)據(jù)應答
        Start();//重復發(fā)送啟始位
        Wait();//等待
        if(TestAck()!=RE_START)//也可寫成if(TestAck!=0X10)
        return 1;
        Write8Bit(RD_24C08_add);//告訴24C08,現(xiàn)在要讀操作,也可寫成Write8bit(0xA1);
        Wait();//等待
        if(TestAck()!=MR_SLA_ACK)//主機接收判斷,也可寫成if(TestAck!=0X40)
        return 1;
        Twi(); //須要重新啟動
        Wait();//等待
        if(TestAck()!=MR_DATA_NOACK)
        return 1;

        temp=TWDR;
        Stop();//送出停止信號
        return temp;
        }
        void main()
        {
        uchar i;
        TWI_init();
        i=IIC_rd(2);
        if(i>9)
        i=0;
        i++;
        IIC_write(2,i);
        while(1)
        {
        show(i,2);
        }
        }



        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 隆安县| 比如县| 龙胜| 张家港市| 渭南市| 灯塔市| 新绛县| 罗定市| 湟中县| 新津县| 东兴市| 大庆市| 定陶县| 玛曲县| 清镇市| 美姑县| 海丰县| 云和县| 准格尔旗| 昌图县| 洛隆县| 阳信县| 北京市| 六盘水市| 邵东县| 石景山区| 祁东县| 廊坊市| 新龙县| 东港市| 奉新县| 涿鹿县| 如皋市| 高要市| 会理县| 福泉市| 莎车县| 新民市| 沂源县| 泉州市| 长海县|