新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > stm8s開發(八) IIC的使用:IIC主機通信!

        stm8s開發(八) IIC的使用:IIC主機通信!

        作者: 時間:2017-09-19 來源:網絡 收藏

          前面講過兩個常用的串口,UART和SPI,這次這次講解一下另一個常用的串口:(I2C)通信

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

          科普:一般有兩根信號線,一根是雙向的數據線SDA,另一根是時鐘線SCL。所有接到總線設備上的串行數據SDA都接到總線的SDA上,各設備的時鐘線SCL接到總線的SCL上。

          通信過程:

          主模式時,IIC接口啟動數據傳輸并產生時鐘信號。串行數據傳輸總是以起始條件開始并以停止條件結束。起始條件和停止條件都是在主模式下由軟件控制產生。

          從模式時,IIC接口能識別它自己的地址(7位或10位)和廣播呼叫地址。軟件能夠控制開啟或禁止廣播呼叫地址的識別。

          數據和地址按8位/字節進行傳輸,高位在前。跟在起始條件后的1或2個字節是地址(7位模式為1個字節,10位模式為2個字節)。地址只在主模式發送。

          在一個字節傳輸的8個時鐘后的第9個時鐘期間,接收器必須回送一個應答位(ACK)給發送器。參考下圖。

            

         

          詳細協議可以參考:http://blog.csdn.net/subkiller/article/details/6854910

          和SPI差不多,使用IIC無非就一個初始化,一個數據發送,一個數據接收,三大功能。

          初始化分初始化為主機、從機,不過一般和外部芯片通信單片機都是作為主機。

          void IIC_Master_Init(void)

          {

          CLK_PCKENR1 |= 0x01; //使能IIC外設時鐘

          PB_DDR &= 0xcf;

          PB_CR1 &= 0xcf;

          PB_CR2 &= 0xcf;

          I2C_CR1 = 0x00; //允許時鐘延展,禁止廣播呼叫,禁止iic

          I2C_FREQR = 0x01; //輸入時鐘頻率8MHz

          I2C_OARH = 0x40; //七位地址模式

          I2C_OARL = 0xa0; //自身地址0xa0

          I2C_CCRL = 0xff; //

          I2C_CCRH = 0x00; //標準模式

          I2C_TRISER = 0x02;

          I2C_CR1 |= 0x01; //使能iic外設

          }

          這里使用的是STM8S105片上的IIC引腳PB4、PB5。另外就是需要使能IIC的時鐘。

          發送和接收數據這里只給出一個最簡單的例子,因為不同的外部芯片的通信方式不一樣,不過一般都是:

          讀操作:開始 -> 發送外設地址 -> 開始 ->發送需要讀取的寄存器地址 -> 讀一個字節 -> (可能再讀一個字節) ->。。。 -> 結束

          寫操作:開始 -> 發送外設地址 -> 發送需要寫入的寄存器地址 -> 寫一個字節 ->

          void IIC_Write_Byte(u8 DeviceAddress, u8 Address, u8 Data)

          {

          vu8 temp = 0;

          while((I2C_SR3 & 0x02) != 0); //等待IIC總線空閑

          IIC_Start();

          while((I2C_SR1 & 0x01) == 0); //EV5,起始信號已經發送

          I2C_DR = (DeviceAddress & 0xfe); // 發送iic從器件物理地址,最低位0,寫操作

          while((I2C_SR1 & 0x02) == 0); //地址已經被發送

          temp = I2C_SR1; //清除ADDR標志位

          temp = I2C_SR3;

          while((I2C_SR1 & 0x80) == 0); //等待發送寄存器為空

          I2C_DR = Address; //發送要寫入的寄存器地址

          while((I2C_SR1 & 0x04) == 0); //等待發送完成

          while((I2C_SR1 & 0x80) == 0); //等待發送寄存器為空

          I2C_DR = Data; //發送要寫入的數據

          while((I2C_SR1 & 0x04) == 0); //等待發送完成

          temp = I2C_SR1; //清零BTF標志位

          temp = I2C_DR;

          IIC_Stop(); //發送停止信號

          }

          unsigned char IIC_Read_Byte(u8 DeviceAddress, u8 Address)

          {

          vu8 temp = 0;

          short read_data = 0;

          while((I2C_SR3 & 0x02) != 0); //等待IIC總線空閑

          I2C_CR2 |= 0x04; //使能ACK

          IIC_Start();

          while((I2C_SR1 & 0x01) == 0); //EV5,起始信號已經發送

          I2C_DR = (DeviceAddress & 0xfe); // 發送iic從器件物理地址,最低位0,寫操作

          while((I2C_SR1 & 0x02) == 0); //地址已經被發送

          temp = I2C_SR1; //清除ADDR標志位

          temp = I2C_SR3;

          while((I2C_SR1 & 0x80) == 0); //等待發送寄存器為空

          I2C_DR = Address; // 發送要讀取的寄存器地址

          while((I2C_SR1 & 0x04) == 0); //等待數據發送完成

          IIC_Start();

          while((I2C_SR1 & 0x01) == 0); //EV5,起始信號已經發送

          I2C_DR = (DeviceAddress | 0x01); // 發送iic從器件物理地址,最低位1,讀操作

          while((I2C_SR1 & 0x02) == 0); //地址已經被發送

          temp = I2C_SR1; //清除ADDR標志位

          temp = I2C_SR3;

          while((I2C_SR1 & 0x40) == 0); //等待接收數據寄存器非空

          read_data = I2C_DR;

          I2C_CR2 &= 0xfb; //讀取數據下,發送stop必須禁止ack,才能釋放從機

          temp = I2C_SR1; //清零BTF標志位

          temp = I2C_DR;

          IIC_Stop();

          return read_data;

          }

          附上在IAR環境下的項目工程,包括了SPI、IIC、PWM、AWU、USART、EEPROM等片上硬件的初始化代碼。

          http://download.csdn.NET/detail/devintt/9454188

          讀操作:開始 -> 發送外設地址 -> 開始 ->發送需要讀取的寄存器地址 -> 讀一個字節 -> (可能再讀一個字節) ->。。。 -> 結束



        關鍵詞: stm8s IIC

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 大兴区| 内丘县| 顺昌县| 札达县| 黄石市| 定兴县| 永胜县| 额尔古纳市| 安龙县| 体育| 保德县| 周口市| 永顺县| 抚宁县| 曲阳县| 含山县| 徐州市| 绥滨县| 永春县| 新民市| 神池县| 延川县| 获嘉县| 襄汾县| 丘北县| 闽侯县| 富蕴县| 临清市| 甘谷县| 绍兴市| 望谟县| 长岛县| 广安市| 铁岭县| 江陵县| 商水县| 叙永县| 白朗县| 九龙城区| 侯马市| 奈曼旗|