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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > IAR For AVR 兩線串行接口 TWI 應(yīng)用

          IAR For AVR 兩線串行接口 TWI 應(yīng)用

          作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò) 收藏
          ATMEL的TWI 和 PHILIPS的IIC 基本上應(yīng)該是算一個(gè)東西,但是他們?cè)诿x上是不同的,這樣誰(shuí)都不用支付給對(duì)方使用費(fèi)。他們的協(xié)議是一樣的,所有我們作為使用者基本可以簡(jiǎn)單的看成 TWI就是IIC 。

          廢話說(shuō)完,開(kāi)始正題。這次是關(guān)于在ATMega16 平臺(tái)下的硬件IIC(還不太習(xí)慣說(shuō)TWI)的使用。在ATMega16的Datasheet里我們可以看到很強(qiáng)大的功能,主從設(shè)置很多。本文只說(shuō)一種最常用的方式,那就是“ATMega16 硬件TWI 的 掃描發(fā)送 和 掃描讀取”。

          本文引用地址:http://cafeforensic.com/article/201612/325112.htm

          首先要明確TWI 發(fā)送和接受的流程:

          發(fā)送:

          1,設(shè)定數(shù)據(jù)傳輸波特率

          2,發(fā)送START信號(hào),等待應(yīng)答 ==》 《== 應(yīng)答信號(hào)

          3,發(fā)送芯片地址,等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          4,發(fā)送數(shù)據(jù)的絕對(duì)地址,等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          5,發(fā)送要寫入的數(shù)據(jù),等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          6,發(fā)送STOP信號(hào),釋放總線 ==》 數(shù)據(jù)寫入成功

          接收:

          1,設(shè)定數(shù)據(jù)傳輸波特率

          2,發(fā)送START信號(hào),等待應(yīng)答 ==》 《== 應(yīng)答信號(hào)

          3,發(fā)送芯片地址,等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          4,發(fā)送數(shù)據(jù)的絕對(duì)地址,等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          5,發(fā)送RESTART信號(hào),等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          6,發(fā)送芯片地址并注明讀操作,等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          7,讀取數(shù)據(jù),等待應(yīng)答 ==》 《==應(yīng)答信號(hào)

          8,發(fā)送STOP信號(hào),釋放總線 ==》 數(shù)據(jù)讀操作成功

          應(yīng)用芯片 :ATMega 16 晶振 : 7.3728

          代碼文件:Project

          |___TWI.C

          | |_____ IAR_DELAY.H

          |___UART.C

          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

          IAR_DELAY.H

          #ifndef __IAR_DELAY_H
          #define __IAR_DELAY_H

          #include

          #define XTAL 7.3728 //可定義為你所用的晶振頻率(單位Mhz)


          #define delay_us(x) __delay_cycles ( (unsigned long)(x * XTAL) )
          #define delay_ms(x) __delay_cycles ( (unsigned long)(x * XTAL*1000) )
          #define delay_s(x) __delay_cycles ( (unsigned long)(x * XTAL*1000000) )

          #endif

          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

          UART.C

          #include
          #define uchar unsigned char
          #define uint unsigned int

          //###########################################################
          /*串口初始化函數(shù)*/
          voidUart_Init(void)
          {
          UCSRB = (1<UCSRC = (1<

          UBRRH=0x00; //設(shè)置波特率寄存器低位字節(jié)
          UBRRL=47; //9600 //設(shè)置波特率寄存器高位字節(jié)

          DDRD_Bit1=1; //配置TX為輸出(很重要)
          }
          //###########################################################
          /*發(fā)送一個(gè)字符數(shù)據(jù),查詢方式*/
          voidUart_Transmit(uchar data)
          {
          while(!(UCSRA&(1< //while(UCSRA_UDRE==0); /* 等待發(fā)送緩沖器為空*/
          UDR = data; /* 發(fā)送數(shù)據(jù)*/
          }

          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

          #include
          #include "IAR_DELAY.H"
          #define uchar unsigned char
          #define uint unsigned int

          void Uart_Init(void);
          void Uart_Transmit(uchar data);


          //變量聲明
          #define EEPROM_BUS_ADDRESS 0xA0 //器件地址
          /*#####################################################################*/
          /*從器件地址位定義:______________________________________-------------*/
          /* AT24C02 | 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |------------*/
          /* ---------------------------------------------------*/
          /*#####################################################################*/
          //主機(jī)發(fā)送模式時(shí)各狀態(tài)字的后續(xù)動(dòng)作
          #define TW_START 0x08 //開(kāi)始信號(hào)已發(fā)出
          #define TW_REP_START 0x10 //重復(fù)開(kāi)始信號(hào)已發(fā)出
          #define TW_MT_SLA_ACK 0x18 //寫字節(jié)已發(fā)出并受到ACK信號(hào)
          #define TW_MT_SLA_NACK 0x20 //寫字節(jié)已發(fā)出并受到NACK信號(hào)
          #define TW_MT_DATA_ACK 0x28 //數(shù)據(jù)已發(fā)出并受到ACK 信號(hào)
          #define TW_MT_DATA_NACK 0x30 //數(shù)據(jù)已發(fā)出并受到NACK 信號(hào)
          #define TW_MT_ARB_LOST 0x38 //丟失總線控制權(quán)
          //主機(jī)接收模式時(shí)各狀態(tài)字的后續(xù)動(dòng)作
          #define TW_MR_ARB_LOST 0x38 //丟失總線控制權(quán),未收到應(yīng)答信號(hào)
          #define TW_MR_SLA_ACK 0x40 //讀命令已發(fā)出并受到ACK
          #define TW_MR_SLA_NACK 0x48 //讀命令已發(fā)出并受到NACK
          #define TW_MR_DATA_ACK 0x50 //數(shù)據(jù)已收到,ACK已發(fā)出
          #define TW_MR_DATA_NACK 0x58 //數(shù)據(jù)已收到,NACK已發(fā)出

          #define IIC_Start() TWCR =(1< // TWSTA位 會(huì)讓硬件在總線上產(chǎn)生一個(gè)START的信號(hào) , 聲明自己希望成為主機(jī)
          // TWEN 位 使能TWI功能,將 PC0 和 PC1 管腳切換到第二功能上來(lái), 如果清零則為中斷 TWI的傳輸
          #define IIC_Stop() TWCR =(1<

          #define IIC_Wait() while(!(TWCR&(1<

          //##############################################################################
          /*I2C總線單字節(jié)寫入*/
          unsigned char twi_write(unsigned char addr, unsigned char dd)
          {
          TWBR = 10; //設(shè)定波特率

          /*start 啟動(dòng)*/
          IIC_Start(); //硬件發(fā)送START信號(hào),并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
          IIC_Wait(); //等待 發(fā)送START完成 TWINT位置位
          if ((TWSR & 0xF8) != 0x08) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量,如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*SLA_W 芯片地址*/
          TWDR = EEPROM_BUS_ADDRESS ; //芯片地址 0xA0 ,賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x18) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*addr 操作地址*/
          TWDR = addr; //將寫入數(shù)據(jù)的絕對(duì)地址 ,賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x28) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*dd 寫入數(shù)據(jù)*/
          TWDR = dd; //將要寫入的數(shù)據(jù) ,賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x28) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*stop 停止*/
          IIC_Stop(); //數(shù)據(jù)傳輸完成,發(fā)送STOP信號(hào),釋放對(duì)總線的控制
          return 1; //寫入數(shù)據(jù)成功 ,返回1 ,用來(lái)判斷是否成功寫入數(shù)據(jù)

          }
          //##############################################################################
          /*I2C總線單字節(jié)讀取*/
          unsigned char twi_read(unsigned char addr)
          {

          unsigned char Receive_Byte ;
          TWBR = 2; //設(shè)定波特率

          /*start 啟動(dòng)*/
          IIC_Start(); //硬件發(fā)送START信號(hào),并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
          IIC_Wait(); //等待 發(fā)送START完成 TWINT位置位
          if ((TWSR & 0xF8) != 0x08) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量,如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*SLA_W 芯片地址*/
          TWDR = EEPROM_BUS_ADDRESS; //芯片地址 0xA0 ,賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x18) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*addr 操作地址*/
          TWDR = addr; //將寫入數(shù)據(jù)的絕對(duì)地址 ,賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x28) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*restart 重啟動(dòng)*/
          IIC_Start(); //硬件發(fā)送 RESTART 信號(hào),并且清零TWINT位,使能硬件TWI,使TWI開(kāi)始工作
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x10) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*SLA_R 芯片地址*/
          TWDR = 0xA1; //芯片地址 0xA0 并注明是讀取操作(最后一位為 1 ),賦值給數(shù)據(jù)寄存器 TWDR ,等待發(fā)送
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x40) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0

          /*讀取數(shù)據(jù)*/
          TWCR = (1 << TWINT) | (1 << TWEN); //對(duì)控制寄存器TWCR的 TWINT 位軟件寫1進(jìn)行清零,然后 使能TWI硬件接口 ,讓TWI進(jìn)行工作,發(fā)送 TWDR寄存器 中的數(shù)據(jù)
          IIC_Wait(); //等待數(shù)據(jù)發(fā)送完畢 TWINT重新置位
          if ((TWSR & 0xF8) != 0x58) return 0;//檢測(cè)到TWINT位置位,比對(duì)TWSR寄存器內(nèi)的狀態(tài)量 , 如果正確則向下進(jìn)行數(shù)據(jù)傳輸,錯(cuò)誤返回 0
          Receive_Byte = TWDR; //讀取到的數(shù)據(jù)放到局部變量里

          /*stop 停止*/
          IIC_Stop(); //數(shù)據(jù)傳輸完成,發(fā)送STOP信號(hào),釋放對(duì)總線的控制

          return Receive_Byte; //將讀取到的數(shù)據(jù)作為函數(shù)的輸出


          }
          //##############################################################################
          /*主函數(shù)*/
          void main(void)
          {
          uchar c,d;
          Uart_Init(); //串口初始化
          delay_us(20);
          Uart_Transmit(0x55); //測(cè)試串口

          c = twi_write(0x51,0xf8); //在地址0x51里寫入數(shù)據(jù)0x22
          Uart_Transmit(c); //將返回值發(fā)送到串口測(cè)試是否寫入成功

          delay_ms(2);

          d = twi_read(0x51); //將地址0x51里的數(shù)據(jù)讀出來(lái)
          Uart_Transmit(d); //將讀取到的數(shù)據(jù)發(fā)送串口
          while(1);
          }



          關(guān)鍵詞: IARrAVR兩線串行接口TW

          評(píng)論


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

          關(guān)閉