原创
GD32VW553 使用串口中断上电自动触发串口空闲中断问题
起初的串口配置如下:
开启了串口接收中断和空闲中断。
/*** 串口0初始化配置* @param dwbaud_rate 波特率设置*/void Uart0InitConfig(uint32_t dwbaud_rate){rcu_periph_clock_enable(BSP_USART_RCU); // 开启串口时钟rcu_periph_clock_enable(BSP_USART_TX_RCU); // 开启端口时钟rcu_periph_clock_enable(BSP_USART_RX_RCU); // 开启端口时钟/* 配置复用功能 */gpio_af_set(BSP_USART_TX_PORT,BSP_USART_TX_AF,BSP_USART_TX_PIN);gpio_af_set(BSP_USART_RX_PORT,BSP_USART_RX_AF,BSP_USART_RX_PIN);/* 配置TX为复用模式 上拉模式 */gpio_mode_set(BSP_USART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_TX_PIN);/* 配置RX为复用模式 上拉模式 */gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_RX_PIN);/* 配置TX为推挽输出 50MHZ */gpio_output_options_set(BSP_USART_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_TX_PIN);/* 配置RX为推挽输出 50MHZ */gpio_output_options_set(BSP_USART_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_RX_PIN);/* 串口参数配置 */usart_deinit(BSP_USART); // 复位串口usart_baudrate_set(BSP_USART,dwbaud_rate); // 设置波特率usart_parity_config(BSP_USART,USART_PM_NONE); // 没有校验位usart_word_length_set(BSP_USART,USART_WL_8BIT); // 8位数据位usart_stop_bit_set(BSP_USART,USART_STB_1BIT); // 1位停止位/* 使能串口接收 */usart_receive_config(BSP_USART, USART_RECEIVE_ENABLE);/* 使能串口发送 */usart_transmit_config(BSP_USART, USART_TRANSMIT_ENABLE);/* 使能读数据缓冲区非空中断和过载错误中断 */usart_interrupt_enable(BSP_USART, USART_INT_RBNE);/* 使能空闲中断 */usart_interrupt_enable(BSP_USART, USART_INT_IDLE);/* 配置中断优先级 */eclic_irq_enable(BSP_USART_IRQ, 2, 2);/* 使能串口 */usart_enable(BSP_USART);}/*! \brief 这个函数处理USART RBNE中断请求和空闲中断请求 \param[in] none \param[out] none \retval none*/void BSP_USART_IRQHandler(void){ if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空 { g_recv_buff[g_recv_length] = usart_data_receive(BSP_USART); // 把接收到的数据放到缓冲区中 //限制长度 g_recv_length=( g_recv_length + 1 ) % USART_RECEIVE_LENGTH; } if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE) != RESET) // 检测到帧中断 { <span style="white-space:pre"> </span>usart_data_receive(BSP_USART); g_recv_buff[g_recv_length] = '\0'; g_recv_complete_flag = 1;// 接收完成 }}复制代码 问题:发现一上电就会进入一次空闲中断。然后尝试在初始化配置时,加入清除中断标志位。发现没有效果。
解决办法:最终在串口中断服务函数中,当接收到数据时,判断是否有开启空闲中断,如果没有开启就开启空闲中断。当空闲中断触发时,处理完中断中的任务之后,关闭空闲中断。初始化的配置如下:
/*** 串口0初始化配置* @param dwbaud_rate 波特率设置*/void Uart0InitConfig(uint32_t dwbaud_rate){rcu_periph_clock_enable(BSP_USART_RCU); // 开启串口时钟rcu_periph_clock_enable(BSP_USART_TX_RCU); // 开启端口时钟rcu_periph_clock_enable(BSP_USART_RX_RCU); // 开启端口时钟/* 配置复用功能 */gpio_af_set(BSP_USART_TX_PORT,BSP_USART_TX_AF,BSP_USART_TX_PIN);gpio_af_set(BSP_USART_RX_PORT,BSP_USART_RX_AF,BSP_USART_RX_PIN);/* 配置TX为复用模式 上拉模式 */gpio_mode_set(BSP_USART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_TX_PIN);/* 配置RX为复用模式 上拉模式 */gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, BSP_USART_RX_PIN);/* 配置TX为推挽输出 50MHZ */gpio_output_options_set(BSP_USART_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_TX_PIN);/* 配置RX为推挽输出 50MHZ */gpio_output_options_set(BSP_USART_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, BSP_USART_RX_PIN);/* 串口参数配置 */usart_deinit(BSP_USART); // 复位串口usart_baudrate_set(BSP_USART,dwbaud_rate); // 设置波特率usart_parity_config(BSP_USART,USART_PM_NONE); // 没有校验位usart_word_length_set(BSP_USART,USART_WL_8BIT); // 8位数据位usart_stop_bit_set(BSP_USART,USART_STB_1BIT); // 1位停止位/* 使能串口接收 */usart_receive_config(BSP_USART, USART_RECEIVE_ENABLE);/* 使能串口发送 */usart_transmit_config(BSP_USART, USART_TRANSMIT_ENABLE);/* 使能读数据缓冲区非空中断和过载错误中断 */usart_interrupt_enable(BSP_USART, USART_INT_RBNE);/* 配置中断优先级 */eclic_irq_enable(BSP_USART_IRQ, 2, 2);/* 使能串口 */usart_enable(BSP_USART);}/*!\brief 这个函数处理USART RBNE中断请求和空闲中断请求\param[in] none\param[out] none\retval none*/void BSP_USART_IRQHandler(void){if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空{usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_RBNE);g_recv_buff[g_recv_length] = usart_data_receive(BSP_USART); // 把接收到的数据放到缓冲区中//限制长度g_recv_length=( g_recv_length + 1 ) % USART_RECEIVE_LENGTH;//判断空闲中断是否开启,如果没有开启if( (USART_CTL0(BSP_USART) & 0X10) == 0 ){/* 使能IDLE线检测中断 */usart_interrupt_enable(BSP_USART, USART_INT_IDLE);usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_IDLE);}}if(usart_interrupt_flag_get(BSP_USART,USART_INT_FLAG_IDLE) != RESET) // 检测到帧中断{usart_interrupt_flag_clear(BSP_USART, USART_INT_FLAG_IDLE);//usart_data_receive(BSP_USART);g_recv_buff[g_recv_length] = '\0';g_recv_complete_flag = 1;// 接收完成usart_interrupt_disable(BSP_USART, USART_INT_IDLE);}}复制代码
作者: a老怪, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-4066354.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
文章评论(0条评论)
登录后参与讨论