<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

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

        作者:我行天下   來源:本站原創   點擊數:  更新時間:2014年03月31日   【字體:


        /*本程序為八位共陰極數碼管且有兩個573控制的動態掃描*/
        /*此程序為開機記憶,可以每次開機分自動加一。如果加了,說明操作成功*/
        /*本程序把24C08的SCL和SDA分別接在MCU的SCL(PC0第22腳)和SDA(PC1第23腳)*/
        //24C08的第7腳WP接地
        #include <iom16v.h>
        #include <macros.h>//這里面有BIT(),所以要包含
        #define uchar unsigned char
        #define uint unsigned int
        #pragma data:code //注code的功能是把后面的數據存在程序存貯器中,不用code就放到了隨機存貯器中.
        uchar const table[]={0x3f,0x06,0x5b,0x4f,0x66,
        0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00} ;
        /*如果用uchar table[]就放到了數據存貯器中。決不要這樣用,這樣占用空間多。*/
        /*兩個573,段碼PA3,位碼PA4*/
        /****************************
         I2C 狀態定義
         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為主機發送,MR為主機接收
        //上述定義中,SLA是對地址操作,DATA是對數據操作
        /*常用TWI操作(主模式寫和讀)*/
        #define Start()   TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)  //啟動I2C
        #define Stop()   TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)  //停止I2C
        #define Wait()   while(!(TWCR&(1<<TWINT)))    //等待中斷發生
        #define TestAck()  TWSR&0xf8        //觀察返回狀態
        #define SetAck   TWCR|=(1<<TWEA)       //做出ACK應答
        #define SetNoAck  TWCR&=~(1<<TWEA)       //做出Not Ack應答
        #define Twi()  TWCR=(1<<TWINT)|(1<<TWEN)    //啟動I2C
        #define Write8Bit(x) TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN)  //寫數據到TWDR
        /*延時子程序*/
        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分頻就可以了,就是不用分頻,就用晶振頻率
        }

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

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

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

        Write8Bit(add);//寫入要讀出數據的地址
        Wait();//等待
        if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
        return 1;
        //DATA是對數據應答
        Start();//重復發送啟始位
        Wait();//等待
        if(TestAck()!=RE_START)//也可寫成if(TestAck!=0X10)
        return 1;
        Write8Bit(RD_24C08_add);//告訴24C08,現在要讀操作,也可寫成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);
          }
        }
         

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮