Я вижу, что как только ведомый адрес записывается в обработчик прерываний, я сразу получаю ACK Failure, но когда я делаю то же самое с подходом опроса, я получаю ACK и продолжаю считывать значения из device.
С прерываниями я вижу, что ISR запускается только один раз (в котором он записывает адрес подчиненного устройства) и никогда больше не вызывается. Мои конфигурации i2 c в порядке, но есть кое-что с прерываниями, которые я, кажется, упускаю.
Метод опроса
HAL_Status I2C_HAL_TX_IT () {
GenerateStartCondition();
// validate the completion of start condition
while (!GetFlagStatus(hi2c->Instance, I2C_SR1_SB) && HAL_Timeout(5));
// write slave address along with write bit
I2C_WriteSlaveAddress(hi2c, WRITE);
// wait for address to be sent
while (!GetFlagStatus(hi2c->Instance, I2C_SR1_ADDR) && HAL_Timeout(5));
// clear address flag
I2C_ClearADDRFlag(hi2c->Instance);
// write data to DR ...
}
С прерывания:
void HAL_StartI2CInterrupts() {
GenerateStartCondition();
// setting control bits
hi2c->Instance->CR2 |= I2C_CR2_ITBUFEN;
hi2c->Instance->CR2 |= I2C_CR2_ITEVTEN;
hi2c->Instance->CR2 |= I2C_CR2_ITERREN;
}
void I2C1_EV_IRQHandler ()
{
uint8_t event_interrupt = (hi2c->Instance->CR2 & I2C_CR2_ITEVTEN) >> I2C_CR2_ITEVTEN_Pos;
uint8_t buffer_interrupt = (hi2c->Instance->CR2 & I2C_CR2_ITBUFEN) >> I2C_CR2_ITBUFEN_Pos;
uint8_t var;
if (event_interrupt)
{
// validate the completion of START condition
var = (hi2c->Instance->SR1 & I2C_SR1_SB) >> I2C_SR1_SB_Pos;
if (var)
{
if (hi2c->I2C_State == I2C_TX_BUSY)
{
I2C_WriteSlaveAddress(hi2c, WRITE);
}
}
// check ADDR bit ...
}
}