- 1,概述
- 2,API参考
- 2.1 主要结构体、枚举、联合体介绍
- 2.2 主要函数介绍
- 2.2.1 UART开启
- 2.2.2 UART重开启
- 2.2.3 UART关闭
- 2.2.4 UART开启查询
- 2.2.5 UART进入睡眠
- 2.2.6 UART唤醒
- 2.2.7 改变UART波特率
- 2.2.8 UART暂停
- 2.2.9 UART继续
- 2.2.10 判断UART是否可读
- 2.2.11 判断UART是否可写
- 2.2.12 获取单个字符
- 2.2.13 发送单个字符
- 2.2.14 获取阻塞单个字符
- 2.2.15 发送阻塞单个字符
- 2.2.16 获取UART标志位寄存器
- 2.2.17 获取UART状态位寄存器
- 2.2.18 清除UART状态位
- 2.2.19 设置break信号
- 2.2.20 清除break信号
- 2.2.21清空FIFO
- 2.2.22 清除IRQ
- 2.2.23 设置irq handler
- 2.2.24 UART DMA接收开始
- 2.2.25 UART DMA设置irq handler
- 2.2.26 UART DMA 双缓存接收开始
- 2.2.27 UART DMA 寻址接收
- 2.2.29 获取UART DMA接收地址
- 2.2.30 停止UART DMA接收
- 2.2.31 UART DMA发送
- 2.2.32 UART DMA发送停止
- 3,使用教程
1,概述
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为 UART)是一种异步收发传输器,提供了与外部设备进行全双工数据交换的灵活方式。
2,API参考
2.1 主要结构体、枚举、联合体介绍
2.1.1 UART_ID枚举
在makefile文件或者头文件中可以定义CHIP_HAS_UART宏,用于移植至拥有不同数量UART的芯片型号。
enum HAL_UART_ID_T {
HAL_UART_ID_0 = 0,
#if (CHIP_HAS_UART >= 2) //芯片拥有2个UART
HAL_UART_ID_1,
#endif
#if (CHIP_HAS_UART >= 3) //芯片拥有3个UART
HAL_UART_ID_2,
#endif
#if (CHIP_HAS_UART >= 4) //芯片拥有4个UART
HAL_UART_ID_3,
#endif
#ifdef BT_UART
HAL_UART_ID_BT,
#endif
HAL_UART_ID_QTY
};
2.1.2 串口通信各参数枚举
串口通信时需要设置数据位、校验位、停止位等参数,这些参数都被规定在下列枚举中
校验位枚举
enum HAL_UART_PARITY_T {
HAL_UART_PARITY_NONE, //无校验
HAL_UART_PARITY_ODD, //奇校验
HAL_UART_PARITY_EVEN, //偶校验
HAL_UART_PARITY_FORCE1, //校验位强制为1
HAL_UART_PARITY_FORCE0, //校验位强制为0
};
停止位枚举
enum HAL_UART_STOP_BITS_T {
HAL_UART_STOP_BITS_1, //停止位1位
HAL_UART_STOP_BITS_2, //停止位2位
};
数据位枚举
enum HAL_UART_DATA_BITS_T { HAL_UART_DATA_BITS_5, //数据位5位 HAL_UART_DATA_BITS_6, //数据位6位 HAL_UART_DATA_BITS_7, //数据位7位 HAL_UART_DATA_BITS_8, //数据位8位 };
流控制枚举
enum HAL_UART_FLOW_CONTROL_T { HAL_UART_FLOW_CONTROL_NONE, //无流控制 HAL_UART_FLOW_CONTROL_RTS, //RTS流控制 HAL_UART_FLOW_CONTROL_CTS, //CTS流控制 HAL_UART_FLOW_CONTROL_RTSCTS, //RTS CTS流控制 };
FIFO中断深度级别枚举
enum HAL_UART_FIFO_LEVEL_T { HAL_UART_FIFO_LEVEL_1_8, //在1/8深度时产生中断 HAL_UART_FIFO_LEVEL_1_4, //在1/4深度时产生中断 HAL_UART_FIFO_LEVEL_1_2, //在1/2深度时产生中断 HAL_UART_FIFO_LEVEL_3_4, //在3/4深度时产生中断 HAL_UART_FIFO_LEVEL_7_8, //在7/8深度时产生中断 };
注:当FIFO里剩余的数据减少(发送时)或累计(接收时)到预设的深度时触发中断。
UART传输模式枚举
enum HAL_UART_XFER_TYPE_T { HAL_UART_XFER_TYPE_TX = (1 << 0), //发送模式 HAL_UART_XFER_TYPE_RX = (1 << 1), //接收模式 };
注:在配置UART时不会用到传输模式枚举,只有在UART暂停和UART继续两个函数中有使用到
2.1.3 UART配置结构体
struct HAL_UART_CFG_T {
enum HAL_UART_PARITY_T parity; //校验位
enum HAL_UART_STOP_BITS_T stop; //停止位
enum HAL_UART_DATA_BITS_T data; //数据位
enum HAL_UART_FLOW_CONTROL_T flow; //流控制
enum HAL_UART_FIFO_LEVEL_T rx_level; //FIFO接收中断深度
enum HAL_UART_FIFO_LEVEL_T tx_level; //FIFO发送中断深度
uint32_t baud; //波特率
bool dma_rx : 1; //dma接收
bool dma_tx : 1; //dma发送
bool dma_rx_stop_on_err : 1; //dma接受错误停止
};
2.1.4 UART各个寄存器联合体
UART状态寄存器联合体
union HAL_UART_STATUS_T { struct { uint32_t FE :1; // frame error uint32_t PE :1; // parity error uint32_t BE :1; // break error uint32_t OE :1; // overrun error }; uint32_t reg; };
UART标志位寄存器联合体
union HAL_UART_FLAG_T { struct { uint32_t CTS :1; uint32_t DSR :1; uint32_t DCD :1; uint32_t BUSY :1; uint32_t RXFE :1; // rx fifo empty uint32_t TXFF :1; // tx fifo full uint32_t RXFF :1; // rx fifo full uint32_t TXFE :1; // tx fifo empty uint32_t RI :1; // ring indicator }; uint32_t reg; };
UART中断寄存器联合体
union HAL_UART_IRQ_T { struct { uint32_t RIM :1; // ri uint32_t CTSM :1; // cts uint32_t DCDM :1; // dcd uint32_t DSRM :1; // dsr uint32_t RX :1; // rx uint32_t TX :1; // tx uint32_t RT :1; // receive timeout uint32_t FE :1; // framing error uint32_t PE :1; // parity error uint32_t BE :1; // break error uint32_t OE :1; // overrun }; uint32_t reg; };
2.1.5 UART中断回调函数指针
//UART中断 typedef void (*HAL_UART_IRQ_HANDLER_T)(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T status); //dma接收中断 typedef void (*HAL_UART_IRQ_RXDMA_HANDLER_T)(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status); //dma发送中断 typedef void (*HAL_UART_IRQ_TXDMA_HANDLER_T)(uint32_t xfer_size, int dma_error);
2.2 主要函数介绍
2.2.1 UART开启
函数原型:
int hal_uart_open(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg);
功能描述:打开指定UART
函数参数:
函数原型:
int hal_uart_reopen(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg);
功能描述:重新打开指定UART
函数参数:
函数原型:
int hal_uart_close(enum HAL_UART_ID_T id);
功能描述:关闭指定UART
函数参数:
函数原型:
int hal_uart_opened(enum HAL_UART_ID_T id);
功能描述:查询指定UART是否开启
- 函数参数:
- id:UART id
返回值:
函数原型:
void hal_uart_sleep(void);
-
2.2.6 UART唤醒
函数原型:
void hal_uart_wakeup(void);
-
2.2.7 改变UART波特率
函数原型:
int hal_uart_change_baud_rate(enum HAL_UART_ID_T id, uint32_t rate);
功能描述:改变指定UART的波特率
- 函数参数:
- id:UART id
- rate:指定波特率
返回值:
函数原型:
int hal_uart_pause(enum HAL_UART_ID_T id, enum HAL_UART_XFER_TYPE_T type);
功能描述:暂停指定UART的接收或发送
- 函数参数:
- id:UART id
- type:接收或发送模式
返回值:
函数原型:
int hal_uart_continue(enum HAL_UART_ID_T id, enum HAL_UART_XFER_TYPE_T type);
功能描述:继续UART接收或发送数据
- 函数参数:
- id:UART id
- type:接收或发送模式
返回值:
函数原型:
int hal_uart_readable(enum HAL_UART_ID_T id);
功能描述:判断指定UART是否可读
- 函数参数:
- id:UART id
返回值:
函数原型:
int hal_uart_writeable(enum HAL_UART_ID_T id);
功能描述:判断指定UART是否可写
- 函数参数:
- id:UART id
返回值:
函数原型:
uint8_t hal_uart_getc(enum HAL_UART_ID_T id);
功能描述:获取指定UART收到的单个字符
- 函数参数:
- id:UART id
返回值
函数原型:
int hal_uart_putc(enum HAL_UART_ID_T id, uint8_t c);
功能描述:发送一字节字符
- 函数参数:
- id:UART id
- c:待发送字符
返回值:
函数原型:
uint8_t hal_uart_blocked_getc(enum HAL_UART_ID_T id);
功能描述:等待直至指定UART可读后获取单个字符
- 函数参数:
- id:UART id
返回值:
函数原型:
int hal_uart_blocked_putc(enum HAL_UART_ID_T id, uint8_t c);
功能描述:等待直至指定UART可写后发送单个字符
- 函数参数:
- id:UART id
- c:待发送字符
返回值
函数原型:
union HAL_UART_FLAG_T hal_uart_get_flag(enum HAL_UART_ID_T id);
功能描述:获取指定UART的标志位寄存器值
- 函数参数:
- id:UART id
返回值:
函数原型:
union HAL_UART_STATUS_T hal_uart_get_status(enum HAL_UART_ID_T id);
功能描述:获取指定UART的状态位寄存器值
- 函数参数:
- id:UART id
返回值:
函数原型:
void hal_uart_clear_status(enum HAL_UART_ID_T id);
功能描述:将指定UART状态位寄存器清0
函数参数:
函数原型:
void hal_uart_break_set(enum HAL_UART_ID_T id);
功能描述:指定UART设置break信号
函数参数:
函数原型:
void hal_uart_break_clear(enum HAL_UART_ID_T id);
函数功能:清除指定UART的break信号
函数参数:
函数原型
void hal_uart_flush(enum HAL_UART_ID_T id, uint32_t ticks);
函数功能:接收完当前最后一个字符后,清空FIFO缓存
函数参数:
函数原型:
void hal_uart_clear_irq(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T irq);
函数功能:清除指定UART irq
函数参数:
函数原型:
HAL_UART_IRQ_HANDLER_T hal_uart_irq_set_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_HANDLER_T handler);
函数功能:为指定UART设置irq
- 函数参数:
- id:UART id
- handler:irq handler
返回值:
函数原型:
int hal_uart_dma_recv(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt);
函数功能:UART DMA接收开始
- 函数参数:
- id:UART id
- *buf:UART buffer
- len:BUART buffer length
- *desc:dma参数结构体
- desc_cnt:descriptor count
返回值:
函数原型:
void hal_uart_irq_set_dma_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_RXDMA_HANDLER_T rxdma, HAL_UART_IRQ_TXDMA_HANDLER_T txdma);
函数功能:设置UART DMA的接收与发送中断
函数参数:
函数原型:
int hal_uart_dma_recv_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt);
函数功能:UART DMA 双缓存接收开始
- 函数参数:
- id:UART id
- *buf:UART buffer
- len:BUART buffer length
- *desc:dma参数结构体
- desc_cnt:descriptor count
返回值:
函数原型: ```c int hal_uart_dma_recv_mask(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, const union HAL_UART_IRQ_T *mask);
- 函数功能:UART DMA 寻址接收开始
- 函数参数:
- id:UART id
- *buf:UART buffer
- len:BUART buffer length
- *desc:dma参数结构体
- desc_cnt:descriptor count
- mask:寻址掩码
- 返回值:
- 0:成功
<a name="IuhXs"></a>
### 2.2.28 UART DMA 双缓存寻址接收
- 函数原型:
```c
int hal_uart_dma_recv_mask_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,
const union HAL_UART_IRQ_T *mask, uint32_t step);
- 函数功能:UART DMA 寻址接收开始
- 函数参数:
- id:UART id
- *buf:UART buffer
- len:BUART buffer length
- *desc:dma参数结构体
- desc_cnt:descriptor count
- mask:寻址掩码
- step:传输步骤次数
返回值:
函数原型:
uint32_t hal_uart_get_dma_recv_addr(enum HAL_UART_ID_T id);
函数功能:获取DMA接收地址
- 函数参数:
- id:UART id
返回值:
函数原型:
uint32_t hal_uart_stop_dma_recv(enum HAL_UART_ID_T id);
函数功能:停止UART DMA接收
- 函数参数:
- id:UART id
返回值
函数原型:
int hal_uart_dma_send(enum HAL_UART_ID_T id, const uint8_t *buf, uint32_t len, struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt);
函数功能:UART DMA发送数据
函数参数:
函数原型:
uint32_t hal_uart_stop_dma_send(enum HAL_UART_ID_T id);
函数功能:停止UART DMA发送
- 函数参数:
- id:UART id
返回值
UART的配置信息通过新建HAL_UART_CFG_T来进行配置,如下
static struct HAL_UART_CFG_T uart_cfg = { .parity = HAL_UART_PARITY_NONE, .stop = HAL_UART_STOP_BITS_1, .data = HAL_UART_DATA_BITS_8, .flow = HAL_UART_FLOW_CONTROL_NONE, .tx_level = HAL_UART_FIFO_LEVEL_1_2, .rx_level = HAL_UART_FIFO_LEVEL_1_4, // max 16 bytes received once, it does not work to change it to other values. .baud = 921600, .dma_rx = false, .dma_tx = false, .dma_rx_stop_on_err = false, };
当确定好UART配置后,接下来需要决定使用哪个UART,并使用iomux头文件中的API进行UART IO口配置
hal_set_uart_iomux(uart_id); //uart id为enum HAL_UART_ID_T枚举
随后启用UART即可
hal_uart_open(uart_id, &uart_cfg); //uart id为enum HAL_UART_ID_T枚举 //uart_cfg为前文中定义的UART配置结构体
3.3 UART的接收与发送
利用2.2.x中的各类API可以采用不同的方式来接收与发送数据,这里采用最基础的API来实现一个基础的UART ECHO功能
UART发送处理函数
static void uart_tx(const void *buf, int len) //void *buf确保能发送各种类型数据 { int i; for (i = 0; i < len; i++) { hal_uart_blocked_putc(uart_id, *((char *)buf + i)); //使用阻塞发送函数,确保数据不会因为UART繁忙而取消发送 } }
UART接收处理函数
static void uart_rx(void) { static uint32_t i = 0; while (hal_uart_readable(uart_id)) { ASSERT(i < sizeof(uart_buf), "buf full"); //确认buffer是否溢出 uart_buf[i++] = hal_uart_getc(uart_id); //获取接收数据并存储在buffer内 } if (i > 0) { uart_tx(uart_buf, i); //ECHO i = 0; } }
ECHO主函数
void uart_echo(void) { printf("[%s:%d] %s\r\n", __FILE__, __LINE__, __func__); //log信息 hal_set_uart_iomux(uart_id); //UART IO设置 hal_uart_open(uart_id, &uart_cfg); //开启UART while (1) { uart_rx(); //轮询接收数据 osDelay(10); } }