Inter-Integrated Circuit(I2C)

大綱

以下文章主要以I2C master為出發,如果是要尋找I2C slave 可點擊右邊文章

  1. 硬體Nucleo-F401RE(STM32F401RE)
  2. STM32CubeMx軟體設置
  3. IDE: STM32CubeIDE
  4. STM32F1xx/STM32F4xxHAL庫
  5. IIC:硬件硬件IIC1

I2C的物理層

I2C傳輸數據線=> SDA數據線:時鐘 Ref:《IIC原理超詳細講解—值得一看》

Ps:的理論理想傳輸距離為通信,用於由於乾擾和傳輸速度的提高,實際上的IC只有15M遠,一般適合板極器件,不適合中長距離的通信
本題STM32與硬體須注意事項

I2C數據傳輸

IIC的每一天偵查數據由9bit組成
如果是發送數據 8bit data+1bit ACK
如果是設備地址數據則8bit包含7bit設備地址+1bit方向

數據是由為一組而傳輸的,因此需要額外發送8位傳感器或應用程序體去設置接收設置
PS:因傳輸訊號為先傳輸數據為雙線結構,所以傳輸數據發送端:地址(8bit)+數據(8bit)

STM32CubeMX I2C設定

PS:接傳感器都是以slave/MCU為master,以下文章會以此為前提撰寫

Ref:【STM32】HAL庫STM32CubeMX教程十二—IIC(讀取AT24C02)

Clock部分來說這邊不特別設定,如果有興趣可以參考去分配資源《【STM32】系統時鐘RCC詳解(超詳細,超全面)》

PS:共用Clock是需要盡可能避免的,因為會出現時序互相干擾現象,如需在使用時必須排好時間流程序

最後是轉出STM32cubeIDE可編輯的程式碼

I2C 程式撰寫

Ref:使用I2C STM32F0 HAL庫編程計算

HAL_I2C_Mem_Write
HAL_I2C_Mem_Read
uint8_t read_register(uint8_t Sensor_register)

{

    HAL_StatusTypeDef status = HAL_OK;

    uint8_t return_value = 0;




    status = HAL_I2C_Mem_Read(&hi2c1,Devadress,Sensor_register, I2C_MEMADD_SIZE_8BIT, &return_value, 1, 100);

    HAL_Delay(10);

    /* Check the communication status */

    if(status != HAL_OK)

    {

    printf("I2C read status error =%#x \n\r",status);

              /*

     HAL_ERROR    = 0x01U,

     HAL_BUSY     = 0x02U,

     HAL_TIMEOUT  = 0x03U

               */

    }




    return return_value;

};




void write_register(uint8_t Sensor_register, uint8_t register_value)

{

    HAL_StatusTypeDef status = HAL_OK;




    status = HAL_I2C_Mem_Write(&hi2c1, Devadress, Sensor_register, I2C_MEMADD_SIZE_8BIT, &register_value,1, 100);

    HAL_Delay(10);

    /* Check the communication status */

    if(status != HAL_OK)

    {

    printf("I2C write status error =%#x \n\r",status);// Error handling, for example re-initialization of the I2C peripheral

    }

}

另外也有以下4種Function可以使用

  • HAL_I2C_Mem_Write_IT
  • HAL_I2C_Mem_Read_IT
  • HAL_I2C_Mem_Write_DMA
  • HAL_I2C_Mem_Read_DMA
  1. 其中IT的使用要注意Clock流程序是否會出現打結現象
  2. DMA的話是必須知道資料長度,如果不知道資料長度會導致程式錯誤
  3. HAL_I2C_Master_Transmit/Receive基本上使用差不多

I2C傳輸失敗

  • 事先確認是否有加外加電阻
  • 第二部份最常錯的就是adress錯誤
外加電阻圖另外可以參考下面詳細介紹電阻配置

針對第2點可以使用以下程式去解

void Scan_i2c_bus_device(void)

{

       int status;

        int i;

        int u8GetDevCnt;

        unsigned char u8data[2];

        printf("Start Scan:\r\n");

        u8GetDevCnt=0;

        for(i=0;i<0xfe;i=i+2)

        {

                status = HAL_I2C_Master_Receive(&hi2c1,(uint16_t)(i), &u8data[0], 1, 10000);

                if(status==HAL_OK)

                {

                                printf("get device on slave addr=0x%x\r\n",i);

                                u8GetDevCnt++;

                }

                HAL_Delay(10);

        }

        printf("Scan get =%d device\r\n",u8GetDevCnt);

        printf("Scan Done!\r\n");

}

2 thoughts on “Inter-Integrated Circuit(I2C)”

  1. Pingback: Pull-up Resistors For I2C Bus - AMS and STM32

  2. Pingback: I2C Slave mode on STM32 Introduction - AMS and STM32

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart