STM32 i2c从机模式中断处理参考

本文详细描述了I2C1中断处理程序的实现,包括处理各种I2C中断事件如接收就绪、发送就绪、停止条件、错误和溢出,并使用HAL库进行状态管理和错误清除。
摘要由CSDN通过智能技术生成

void I2C1_IRQHandler(void)
{
  /* USER CODE BEGIN I2C1_IRQn 0 */
    extern void i2c1_irq(I2C_HandleTypeDef *hi2c);
    i2c1_irq(&hi2c1);
    return ;
  /* USER CODE END I2C1_IRQn 0 */
  if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
    HAL_I2C_ER_IRQHandler(&hi2c1);
  } else {
    HAL_I2C_EV_IRQHandler(&hi2c1);
  }
  /* USER CODE BEGIN I2C1_IRQn 1 */

  /* USER CODE END I2C1_IRQn 1 */
}

void i2c1_irq(I2C_HandleTypeDef *hi2c)
{
    uint32_t ITFlags   = READ_REG(hi2c->Instance->ISR);
    uint32_t ITSources = READ_REG(hi2c->Instance->CR1);
    
    
  if (((ITFlags & I2C_FLAG_ADDR) != RESET) )
  {
      i2c_sta.rx_index=0;
      i2c_sta.tx_index=0;
      if((ITFlags&I2C_ISR_DIR)!=0)
      {
          hi2c1.Instance->ISR |= I2C_ISR_TXE;
          i2c_sta.pec=Pectable[0^I2C_SLAVE_ADD];
      }
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
  }
 
    if (((ITFlags & I2C_FLAG_RXNE) != RESET) )
    {
        i2c_sta.rx_flag=1;
        i2c_sta.rx_buff[i2c_sta.rx_index] = hi2c->Instance->RXDR;
        if(i2c_sta.rx_index< I2C_BUFF_LEN-1)
           i2c_sta.rx_index++;
  }
    
 
  if (((ITFlags & I2C_FLAG_TXIS) != RESET) )
  {
        if(i2c_sta.tx_index<i2c_sta.tx_len)
        {
            hi2c->Instance->TXDR = i2c_sta.tx_buff[i2c_sta.tx_index];
            i2c_sta.pec=Pectable[i2c_sta.pec^i2c_sta.tx_buff[i2c_sta.tx_index]];

            if(i2c_sta.tx_index< I2C_BUFF_LEN-1)
            i2c_sta.tx_index++;
        }
        else
            hi2c->Instance->TXDR = i2c_sta.pec;      
          
  }
  if (((ITFlags & I2C_FLAG_STOPF) != RESET) )
  {
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
      i2c_sta.stop=1;
  }
 
    if (((ITFlags & I2C_FLAG_AF) != RESET) )
    {

        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
    }
    
    if (hi2c1.Instance->ISR & (I2C_FLAG_BERR )) {
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
    }
    
    if (hi2c1.Instance->ISR & ( I2C_FLAG_ARLO )) {
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
    }
    
    if (hi2c1.Instance->ISR & (I2C_FLAG_OVR)) {
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
    }
    
    
}

  • 13
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HAL_I2C_Master_Receive_IT 是 STM32 HAL 库中用于 I2C 主机非阻塞接收的函数。它的作用是启动 I2C 主机接收,并在接收完成后触发一个中断处理接收到的数据。 使用 HAL_I2C_Master_Receive_IT 的步骤如下: 1. 初始化 I2C:首先,你需要初始化 I2C 外设。可以使用 HAL_I2C_Init 函数来配置所需的 I2C 参数,例如时钟频率、地址模式等。 2. 启动接收:使用 HAL_I2C_Master_Receive_IT 函数启动 I2C 主机接收。该函数需要传入 I2C 外设的句柄(I2C_HandleTypeDef)、从设备地址以及接收数据的缓冲区和长度。函数会将接收请求放入 I2C 接收队列中,并启动接收过程。 3. 中断处理:当接收完成时,将触发一个中断,你需要在中断服务程序(ISR)中处理接收到的数据。在 ISR 中,可以通过检查 I2C_SR1 和 I2C_SR2 寄存器的状态标志位来判断接收是否完成,并使用 HAL_I2C_Receive_IT 函数读取接收到的数据。 以下是一个使用 HAL_I2C_Master_Receive_IT 的示例代码片段: ```c#define RX_BUFFER_SIZE100uint8_t rx_buffer[RX_BUFFER_SIZE]; // 初始化 I2CI2C_HandleTypeDef i2c_handle; i2c_handle.Instance = I2C1; i2c_handle.Init.ClockSpeed =400000; i2c_handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; HAL_I2C_Init(&i2c_handle); // 启动接收HAL_I2C_Master_Receive_IT(&i2c_handle, slave_address, rx_buffer, RX_BUFFER_SIZE); // 中断服务程序void I2C1_IRQHandler(void) { HAL_I2C_EV_IRQHandler(&i2c_handle); HAL_I2C_ER_IRQHandler(&i2c_handle); } // 接收完成回调函数void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) { if (hi2c == &i2c_handle) { // 处理接收到的数据 // ... // 继续启动接收 HAL_I2C_Master_Receive_IT(&i2c_handle, slave_address, rx_buffer, RX_BUFFER_SIZE); } } ``` 在上面的示例中,我们首先初始化了 I2C,并启动了接收。然后,在中断服务程序中,使用 HAL_I2C_EV_IRQHandler 和 HAL_I2C_ER_IRQHandler 函数处理接收中断。当接收完成后,会触发 HAL_I2C_MasterRxCpltCallback 回调函数,我们可以在该函数中处理接收到的数据,并再次启动接收以便下一次接收。 请注意,以上只是一个简化的示例,你可能需要根据具体的硬件和需求进行适当的修改。还应确保正确配置中断优先级,并在 main 函数中启用中断

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值