目錄
三、IIC通信的三種方式(Polling、IT、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);
}