一、从机双地址,在回调函数中获取主机访问的地址:
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
uint16_t slaveaddrcode = I2C_GET_ADDR_MATCH(I2cHandle);
printf("R:%d\r\n",slaveaddrcode);
}
二、如果用地址回调函数HAL_I2C_AddrCallback(),这个回调函数触发后,会关闭中断,需要再次开启中断,才能继续监听。需要特别注意开启监听中断的位置,有人在这个回调函数里直接开启,我测试了一下,不行,开启失败;还有人,把开启监听放在主循环里,一直不断轮询去开启,大力出奇迹,这样确实可以用,但是经过测试发现有时候会丢失,不能触发回调函数。直到看到这篇文章,在HAL_I2C_ListenCpltCallback()函数中开启,才是最优解。
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
if(TransferDirection == I2C_DIRECTION_TRANSMIT)
{
// if(HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, i2c.RxData, sizeof(i2c.RxData), I2C_FIRST_FRAME) != HAL_OK)
// {
// }
}
else if(TransferDirection == I2C_DIRECTION_RECEIVE)
{
// if(HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, i2c.TxData, sizeof(i2c.TxData), I2C_LAST_FRAME)!= HAL_OK)
// {
// }
}
//HAL_I2C_EnableListen_IT(hi2c);//在这里启动监听会失败,没有用
}
// 侦听完成回调函数(完成一次完整的i2c通信以后会进入该函数)
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
// 完成一次通信,清除状态
// first_byte_state = 1;
// offset = 0;
HAL_I2C_EnableListen_IT(hi2c); // slave is ready again
}