GD32L23x的UART有很多实用的功能,比如接收超时中断、接收缓冲区FIFO等。不过首先还是要掌握基本的功能。
一、初始化
初始化包括:
-
时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
-
引脚
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
- UART初始化和使能。初始化不像STM32那样通过一个结构体设置参数,而是通过函数对每个参数进行的设置。
usart_deinit(USART0);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_baudrate_set(USART0, 115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
二、接收和发送功能
轮询方式
接收的标志位USART_FLAG_RBNE
,当接收缓冲区不为空的时候置位。
void uart_recv_polling(uint8_t* data_buf,uint8_t len)
{
uint8_t i;
for(i=0;i<len;i++){
while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE));
data_buf[i] = usart_data_receive(USART0);
}
}
发送的标志位USART_FLAG_TBE
,当发送缓冲区空的时候置位。
void uart_trans_polling(uint8_t* data_buf,uint8_t len)
{
uint8_t i;
for(i=0;i<len;i++){
usart_data_transmit(USART0, (uint8_t) data_buf[i]);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}
}
中断方式
nvic_irq_enable(USART0_IRQn, 0);
usart_interrupt_enable(USART0, USART_INT_RBNE);//使能接收缓冲区非空中断
usart_interrupt_enable(USART0, USART_INT_TBE);//使能发送缓冲区空中断
usart_interrupt_enable(USART0, USART_INT_TC);//使能发送完成中断
- 重要标志位
USART_INT_FLAG_RBNE
接收缓冲区非空中断标志位
USART_INT_FLAG_TBE
发送缓冲区空中断标志位
注意使用usart_interrupt_enable(USART0, USART_INT_TBE);
使能中断后就会触发一次中断,因为此时接收缓冲区为空
编写一个收到什么数据发送什么数据的中断函数
#define RECV_BUF_LEN 50
char uart_recv_buf[RECV_BUF_LEN];
uint8_t recv_index;
uint8_t tran_index;
void USART0_IRQHandler(void)
{
uint8_t data;
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
uart_recv_buf[recv_index++] = usart_data_receive(USART0);
if(recv_index >= RECV_BUF_LEN){
recv_index = 0;
}
usart_interrupt_enable(USART0, USART_INT_TBE);
}
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE)) {
if(tran_index != recv_index){
usart_data_transmit(USART0,uart_recv_buf[tran_index]);
tran_index++;
if(tran_index >= RECV_BUF_LEN){
tran_index = 0;
}
}
}
}