嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > 超级精简系列之十六:基于IO模拟+FIFO的串口驱动

超级精简系列之十六:基于IO模拟+FIFO的串口驱动

一. 前言

接上一篇预告,结合前面实现的FIFO和前面实现的IO模拟串口。我们这一篇继续超级精简系列,来实现基于FIFO的串口驱动。

 超级精简系列之十四:超级精简的IO模拟UART发送

 超级精简系列之十三:超级精简的循环FIFO,C实现

测试环境为HPM5300evk开发板,如果需要该工程可以留言。当然直接从系列文章中复制源码也可以很快捷的移植到任意平台。

二. 实现过程

Uart_fifo.c

包含头文件

#include <uart_tx_port.h>
#include <uart_rx_port.h>
#include <rtthread.h>
#include "fifo.h"

Fifo实例创建

/* FIFO设备实例 */
static uint8_t fifo_buffer[1024];
static fifo_st fifo_dev=
{
.in=0,
.out=0,
.len=0,
.buffer_len=sizeof(fifo_buffer),
.buffer=fifo_buffer
};

接收到数据写入fifo

/* 接收到数据写入fifo */
static void rx_cb(uint8_t val){
uint8_t tmp = val;
rt_enter_critical();
fifo_in(&fifo_dev, &tmp, 1);
rt_exit_critical();
}

初始化和解除初始化

void suart_init(void)
{
sw_uart_tx_init();
sw_uart_rx_init();
sw_uart_rx_start(1,rx_cb);
}
void suart_deinit(void)
{
sw_uart_tx_deinit();
sw_uart_rx_deinit();
}

读接口

uint32_t suart_read(uint8_t* buffer, uint32_t size)
{
uint32_t len;
rt_enter_critical();
len = fifo_out(&fifo_dev, buffer, size);
rt_exit_critical();
return len;
}

写接口

uint32_t suart_write(uint8_t* buffer, uint32_t size)
{
for(uint32_t i=0; i<size; i++)
{
sw_uart_tx_byte(buffer[i]);
}
return size;
}

uart_fifo.h接口

#ifndef UART_FIFO_H
#define UART_FIFO_H
#ifdef __cplusplus
extern "C"{
#endif
#include <stdint.h>
void suart_init(void);
void suart_deinit(void);
uint32_t suart_read(uint8_t* buffer, uint32_t size);
uint32_t suart_write(uint8_t* buffer, uint32_t size);
#ifdef __cplusplus
}
#endif
#endif

三. 测试

测试代码如下,可以看到此时接口非常简单了,只要初始化,调用读写接口即可。对于应用层来说已经非常方便使用了。并且底层基于FIFO所以也很高效。这就是我们层层搭建轮子的目的,给应用提供简单好用高效的接口。

我们使用串口调试助手连续发送,开发板收到原样返回。

uint8_t buffer[64];
void thread_entry(void *arg){
suart_init();
while(1){
int len = suart_read(buffer,sizeof(buffer));
if(len > 0)
{
suart_write(buffer,len);
}
}
}

可以看到收发完全一致。

四. 总结

可以看到经过层层的轮子构建,装配,哪怕是使用IO我们也可以实现方便好用的串口驱动。可以看到平常积累我们自己的轮子是多么重要,这也是本系列超级精简系类文章的意义。