【STM32】標準庫與HAL庫對照學習教程特別篇--IIC通信原理講解
- 一、前言
- 二、IIC總線介紹
- 三、IIC物理層
- 四、IIC協議層
- 1、通信大致流程:
- 2、傳輸程序
- 3、信號要求
- 五、使用C語言實作IIC
- 1、起始信號與停止信號
- 2、應答信號、非應答信號與等待應答信號
- 3、發送一個位元組資料與接收一個位元組的資料
- 六、設備間使用IIC的大致流程
- 1、發送資料
- 2、接收資料
一、前言
IIC通信作為單片機經常使用的通信協議,有著十分重要的地位,我們經常使用IIC通信驅動各種外設,IIC在使用上有軟體IIC與硬體IIC,
軟體IIC是指用單片機的兩個引腳模擬出來的IIC,通程序式控制引腳狀態,
硬體IIC是指芯片上的IIC外設,有專門的電路與控制暫存器,對應引腳也是專用的,
硬體IIC的效率要遠高于軟體IIC,但引腳固定且數量有限,軟體IIC不受引腳限制,
本章我們使用軟體IIC,
二、IIC總線介紹
I2C(Inter-Integrated Circuit)總線是由PHILIPS公司開發的兩線式串行總線,用于連接微控制器及其外圍設備,是微電子通信控制領域廣泛采用的一種總線標準,
I2C總線只有兩根雙向信號線,一根是資料線SDA,另一根是時鐘線SCL,
三、IIC物理層
IIC通信的連接方式:

說明:
- SCL總線是時鐘線,由主設備提供,SDA總線是資料線,用于資料的傳輸,
- 總線上同一時間只能由一個主設備使用,當多個主機同時使用總線時,為了防止資料沖突,會利用仲裁方式決定由哪個設備占用總線,
- 每個連接到總線的從設備都有一個獨立的地址,主設備可以利用這個地址進行不同設備之間的訪問,
- IIC通信屬于半雙工通信,同一時間的設備只能接收資料或者發射資料,(因為只有一根資料線)
- 總線通過上拉電阻接到電源,當 I2C 設備空閑時,會輸出高阻態,由上拉電阻把總線拉成高電平,
- 常見兩種傳輸模式:標準模式傳輸速率為 100kbit/s ,快速模式為 400kbit/s ,
- 連接設備數量受最大電容400pF的限制,
四、IIC協議層
1、通信大致流程:
- 主設備首先發射一個起始信號,開始通信,
- 然后,主設備會發射需要通信的某一個從設備的地址,
- 當對應地址的從設備接收到地址信號后會回傳一個應答信號,當主設備接收到應答信號時,開始進行資料傳輸,
- 每當 接識訓者發送 資料都會 接識訓者發送 一個應答信號,當不需要傳輸資料時,需要提供一個非應答信號,結束資料傳輸,
- 資料傳輸完畢時,主設備會發射一個停止信號結束通信,
2、傳輸程序
(1)主機向從機發送資料:

(2)主機讀取從設備的資料:

(3)主機在發送資料程序中,轉為讀取資料,

S:起始信號, 0:寫資料, 1:讀資料, A:應答信號, A非:非應答信號, P:停止信號
資料傳輸一幀資料有8位,地址的資料一般為7位加上1位讀寫位,正好一幀資料,(10位的地址一般檢測頭7位)
3、信號要求
(1)起始和停止信號

(2)應答與非應答信號

(3)資料有效性規定

資料電平變化必須在SCL為低電平的時候,
五、使用C語言實作IIC
根據信號要求,可以用C語言寫出對應傳輸程式,
1、起始信號與停止信號
(1)起始信號
/*************************************************
*函式名: IIC_start
*函式功能: IIC起始信號
*輸入: 無
*回傳值: 無
**************************************************/
void IIC_start()
{
IIC_OUT(); //SDA變為輸出狀態
SCL = 1;
SDA_out = 1;
Delay_us(5);
SDA_out = 0;
Delay_us(5);
}
(2)終止信號
/*************************************************
*函式名: IIC_end
*函式功能: IIC停止信號
*輸入: 無
*回傳值: 無
**************************************************/
void IIC_end()
{
IIC_OUT(); //SDA變為輸出狀態
SCL = 1;
SDA_out = 0;
Delay_us(5);
SDA_out = 1;
Delay_us(5);
}
2、應答信號、非應答信號與等待應答信號
(1)應答信號
/*************************************************
*函式名: IIC_ACK
*函式功能: IIC主機發出應答信號
*輸入: 無
*回傳值: 無
**************************************************/
void IIC_ACK()
{
IIC_OUT(); //SDA變為輸出狀態
SCL = 0;
SDA_out = 0;
SCL = 1;
Delay_us(5);
SCL = 0;
}
(2)非應答信號
/*************************************************
*函式名: IIC_NACK
*函式功能: IIC主機發出非應答信號
*輸入: 無
*回傳值: 無
**************************************************/
void IIC_NACK()
{
IIC_OUT(); //SDA變為輸出狀態
SCL = 0;
SDA_out = 1;
SCL = 1;
Delay_us(5);
SCL = 0;
}
(3)等待應答信號
/*************************************************
*函式名: IIC_Wait_ACK
*函式功能: 主機等待應答信號
*輸入: 無
*回傳值: 1:接收到應答信號,0:非應答或者未接收到應答信號
**************************************************/
u8 IIC_Wait_ACK()
{
u8 i;
IIC_IN(); //SDA變為輸入狀態
SCL = 1;
while(SDA_in)
{
i++;
if(i > 250)
{
IIC_end();
#if DEBUG_IIC
printf("未收到應答信號,IIC有誤\r\n");
#endif
return 0;
}
}
SCL=0;
return 1;
}
3、發送一個位元組資料與接收一個位元組的資料
(1)發送一個位元組資料
/*************************************************
*函式名: IIC_Write_byte
*函式功能: IIC寫一個位元組函式
*輸入: bit:寫入的資料
*回傳值: 無
**************************************************/
void IIC_Write_byte(u8 bit)
{
u8 i;
IIC_OUT(); //SDA變為輸出狀態
SCL = 0;
for(i = 0;i < 8;i++)
{
if(bit & 0x80)
SDA_out = 1;
else
SDA_out = 0;
bit <<= 1;
Delay_us(2);
SCL = 1;
Delay_us(2);
SCL = 0;
Delay_us(2);
}
}
(2)接收一個位元組的資料
/*************************************************
*函式名: IIC_Read_byte
*函式功能: IIC讀取一個位元組的資料
*輸入: ACK:1-接收后給應答信號,0-接收后給非應答信號
*回傳值: BIt:讀取的值
**************************************************/
u8 IIC_Read_byte(u8 ACK)
{
u8 i,Bit;
IIC_IN(); //SCL變為輸入狀態
for(i = 0;i < 8;i++) //判斷最高位,0x80 = 1000 0000
{
SCL = 0;
Delay_us(2);
SCL = 1;
Bit <<= 1;
if(SDA_in)
Bit++;
}
if(ACK)
IIC_ACK();
else
IIC_NACK();
return Bit;
}
六、設備間使用IIC的大致流程
1、發送資料
- 主機發送起始信號
- 主機發送從機地址+寫信號
- 主機接收到應答信號,發送從設備寫入資料的地址
- 主機接收到應答信號,主機開始發送資料,每發送一位元組資料,都要接收一次應答信號,
- 資料發送完畢,主機發送停止信號,通信結束,
2、接收資料
- 主機發送起始信號
- 主機發送從機地址+讀信號
- 主機接收到應答信號,發送從設備讀取資料的地址
- 主機接收到應答信號,從設備開始發送資料,主機每接送一位元組資料,都要發送一次應答信號,
- 主機不在想接收資料時,發送非應答信號,,結束資料傳輸,
- 主機發送停止信號,通信結束,
到這里就結束啦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/377210.html
標籤:其他
