hal库的uart驱动用起来不太顺手,因此对ll库的uart驱动重新封装,基本流程是将要发送的数据保存到发送fifo,通过发送完成中断驱动发送过程,通过接收完成中断将接收到的数据保存到接收fifo,应用程式查询并读取接收fifo的内容从而完成接收过程
封装是对各个uart独立处理的,下文以uart1举例。
定义fifo结构体
typedef struct
{
uint32_t write;
uint32_t read;
uint8_t *buf;
}uart_fifo_t;
定义发送,接收fifo:
#define UART1_TX_BUF_SIZE 256
#define UART1_RX_BUF_SIZE 256
uint8_t uart1_tx_buf[UART1_TX_BUF_SIZE], uart1_rx_buf[UART1_RX_BUF_SIZE];
uart_fifo_t uart1_tx_fifo = { 0, 0, uart1_tx_buf };
uart_fifo_t uart1_rx_fifo = { 0, 0, uart1_rx_buf };
串口初始化和启动后,使能发送完成中断,接收完成中断。
LL_USART_EnableIT_RXNE(USART1); //使能接收完成中断
LL_USART_EnableIT_TC(USART1); //使能发送完成中断
uart1中断处理函数
void USART1_IRQHandler(void)
{
if (LL_USART_IsActiveFlag_RXNE(USART1) && LL_USART_IsEnabledIT_RXNE(USART1))
{
//接收完成中断, 读取RDR后,接收完成中断标志自动清零
uart1_rx_fifo.buf[uart1_rx_fifo.write] = LL_USART_ReceiveData8(USART1);
if(++uart1_rx_fifo.write >= UART1_RX_BUF_SIZE) uart1_rx_fifo.write = 0;
if(uart1_rx_fifo.write == uart1_rx_fifo.read)
{
if(++uart1_rx_fifo.read >= UART1_RX_BUF_SIZE) uart1_rx_fifo.read = 0;
}
uart1_data_received = 1;
}
else if (LL_USART_IsActiveFlag_TC(USART1) && LL_USART_IsEnabledIT_TC(USART1))
{
//发送完成中断
LL_USART_ClearFlag_TC(USART1);//手动清除中断标志
if(uart1_tx_fifo.write == uart1_tx_fifo.read)
{
uart1_tx_processing = false;
return;
}
LL_USART_TransmitData8(USART1, uart1_tx_fifo.buf[uart1_tx_fifo.read]);
if(++uart1_tx_fifo.read >= UART1_TX_BUF_SIZE) uart1_tx_fifo.read = 0;
uart1_tx_processing = true;
}
else
{
//异常或错误中断处理
/* Disable USARTx_IRQn */
NVIC_DisableIRQ(USART1_IRQn);
LL_USART_ClearFlag_PE(USART1);
LL_USART_ClearFlag_FE(USART1);
LL_USART_ClearFlag_NE(USART1);
LL_USART_ClearFlag_ORE(USART1);
LL_USART_ClearFlag_IDLE(USART1);
NVIC_EnableIRQ(USART1_IRQn);
}
}
发送数据接口,将待发送的数据保存到fifo
void uart1_write_data_to_tx_fifo(uint8_t *buf, int buf_len)
{
if(!uart1_is_on) return;
uint32_t write;
for(int i = 0; i < buf_len; i++)
{
write = uart1_tx_fifo.write;
if(++write >= UART1_TX_BUF_SIZE) write = 0;
if(write == uart1_tx_fifo.read)
{
break;//fifo 已满
}
uart1_tx_fifo.buf[uart1_tx_fifo.write] = *buf++;
uart1_tx_fifo.write = write;
}
if(uart1_tx_processing == false)
{
//发送第1个字节
LL_USART_TransmitData8(USART1, uart1_tx_fifo.buf[uart1_tx_fifo.read]);
if(++uart1_tx_fifo.read >= UART1_TX_BUF_SIZE) uart1_tx_fifo.read = 0;
uart1_tx_processing = true;
}
}
void uart1_write_char_to_tx_fifo(uint8_t c)
{
...
}
接收fifo检查&接收
bool uart1_rx_fifo_is_empty(void)
{
return (uart1_rx_fifo.write == uart1_rx_fifo.read);
}
bool uart1_read_char_from_rx_fifo(uint8_t *c)
{
if(uart1_rx_fifo.write == uart1_rx_fifo.read) return false;
*c = uart1_rx_fifo.buf[uart1_rx_fifo.read];
if(++uart1_rx_fifo.read >= UART1_RX_BUF_SIZE) uart1_rx_fifo.read = 0;
return true;
}
printf 重定向
int fputc(int ch, FILE *f)
{
uart1_write_char_to_tx_fifo(ch);
return ch;
}
发送数据应用:
uart1_write_data_to_tx_fifo(buf, buf_len);
uart1_write_char_to_tx_fifo('a');
printf("uart1 test");
接收数据应用:
uint8_t c;
while(1)
{
if(uart1_data_received )
{
uart1_data_received = 0;
while(!uart1_rx_fifo_is_empty())
{
uart1_read_char_from_rx_fifo(&c);
...
}
}
}