STM32CubeIDE HAL庫操作IIC (一)配置篇

目錄

一、MX配置

使能中斷(可選):

DMA設置(可選):

二、生成的代碼

三、IIC通信的三種方式(Polling、IT、DMA)(代碼源自官方例程)

1、Polling (常用)

2、IT(開啓中斷,接收到數據時會調用回調函數)

3、DMA模式(回調函數同中斷)

四、對IIC從設備的寄存器操作(適用於SHT21、MPU6050、AT24C02等)


一、MX配置

標準模式,100KHz時鐘,7位地址

 

使能中斷(可選):

DMA設置(可選):

 

二、生成的代碼

初始化函數

底層初始化

確定了引腳爲開漏模式、時鐘、DMA以及開啓EV中斷。

三、IIC通信的三種方式(Polling、IT、DMA)(代碼源自官方例程)

1、Polling (常用)

//主機模式發送  
/* Timeout is set to 10S */
  while(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 10000)!= HAL_OK)
  {
    /* Error_Handler() function is called when Timeout error occurs.
       When Acknowledge failure occurs (Slave don't acknowledge its address)
       Master restarts communication */
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }

//主機模式接收
/* Timeout is set to 10S */ 
  while(HAL_I2C_Master_Receive(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 10000) != HAL_OK)
  {
    /* Error_Handler() function is called when Timeout error occurs.
       When Acknowledge failure occurs (Slave don't acknowledge it's address)
       Master restarts communication */
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }

//從機模式接收
/* Timeout is set to 10S  */
  if(HAL_I2C_Slave_Receive(&hi2c1, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 10000) != HAL_OK)
  {
    /* Transfer error in reception process */
    Error_Handler();
  }
  
//從機模式發送
  /* Timeout is set to 10S */
  if(HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 10000)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();    
  }

//錯誤回調函數
/**
  * @brief  I2C error callbacks.
  * @param  I2cHandle: I2C handle
  * @note   This example shows a simple way to report transfer error, and you can
  *         add your own implementation.
  * @retval None
  */
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
{
  //
}

2、IT(開啓中斷,接收到數據時會調用回調函數)

//主機模式中斷髮送
/* While the I2C in reception process, user can transmit data through 
    "aTxBuffer" buffer */
    if(HAL_I2C_Master_Transmit_IT(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
    {
      /* Error_Handler() function is called in case of error. */
      Error_Handler();
    }
/*##-3- Wait for the end of the transfer ###################################*/
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
    {
    }

//主機模式中斷接收
if(HAL_I2C_Master_Receive_IT(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    {
      /* Error_Handler() function is called in case of error. */
      Error_Handler();
    }

//主機模式發送回調函數
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
//
}
//主機模式接收回調函數
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
//
}

//從機模式中斷接收
 if(HAL_I2C_Slave_Receive_IT(&hi2c1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
  {
    /* Transfer error in reception process */
    Error_Handler();
  }
  
  /*##-3- Wait for the end of the transfer ###################################*/  
  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  {
  }

//從機模式中斷髮送
  /*##-4- Start the transmission process #####################################*/  
  /* While the I2C in reception process, user can transmit data through 
     "aTxBuffer" buffer */
if(HAL_I2C_Slave_Transmit_IT(&hi2c1, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();    
  }


//從機模式發送回調函數
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
//
}
//從機模式接收回調函數
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
//
}

3、DMA模式(回調函數同中斷)

//主機模式DMA發送
while(HAL_I2C_Master_Transmit_DMA(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
  {
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }
  /*##-3- Wait for the end of the transfer ###################################*/  
  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);

//主機模式DMA接收
while(HAL_I2C_Master_Receive_DMA(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
  {
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }

//從機模式DMA發送
  if(HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
  {

    Error_Handler();
  }
  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
//從機模式DMA接收
  if(HAL_I2C_Slave_Transmit_DMA(&hi2c1, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();    
  }
  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);

四、對IIC從設備的寄存器操作(適用於SHT21、MPU6050、AT24C02等)

下面對庫函數的操作做了一次封裝,函數前還可以加上 __STATIC_INLINE

I2C_Addr 器件地址,例如MPU6050爲0xd0

reg 寄存器地址,例如陀螺儀配置寄存器 0x1B

data 操作數,例如操作陀螺儀配置寄存器數值0x18,開啓滿量程

*buf 讀取數存儲地址指針

uint8_t HALIIC_WriteByteToSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t data)
{
  uint8_t  *pData;
  pData = &data;
  return HAL_I2C_Mem_Write(&hi2c1, I2C_Addr, reg, I2C_MEMADD_SIZE_8BIT, pData, 1, 100);
}
uint8_t HALIIC_ReadByteFromSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t *buf)
{
  return HAL_I2C_Mem_Read(&hi2c1, I2C_Addr, reg, I2C_MEMADD_SIZE_8BIT, buf, 1, 100);
}

uint8_t HALIIC_ReadMultByteFromSlave(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data)
{
  return HAL_I2C_Mem_Read(&hi2c1, dev, reg, I2C_MEMADD_SIZE_8BIT, data, length, 200);
}
uint8_t HALIIC_WriteMultByteToSlave(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data)
{
  return HAL_I2C_Mem_Write(&hi2c1, dev, reg, I2C_MEMADD_SIZE_8BIT, data, length, 200);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章