原创 GD32VW553 使用串口中断上电自动触发串口空闲中断问题

2023-12-15 11:52 837 4 4 分类: MCU/ 嵌入式 文集: GD32
起初的串口配置如下:
开启了串口接收中断和空闲中断。

  1. /**
  2. * 串口0初始化配置
  3. * @param dwbaud_rate 波特率设置
  4. */
  5. void Uart0InitConfig(uint32_t dwbaud_rate)
  6. {
  7. rcu_periph_clock_enable(BSP_USART_RCU); // 开启串口时钟
  8. rcu_periph_clock_enable(BSP_USART_TX_RCU); // 开启端口时钟
  9. rcu_periph_clock_enable(BSP_USART_RX_RCU); // 开启端口时钟
  10. /* 配置复用功能 */
  11. gpio_af_set(BSP_USART_TX_PORT,BSP_USART_TX_AF,BSP_USART_TX_PIN);
  12. gpio_af_set(BSP_USART_RX_PORT,BSP_USART_RX_AF,BSP_USART_RX_PIN);
  13. /* 配置TX为复用模式 上拉模式 */
  14. gpio_mode_set(BSP_USART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_TX_PIN);
  15. /* 配置RX为复用模式 上拉模式 */
  16. gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_RX_PIN);
  17. /* 配置TX为推挽输出 50MHZ */
  18. gpio_output_options_set(BSP_USART_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_TX_PIN);
  19. /* 配置RX为推挽输出 50MHZ */
  20. gpio_output_options_set(BSP_USART_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_RX_PIN);
  21. /* 串口参数配置 */
  22. usart_deinit(BSP_USART); // 复位串口
  23. usart_baudrate_set(BSP_USART,dwbaud_rate); // 设置波特率
  24. usart_parity_config(BSP_USART,USART_PM_NONE); // 没有校验位
  25. usart_word_length_set(BSP_USART,USART_WL_8BIT); // 8位数据位
  26. usart_stop_bit_set(BSP_USART,USART_STB_1BIT); // 1位停止位
  27. /* 使能串口接收 */
  28. usart_receive_config(BSP_USART, USART_RECEIVE_ENABLE);
  29. /* 使能串口发送 */
  30. usart_transmit_config(BSP_USART, USART_TRANSMIT_ENABLE);
  31. /* 使能读数据缓冲区非空中断和过载错误中断 */
  32. usart_interrupt_enable(BSP_USART, USART_INT_RBNE);
  33. /* 使能空闲中断 */
  34. usart_interrupt_enable(BSP_USART, USART_INT_IDLE);
  35. /* 配置中断优先级 */
  36. eclic_irq_enable(BSP_USART_IRQ, 2, 2);
  37. /* 使能串口 */
  38. usart_enable(BSP_USART);
  39. }
  40. /*!
  41.     \brief     这个函数处理USART RBNE中断请求和空闲中断请求
  42.     \param[in]  none
  43.     \param[out] none
  44.     \retval     none
  45. */
  46. void BSP_USART_IRQHandler(void)
  47. {
  48.     if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空
  49.     {
  50.          g_recv_buff[g_recv_length] = usart_data_receive(BSP_USART);  // 把接收到的数据放到缓冲区中
  51.          //限制长度
  52.          g_recv_length=( g_recv_length + 1 ) % USART_RECEIVE_LENGTH;
  53.     }
  54.     if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE) != RESET) // 检测到帧中断
  55.     {
  56.     <span style="white-space:pre"> </span>usart_data_receive(BSP_USART);
  57.         g_recv_buff[g_recv_length] = '\0';
  58.         g_recv_complete_flag = 1;// 接收完成
  59.     }
  60. }




问题:发现一上电就会进入一次空闲中断。然后尝试在初始化配置时,加入清除中断标志位。发现没有效果。


解决办法:最终在串口中断服务函数中,当接收到数据时,判断是否有开启空闲中断,如果没有开启就开启空闲中断。当空闲中断触发时,处理完中断中的任务之后,关闭空闲中断。初始化的配置如下:

  1. /**
  2. * 串口0初始化配置
  3. * @param dwbaud_rate 波特率设置
  4. */
  5. void Uart0InitConfig(uint32_t dwbaud_rate)
  6. {
  7. rcu_periph_clock_enable(BSP_USART_RCU); // 开启串口时钟
  8. rcu_periph_clock_enable(BSP_USART_TX_RCU); // 开启端口时钟
  9. rcu_periph_clock_enable(BSP_USART_RX_RCU); // 开启端口时钟
  10. /* 配置复用功能 */
  11. gpio_af_set(BSP_USART_TX_PORT,BSP_USART_TX_AF,BSP_USART_TX_PIN);
  12. gpio_af_set(BSP_USART_RX_PORT,BSP_USART_RX_AF,BSP_USART_RX_PIN);
  13. /* 配置TX为复用模式 上拉模式 */
  14. gpio_mode_set(BSP_USART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_TX_PIN);
  15. /* 配置RX为复用模式 上拉模式 */
  16. gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_RX_PIN);
  17. /* 配置TX为推挽输出 50MHZ */
  18. gpio_output_options_set(BSP_USART_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_TX_PIN);
  19. /* 配置RX为推挽输出 50MHZ */
  20. gpio_output_options_set(BSP_USART_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_RX_PIN);
  21. /* 串口参数配置 */
  22. usart_deinit(BSP_USART); // 复位串口
  23. usart_baudrate_set(BSP_USART,dwbaud_rate); // 设置波特率
  24. usart_parity_config(BSP_USART,USART_PM_NONE); // 没有校验位
  25. usart_word_length_set(BSP_USART,USART_WL_8BIT); // 8位数据位
  26. usart_stop_bit_set(BSP_USART,USART_STB_1BIT); // 1位停止位
  27. /* 使能串口接收 */
  28. usart_receive_config(BSP_USART, USART_RECEIVE_ENABLE);
  29. /* 使能串口发送 */
  30. usart_transmit_config(BSP_USART, USART_TRANSMIT_ENABLE);
  31. /* 使能读数据缓冲区非空中断和过载错误中断 */
  32. usart_interrupt_enable(BSP_USART, USART_INT_RBNE);
  33. /* 配置中断优先级 */
  34. eclic_irq_enable(BSP_USART_IRQ, 2, 2);
  35. /* 使能串口 */
  36. usart_enable(BSP_USART);
  37. }
  38. /*!
  39. \brief 这个函数处理USART RBNE中断请求和空闲中断请求
  40. \param[in] none
  41. \param[out] none
  42. \retval none
  43. */
  44. void BSP_USART_IRQHandler(void)
  45. {
  46. if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空
  47. {
  48. usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_RBNE);
  49. g_recv_buff[g_recv_length] = usart_data_receive(BSP_USART); // 把接收到的数据放到缓冲区中
  50. //限制长度
  51. g_recv_length=( g_recv_length + 1 ) % USART_RECEIVE_LENGTH;
  52. //判断空闲中断是否开启,如果没有开启
  53. if( (USART_CTL0(BSP_USART) & 0X10) == 0 )
  54. {
  55. /* 使能IDLE线检测中断 */
  56. usart_interrupt_enable(BSP_USART, USART_INT_IDLE);
  57. usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_IDLE);
  58. }
  59. }
  60. if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE) != RESET) // 检测到帧中断
  61. {
  62. usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_IDLE);
  63. //usart_data_receive(BSP_USART);
  64. g_recv_buff[g_recv_length] = '\0';
  65. g_recv_complete_flag = 1;// 接收完成
  66. usart_interrupt_disable(BSP_USART, USART_INT_IDLE);
  67. }
  68. }




作者: a老怪, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-4066354.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条