【GD32自用】GD32串口中断收发不定长数据
GD32串口中断收发不定长数据
1.利用串口空闲中断
串口在空闲时,也就是说串口在一段时间里没有接收到新数据,则会触发空闲中断。在中断函数中实现数据的处理,完成后再开启下一帧的数据。
2.代码
使用的芯片为GD32F303CCT6,在主函数调用uart_init()即可。
头文件变量定义:
#include <string.h>
#include "gd32f30x.h"
uint8_t buff[20]={0};//接收数组(不够可以加大)
配置串口:
void uart_init(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART1);
/* connect port to USARTx_Tx */
gpio_init(RCU_GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
/* connect port to USARTx_Rx */
gpio_init(RCU_GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
/* USART configure */
usart_deinit(USART1);
usart_baudrate_set(USART1, 115200);
usart_word_length_set(USART1,USART_WL_8BIT);
usart_parity_config(USART1, USART_PM_NONE);
usart_stop_bit_set(USART1, USART_STB_1BIT);
usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
usart_interrupt_enable(USART1,USART_INT_RBNE);
usart_interrupt_enable(USART1,USART_INT_IDLE); //使能空闲中断
nvic_irq_enable(USART1_IRQn,0,0);
usart_enable(USART1);
}
重定向:
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART1, (uint8_t)ch);
while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
return ch;
}
发送字节数组函数:
void usart1_send_byte(uint8_t byte) //发送单个字节
{
usart_data_transmit(USART1, byte);
while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
}
void buff_send(uint8_t *buff) //发送数组
{
int a = 0;
while(buff[a])
{
usart1_send_byte(buff[a++]);
}
}
中断处理函数:
注意:空闲中断执行完一次后要关闭空闲中断,不然会一直进入空闲中断,可在接收中断中再打开空闲中断。(也可自定义标志位进行处理)
void USART1_IRQHandler(void)
{
static uint8_t i = 0;
if (usart_interrupt_flag_get(USART1,USART_INT_FLAG_RBNE))
{
uint8_t RxData = usart_data_receive(USART1);
buff[i]=RxData;
i++;
usart_interrupt_flag_clear(USART1,USART_INT_FLAG_RBNE);
usart_interrupt_enable(USART1,USART_INT_RBNE);
//此处使能空闲中断,完成接收后可以进入空闲中断
usart_interrupt_enable(USART1,USART_INT_IDLE);
}
if (usart_interrupt_flag_get(USART1,USART_INT_FLAG_IDLE))
{
buff_send(buff); //将接收完的数据发送
i = 0; //指向清零
memset(buff,0,sizeof(buff));//清空buff
usart_interrupt_flag_clear(USART1,USART_INT_FLAG_IDLE);
//空闲中断执行完一次后要关闭空闲中断,不然会一直进入空闲中断
usart_interrupt_disable(USART1,USART_INT_IDLE);
}
}
3.实验现象
作者:后摇疯子