stm32 对uart的封装

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);
			...
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值