项目场景:
MCU-GD32E230G8U6TR:
最近项目需求需要使用GD32E230G8U6TR这款MCU开发MODBUS通信,modbus开发需要使用帧中断功能,而网上GD32关于这一块的内容资料不是很多,兆易官网也没找到合适的例程,没办法只能自己照着手册折腾了好久。
解决方案:
提示 根据用户手册的介绍来看,串口中断功能中自带接收超时中断功能,使用过程先调用usart_receiver_timeout_threshold_config(USARTX,timerout)函数设置超时时间阈值,这里timeout参数是按传输的位来计算,例如填入10则表示在10个BIT的时间内没有新数据过来就触发超时。usart_receiver_timeout_enable(USARTX)函数使能串口接收超时功能
usart_interrupt_enable(USART0, USART_INT_RT)函数使能接收超时中断
@Override
/* USART configure */
usart_deinit(USARTX);
usart_baudrate_set(USARTX,BAUDRATE);
usart_transmit_config(USARTX, USART_TRANSMIT_ENABLE);//使能发送
usart_receive_config(USARTX, USART_RECEIVE_ENABLE);//使能接收
usart_receiver_timeout_threshold_config(USARTX,1000);//设置串口接收超时阈值,这个100是指100bit时间,如果按照10bit传输一个字节,那么就是10个字节时间
usart_receiver_timeout_enable(USARTX);
usart_enable(USARTX);
nvic_irq_enable(USART0_IRQn, 0);
usart_interrupt_enable(USART0, USART_INT_RBNE); //使能读取数据缓冲区不空中断和溢出错误中断
usart_interrupt_enable(USART0, USART_INT_RT);//使能串口接收超时中断
}
在串口中断回调函数中,判断中断标志并进行处理,串口超时中断触发一次后调用usart_flag_clear(USART0,USART_FLAG_RT);函数清楚中断标志
/*!
\brief 串口0中断处理函数
\param[in] none
\param[out] none
\retval none
*/
void USART0_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){ //读取数据缓冲区不为空标志
/* receive data */
//receiver_buffer[rxcount++] = usart_data_receive(USART0);
receiver_buffer[rxcount] = usart_data_receive(USART0);
if(rxcount == receivesize){
usart_interrupt_disable(USART0, USART_INT_RBNE);
}
}
if((RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE))){ //发送缓冲区为空标志
/* transmit data */
usart_data_transmit(USART0, transmitter_buffer[txcount++]);
if(txcount == transfersize){
usart_interrupt_disable(USART0, USART_INT_TBE);
}
}
if(RESET != usart_interrupt_flag_get(USART0,USART_INT_FLAG_RT)){ //接收中断超时标志
LED_TOGGLE();
usart_flag_clear(USART0,USART_FLAG_RT);
}
}