色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > AVR單片機IO仿真I2C

          AVR單片機IO仿真I2C

          作者: 時間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          #include

          #define EEP_PORT PORTC //定義是使用PROTC口
          #define EEP_DDR DDRC //定義是使用PROTC口
          #define SDA 0X10 //定義sda連接的是portd1
          #define SCL 0X20 //定義scl連接的是portd0
          //#define WP 0X04 //定義wp連接的是portd2
          #define EEP_ADD_R 0xa1 //寫I2C從器件地址和讀方式 a0,a1接地
          #define EEP_ADD_W 0xa0 //寫I2C從器件地址和寫方式 a0,a1接地

          本文引用地址:http://cafeforensic.com/article/201611/315599.htm

          void delay(unsigned int us)
          {
          while(us--);
          }

          void eep_init(void)
          {
          EEP_DDR|= SDA | SCL ;//| WP ;
          EEP_PORT|=SDA | SCL ;//| WP ;
          }

          void send(void)
          {
          EEP_PORT|=SCL;
          asm("nop");
          EEP_PORT&=~SCL;
          }
          /********************************************
          內(nèi)部函數(shù),I2C開始
          ********************************************/
          void Start(void)
          {
          EEP_PORT|=SDA; //sda
          EEP_PORT|=SCL; //scl
          asm("nop");
          EEP_PORT&=~SDA;
          asm("nop");
          EEP_PORT&=~SCL;
          }
          /********************************************
          內(nèi)部函數(shù),I2C結(jié)束
          ********************************************/
          void Stop(void)
          {
          EEP_PORT&=~SDA;
          EEP_PORT&=~SCL;
          asm("nop");
          EEP_PORT|=SCL;
          asm("nop");
          EEP_PORT|=SDA;
          asm("nop");
          }

          /********************************************
          內(nèi)部函數(shù),等待ACK
          ********************************************/
          void ACK(void)
          {

          unsigned char errtime=20;
          EEP_PORT|=SDA; //上拉
          EEP_DDR&=~SDA; //設(shè)置為輸入口
          EEP_PORT|=SCL;
          asm("nop");
          while(PINC&SDA)
          { errtime--;
          if(!errtime)
          {
          Stop();
          EEP_PORT&=~SDA; //超時,給他個離開的理由
          }
          }
          EEP_PORT&=~SCL;
          asm("nop");
          EEP_DDR|=SDA; //設(shè)置為輸出口
          }
          /********************************************
          內(nèi)部函數(shù).輸出數(shù)據(jù)字節(jié)
          ********************************************/
          void writebyte(unsigned char wdata)
          {
          unsigned char i;
          for(i=0;i<8;i++)
          {
          if((wdata&0x80)){EEP_PORT|=SDA;}else{EEP_PORT&=~SDA;}
          wdata<<=1;
          send(); //發(fā)送一個位

          }
          }
          /********************************************
          內(nèi)部函數(shù).輸入數(shù)據(jù)
          ********************************************/
          unsigned char Readbyte(void)
          {
          unsigned char i,bytedata;
          EEP_DDR&=~SDA; //設(shè)置為輸入?
          for(i=0;i<8;i++)
          {
          EEP_PORT|=SCL;
          bytedata<<=1;
          if(PINC&SDA){
          bytedata|=0X01;
          }else{
          bytedata&=~0X01;
          }
          EEP_PORT&=~SCL;
          asm("nop");
          }
          EEP_DDR|=SDA;
          return(bytedata);

          }

          /********************讀24cxx--外部調(diào)用********************/
          unsigned char read_eep(unsigned char add1,unsigned char add2)
          { unsigned char mdata;
          Start(); //起始位
          writebyte(EEP_ADD_W); //寫eeprom地址+1個寫命令
          ACK(); //等待應答信號
          writebyte(add1); //寫如訪問地址
          ACK(); //等待應答信號
          writebyte(add2); //寫入訪問地址
          ACK(); //等待應答信號
          Start(); //起始位
          writebyte(EEP_ADD_R); //寫eeprom地址+1個讀命令
          ACK(); //等待應答信號
          mdata=Readbyte(); //獲取數(shù)據(jù)
          Stop(); //發(fā)送停止位置
          asm("nop"); //此處延時根據(jù)實際情況,如果不延時,可能會不正常
          return(mdata);
          }
          /********************寫24cxx--外部調(diào)用********************/
          void write_eep(unsigned char add1,unsigned char add2,unsigned char udata)
          {
          //EEP_PORT&=~WP; //關(guān)閉寫保護
          Start(); //起始位
          writebyte(EEP_ADD_W); //寫eeprom地址+1個寫命令
          ACK(); //等待應答信號
          writebyte(add1); //寫如訪問地址
          ACK(); //等待應答信號
          writebyte(add2); //寫如訪問地址
          ACK(); //等待應答信號
          writebyte(udata); //寫入數(shù)據(jù)
          ACK(); //等待應答信號
          Stop(); //發(fā)送停止位
          delay(24000);
          //delay_nms(4); //此處延時根據(jù)實際情況,大多EEPROM都需要3毫秒的寫入時間,如果不延時,可能會不正常
          //EEP_PORT|=WP; //打開寫保護
          }

          void main(void)
          {
          unsigned char tmp;
          eep_init();
          DDRC|=(1<<0);
          PORTC&=~(1<<0);
          write_eep(0,2,7);
          tmp=read_eep(0,2);
          if(tmp==7)
          PORTC|=(1<<0);
          while(1);
          }



          關(guān)鍵詞: AVR單片機IO仿真I2

          評論


          技術(shù)專區(qū)

          關(guān)閉