iT邦幫忙

0

STM32-15 I²C 介紹

  • 分享至 

  • xImage
  •  

介紹

I²C(Inter-Integrated Circuit)中文是內部整合電路,屬於串列通訊匯流排。最早是由Philips開發,為了使嵌入式系統、手機等等可以連接低速周邊裝置而發展的,適用於短距離通訊。

I²C只需要兩條線即可完成通訊,分別是SDA與SCL因此非常的節省空間。大多應用於小型元件,最常看到的應該是EEPROM這一類的元件。

那I²C與SPI差別在哪呢?

I²C SPI
半/全雙工 半雙工 全雙工
傳輸速度 較低 較高
所需腳位 2 4 or 3
通訊 允許多個Master 1 Master n Slave
資料傳輸方式 8bit→8bit 1 bit逐位交換

I²C匯流排架構

使用時允許多個Master進行通訊,將各設備SCL與SDA連結即可。每一設備皆由屬於自己的地址,不管是任何設備SDA與SCL都屬於Open Drain 的IO腳,同時並接(Wired-And)在兩條線路上,皆需要加入上拉電阻。當導通時是低電位不導通時為浮接,所以利用電阻將電位拉高。
https://ithelp.ithome.com.tw/upload/images/20220319/20146325OD2gqO4fyV.png
Wired-And指的是:

→Wired : 直接將設備對應的線接在一起

→And : 也就是大家熟知的And邏輯閘

a b output
0 0 0
0 1 0
1 0 0
1 1 1

也就是說只有當輸入都為High的時候才會輸出High,任一個為Low即為Low。代表著在匯流排當中只要有一個晶片為Low那就會是Low,而晶片可以輕易地控制Bus輸出Low,但要輸出High實則連其他晶片也必須同時輸出High。


I²C Protocol

https://ithelp.ithome.com.tw/upload/images/20220319/20146325Sm651XEd1g.png
可以看到上圖是一個I²C傳送資料的過程,先說明一下什麼是SDA與SCL:

SDA : 資料線,所以的資料交換都是在SDA上完成
SCL : 時鐘線,由Master輸出用

I²C的傳輸包括了四個部分:最開頭的Start信號,接下來會接上設備的I²C地址與傳送的資料,最後會接上一個Stop信號。

  1. 先從起始信號與結束信號來看:
    https://ithelp.ithome.com.tw/upload/images/20220319/20146325Gmhm8jZnDl.png

如何開始通訊?可以看到上方一剛開始由SDA與SCL皆處於High的情況,接著SDA向下拉由1變為0,這時SCL一樣保持為High,這個動作就可以當作一個開始信號。

SDA = 1;
Delay();
SCL = 1;
Delay();
SDA = 0;
Delay();
SCL = 0;
Delay();

如何結束通訊? 首先由SDA先降為Low而SCL處在High,接著再將SDA拉回High則代表結束通訊。

SDA = 0;
Delay();
SCL = 1;
Delay();
SDA = 1;
Delay();
  1. 資料傳輸過程 :

在I²C當中交換資料時,是以8bit加上1bit的ACK為一組,每一次交換都是將MSB先傳送。無論是I²C的設備地址還是後續要交換的資料都需要按照這個模式去做傳送。

ACK與NACK說明

上方提到每一組資料會在後方接上一個ACK bit,而這個bit會由接收端產生。其中又分為ACK與NACK,ACK為Low而NACK為High。在這過程並非發送端一定時Master,也有可能是由Slave在傳送,而由Master產生ACK或NACK。

那是不是任何時候都能去透過SDA做資料交換呢?

當然是不行,可以看看下方這張圖片說明資料有效性。只有在SCL為Low時才可以去做資料的交換,這時候表示SDA處在混亂的階段。相反的當SCL為High時則無法去變更SDA,表示SDA處於穩定狀態。
https://ithelp.ithome.com.tw/upload/images/20220319/20146325XfAsAjtWmS.png
3. I²C地址說明 :

地址分為7bit與10bit兩種地址,大多設備還是使用7bit作為地址長度。而如何區分究竟是7還是10bit則可以看到下圖,假設是10bit前方5個bit則為11110而後續接上2bit設備地址並且接上r/w(r:1 / w: 0)後等待ACK,接著才會接收剩餘的7bit。
https://ithelp.ithome.com.tw/upload/images/20220319/20146325ZsoGsesVi5.png


.IOC檔設定

  1. 左側Connectivity選單當中可以選擇I2C1-I2C3這邊以I2C示範。點選後可以看到上方可以設置I2C的模式選擇I2C開啟。
  • SMBus-Alert-Mode
  • SMBus-two-wire-interface

SMBus另外有支援Alert Signal可以在收到Alert時詢問是哪個Slace所發出的,再去對該設備進行後續處理。

https://ithelp.ithome.com.tw/upload/images/20220319/20146325wmmodGgj2C.png
2. GPIO腳位 : I2C1的SCL連接為PB6 SDA為PB7
https://ithelp.ithome.com.tw/upload/images/20220319/20146325euxOzMgzFh.png
3. 詳細設置
https://ithelp.ithome.com.tw/upload/images/20220319/20146325sB30lvnKoN.png


函數說明

同樣的有分為輪詢與中斷方式

Master

  • 傳送輪詢方式
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,uint16_t Size, uint32_t Timeout)
  • 接收輪詢方式
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,uint16_t Size, uint32_t Timeout);
  • 傳送 中斷方式
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,uint16_t Size);
  • 接收 中斷方式
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,uint16_t Size);

Slave

  • 傳送輪詢方式
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,uint32_t Timeout);
  • 接收輪詢方式
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,uint32_t Timeout);
  • 傳送 中斷方式
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
  • 接收 中斷方式
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);

中斷回調函式-Master

  • 傳送中斷回調函式
__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hi2c);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
   */
}
  • 接收中斷回調函式
__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hi2c);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
   */
}

中斷回調函式-Slave

  • 傳送中斷回調函式
__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hi2c);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
   */
}
  • 接收中斷回調函式
__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hi2c);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
   */
}

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言