通讯流程
1.使用HT2202芯片配置为主机接收(轮询模式)。
2.将STM32芯片配置为从机发送,中断模式下发送固定数据。
3.如果HT2202芯片能够收到STM32发送的数据则通讯成功,否则通讯失败。
STM32程序
1.这些函数是STM32的I2C(Inter-Integrated Circuit)总线操作函数,用于在不同模式下进行数据传输和通信。
/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
/* IO operation functions ****************************************************/
/******* Blocking mode: Polling */
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_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_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
/******* Non-Blocking mode: Interrupt */
Non-Blocking Mode - Interrupt:
// 在此模式下,函数会启动操作然后允许代码继续执行,操作完成后会触发中断。
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);
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);
HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); // 函数是STM32 HAL库中用于I2C从机模式的监听使能函数。这个函数用于配置I2C外设以启用从机模式,并使其能够侦听主机发来的特定地址的请求。
HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
/******* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
/**
* @}
*/
2.回调函数含义
这些函数是与STM32的HAL库(Hardware Abstraction Layer)中I2C模块相关的中断处理和回调函数。它们用于在I2C通信中的不同阶段或事件发生时执行相应的操作或处理
/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
* @{
*/
/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); // 用于处理I2C事件中断。当I2C事件触发中断时,执行相应的事件处理。
void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); // 处理I2C错误中断。当I2C产生错误时,执行相应的错误处理。
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); // 主机发送数据完成时的回调函数。
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); // 主机接收数据完成时的回调函数。
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); // 从机发送数据完成时的回调函数。
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); // 从机接收数据完成时的回调函数。
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); // I2C地址匹配时的回调函数。 用于处理当I2C地址与预期地址匹配时的操作。
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); // 从机监听模式完成时的回调函数。
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); // I2C内存发送完成时的回调函数。
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); // I2C内存接收完成时的回调函数。
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); // I2C错误发生时的回调函数。
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); // I2C传输中止完成时的回调函数。
/**
* @}
*/
当I2C从机模式下发生地址匹配时,HAL库会调用HAL_I2C_AddrCallback函数。以下是这个函数的参数含义:
I2C_HandleTypeDef *hi2c:
这是指向I2C句柄的指针,包含了I2C外设的相关信息和配置。通过这个句柄,可以访问和控制I2C外设的各种属性和寄存器。uint8_t TransferDirection: 这个参数指示了数据传输的方向。它可以是以下两个值之一:
I2C_DIRECTION_RECEIVE:表示主机向从机发送数据(读取数据)。
I2C_DIRECTION_TRANSMIT:表示主机从从机接收数据(写入数据)。 uint16_t AddrMatchCode:
这个参数表示匹配的地址码。它是16位的值,表示与I2C总线上检测到的匹配地址的码值。在这个回调函数中,你可以根据TransferDirection参数的值来确定接下来的操作是发送数据还是接
收数据,并对数据进行相应的准备和处理。AddrMatchCode参数可以帮助你确认匹配的具体地址值,以便根据需要执行相应的操作。
/* USER CODE BEGIN 1 */
// 准备发送的数据
void driver_i2c_init() {
if (HAL_I2C_EnableListen_IT(&hi2c1) != HAL_OK) {
// 使能从机监听失败
Error_Handler();
}
}
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
// 当地址匹配时的回调函数
if (TransferDirection == I2C_DIRECTION_TRANSMIT) {
// 发送数据
uint8_t data_to_send[4] = {0x01, 0x02, 0x03, 0x04}; // 要发送的数据
HAL_I2C_Slave_Transmit_IT(hi2c, data_to_send, sizeof(data_to_send));
}
}
// 在中断服务函数中处理I2C传输完成的情况
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {
// 数据发送完成后调用此回调函数
// 可以在这里执行任何必要的操作
// 1.程序数据发送完毕后翻转GPIO
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}
/* USER CODE END 1 */
使用中断程序进行和2202进行通讯,2202芯片未获取到STM32发送的数据,需要排查原因。
通讯方式:
发送读写: