GD32E230上电复位后,立马进入发送中断

[复制链接]
3699|17
 楼主| huaimengzi 发表于 2024-12-26 18:38 | 显示全部楼层 |阅读模式
本帖最后由 huaimengzi 于 2024-12-26 18:43 编辑

     想写一个串口通信,利用串口收发中断来写,非DMA,发现上电按复位键调试,串口立马进入中断发送,是什么原因呢?求大家帮助指点一下

实验现象,上电即发送7,代码如下:

1. 串口GPIO初始化

  1. static void Com0_Gpio_Init(void)
  2. {
  3.     /* enable COM GPIO clock */
  4.     rcu_periph_clock_enable(BSP_USART0_PORT_RCU);

  5.           /* connect port to USARTx_Tx */
  6.     gpio_af_set(BSP_USART0_PORT, BSP_USART0_AF, BSP_USART0_TX_PIN);

  7.     /* connect port to USARTx_Rx */
  8.     gpio_af_set(BSP_USART0_PORT, BSP_USART0_AF, BSP_USART0_RX_PIN);

  9.     /* configure USART Tx as alternate function push-pull */
  10.     gpio_mode_set(BSP_USART0_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART0_TX_PIN);
  11.     gpio_output_options_set(BSP_USART0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, BSP_USART0_TX_PIN);

  12.     /* configure USART Rx as alternate function push-pull */
  13.     gpio_mode_set(BSP_USART0_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART0_RX_PIN);
  14.     gpio_output_options_set(BSP_USART0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, BSP_USART0_RX_PIN);
  15.         
  16.                 /*5.配置RS485的Enable引脚*/  
  17.                 rcu_periph_clock_enable(BSP_RS485EN0_RCU);                                                     //开启时钟
  18.                 gpio_mode_set(BSP_RS485EN0_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, BSP_RS485EN0_PIN);        //输出,上拉
  19.                 gpio_output_options_set(BSP_RS485EN0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, BSP_RS485EN0_PIN);//配置为推挽输出
  20. }
2. USART0 配置初始化
  1. static void Com0_Usart0_Init(uint32_t BaudRate)
  2. {
  3.     /* enable USART clock */
  4.     rcu_periph_clock_enable(BSP_USART0_RCU);

  5.     /* USART configure */
  6.                 usart_deinit(BSP_USART0);                                     //复位串口
  7.                 usart_baudrate_set(BSP_USART0, BaudRate);                     //设置波特率
  8.                 usart_parity_config(BSP_USART0,USART_PM_NONE);                //设置无校验
  9.                 usart_word_length_set(BSP_USART0,USART_WL_8BIT);              //配置数据位的长度8
  10.                 usart_stop_bit_set(BSP_USART0, USART_STB_1BIT);               //停止位1位
  11.                 usart_hardware_flow_rts_config(BSP_USART0, USART_RTS_DISABLE);//RTS流控关闭
  12.                 usart_hardware_flow_cts_config(BSP_USART0, USART_CTS_DISABLE);//CTS流控关闭
  13.                
  14.           /*打开RX,TX及串口的开关*/
  15.                 usart_transmit_config(BSP_USART0,USART_TRANSMIT_ENABLE);      //使能发送
  16.                 usart_receive_config(BSP_USART0, USART_RECEIVE_ENABLE);       //使能接收
  17.                 DIR_RX0;                                                                                                                                                                                                                        //5.2 作为从机,初始状态设置为等待接收状态
  18.                 usart_enable(BSP_USART0);                                                                                                                               //使能串口
  19.           /* USART interrupt configuration */
  20.                 nvic_irq_enable(BSP_USART0_IRQn,0U);                          //在内核中打开串口及配置中断优先级
  21.     usart_interrupt_enable(BSP_USART0, USART_INT_RBNE);           //读数据缓冲区非空中断和过载错误中断
  22.           usart_interrupt_enable(BSP_USART0,  USART_INT_TBE);           //发送缓冲区空中断
  23.   
  24.                 /*6.把结构体进行初始化*/  
  25.                 UART0.m_ReceiveBytes = 0;
  26.                 UART0.m_SendBytes = 0;
  27.                 UART0.ComInterruptFlag = 0;
  28.                 UART0.g_NoticeTimeOutCounterStartFlag = 0;
  29.                 UART0.g_TimeOutCounter = 0;
  30.                 UART0.g_RecTimeOverFlag = 0;
  31.                 UART0.p_RecBuff  = (uint8_t *)UART0.RecBuff;     //将发送数据指针指向发送缓冲区头
  32.                 UART0.p_SendBuff = (uint8_t *)UART0.SendBuff;    //将接收数据指针指向接收缓存区头
  33. }
3. USART0中断服务函数   接收中断,发送中断

  1. void USART0_IRQHandler(void)  
  2. {
  3.                     if(usart_interrupt_flag_get(BSP_USART0, USART_INT_FLAG_RBNE) != RESET)    //接收缓冲区非空中断,表示里面有数据了
  4.                           {
  5.                                         led_setup(LED2,ON);  
  6.                                         data = usart_data_receive(BSP_USART0);   //将接收到的字节存储到缓冲区
  7.                                 }
  8.                                         if(usart_interrupt_flag_get(BSP_USART0, USART_INT_FLAG_TBE)!= RESET)  //发送缓冲区空中断
  9.                                 {
  10.                                         usart_interrupt_flag_clear(BSP_USART0, USART_INT_FLAG_TBE);       //清除发送中断标志
  11.                                   led_setup(LED3,ON);                     
  12.                
  13.                                         usart_data_transmit(BSP_USART0, 7);      //将数据写入USART_DR进行发送
  14.                                 }
  15. }
4. 调试上电复位后,立马收到数字7

73195676d330fb8ba4.png






评论

很常见,一般都是通过协议处理  发表于 2024-12-26 23:02
pidalu 发表于 2024-12-26 19:08 | 显示全部楼层
你开启了TXE中断,刚上电的时候,TX数据寄存器应该就是空的,那可不就是立即进入了TXE中断一次了嘛。
 楼主| huaimengzi 发表于 2024-12-26 19:17 | 显示全部楼层
我中断接收如果是这样写,上电复位后 TX发给串口上百行乱码,是什么原因呢?
  1.                         if(usart_interrupt_flag_get(BSP_USART0, USART_INT_FLAG_TBE)!= RESET)  //发送缓冲区空中断
  2.                         {   
  3.                                         usart_interrupt_flag_clear(BSP_USART0, USART_INT_FLAG_TBE);       //清除发送中断标志
  4.                                   led_setup(LED3,ON);                     
  5.                                         // 3.1 如果还有待发送数据,则逐一发送出去
  6.                                         if( --UART0.m_SendBytes> 0 )      
  7.                                         {
  8.                                                     led_setup(LED4,ON);   
  9.                                                                 usart_data_transmit(BSP_USART0, *(++UART0.p_SendBuff));      //将数据写入USART_DR进行发送
  10.                                         }
  11.                                         else   //发送缓冲区字节数为0,即缓冲区空
  12.                                         {   
  13.                                                  UART0.ComInterruptFlag = 0;
  14.                                                  DIR_RX0;
  15.                                         }                                       
  16.                         }
Amazingxixixi 发表于 2024-12-27 11:11 | 显示全部楼层
直接协议处理
elephant00 发表于 2025-1-25 15:33 | 显示全部楼层
如果在USART的初始化过程中,错误地配置了中断使能位,例如使能了不必要的发送或接收中断,那么在复位后,MCU可能会因为这些配置错误而立即进入中断。
两只袜子 发表于 2025-1-25 16:00 | 显示全部楼层
在USART的初始化代码中,如果存在逻辑错误或配置不当,也可能导致复位后立即进入中断。
jcky001 发表于 2025-1-25 16:36 | 显示全部楼层
硬件连接错误或不稳定可能导致此类问题
cr315 发表于 2025-1-25 17:00 | 显示全部楼层
硬件连接问题?
laocuo1142 发表于 2025-1-25 18:00 | 显示全部楼层
USART的TX和RX引脚连接不正确,或者存在外部干扰,就可能导致复位后立即进入发送中断。
flycamelaaa 发表于 2025-1-25 19:26 | 显示全部楼层
固件或软件缺陷
powerantone 发表于 2025-1-25 20:00 | 显示全部楼层
中断处理函数中的bug,可能导致复位后立即进入中断。
probedog 发表于 2025-1-25 21:00 | 显示全部楼层
检查USART的初始化代码配置是否正确的。特别是中断使能位,应该只使能需要的中断。
classroom 发表于 2025-1-25 21:00 | 显示全部楼层
在中断服务函数中,确保正确地检查和清除中断标志位。这可以防止中断被反复触发。
慢动作 发表于 2025-1-31 11:48 | 显示全部楼层
刚上电的时候,TX数据寄存器应该就是空的
高级安全大使 发表于 2025-1-31 12:01 | 显示全部楼层
上电按复位键调试,串口立马进入中断发送,是什么原因呢?
梅花香自123 发表于 2025-2-28 16:11 | 显示全部楼层
如果发送缓冲区为空,USART0会进入发送缓冲区空中断。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

40

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部