空闲中断是在监测到数据接收后(即串口的RXNE位被置位)开始检测,当总线上在一个字节对应的周期内未再有新的数据接收时,触发空闲中断IDLE位被硬件置1。
GD32的空闲中断标志位有个特点,没有直接清零的操作,必须读一个字节的数据才能清零。
代码如下:
1. 初始化UART0:
void gd_eval_com_init(uint32_t com)
{
uint32_t com_id = 0U;
if(EVAL_COM0 == com){
com_id = 0U;
}else{
while(1);
}
/* enable GPIO clock */
rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);
/* enable USART clock */
rcu_periph_clock_enable(COM_CLK[com_id]);
/* connect port to USARTx_Tx */
gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]);
/* connect port to USARTx_Rx */
gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]);
/* USART configure */
usart_deinit(com);
usart_baudrate_set(com, 115200U);
usart_receive_config(com, USART_RECEIVE_ENABLE);
usart_transmit_config(com, USART_TRANSMIT_ENABLE);
/* enable USART RBNE interrupt */
usart_interrupt_enable(EVAL_COM0, USART_INT_RBNE);
usart_interrupt_enable(EVAL_COM0, USART_INT_IDLE);
usart_enable(com);
}
2. uart中断函数:
void USART0_IRQHandler(void)
{
uint8_t res = 0;
if(RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_RBNE))
{
/* receive data */
res = usart_data_receive(EVAL_COM0); /*读数据自动清零RBNE*/
gd_eval_led_toggle(LED1);
}
if(RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_IDLE))
{
res = usart_data_receive(EVAL_COM0); /*注意,必须读数据才能清空标志位*/
gd_eval_led_toggle(LED4);
}
}
写到这里就OK了。
你可以在一个任务中去解析这个数据了。
空闲中断比较好用,不至于每次数据中断进行处理数据,而是等到空闲再去处理数据!
引用: w494143467 发表于 2021-1-26 21:43 空闲中断比较好用,不至于每次数据中断进行处理数据,而是等到空闲再去处理数据!
是的,第一次用,确实很好,对于不定长数据接收,比DMA好使
引用: caizhiwei 发表于 2021-1-26 23:12 是的,第一次用,确实很好,对于不定长数据接收,比DMA好使
可以配合DMA一起用,效率更高!