通用异步收发传输器(UART)¶
1、简介¶
UART(通用异步收发传输器)是一种通用串行数据总线,用于异步通信;可以实现全双工传输和接收。
CI14LP芯片共有UART0、UART1、UART2三路UART,FIFO深度64字节,支持轮询、中断、DMA三种工作模式,波特率最大支持3000000(3M),并内置波特率自动检测(自适应)功能。
2、时序¶
2.1、 基础简介¶
- UART工作原理是将数据的二进制位一位一位的进行传输。在UART通讯协议中信号线上的状态位高电平代表‘1’低电平代表‘0’
- 硬件连接比较简单,仅需要3条线,TX、RX、GND
- TX(发送数据端,要接对面设备的RX)
- RX(接收数据端,要接对面设备的TX)
- 空闲位(当总线处于空闲状态时信号线的状态为‘1’即高电平)
- 起始位(开始传输时要先发出一个低电平‘0’来表示传输字符的开始)
- 数据位(起始位之后就是要传输的数据,数据一般都是8位。先发送最低位最后发送最高位)
- 奇偶校验位(数据位传送完成后,要进行奇偶校验)
- 停止位(数据结束标志,可以是1位,1.5位,2位的高电平)
- 波特率(传输一个比特需要的时间是(1/波特率)秒)
3、API¶
| 函数名 | 描述 |
|---|---|
| uart_polling_config | UART 轮询模式初始化配置(8N1,屏蔽所有中断) |
| uart_interrupt_config | UART 中断模式初始化配置(含引脚、中断使能) |
| uart_dma_config | UART DMA模式初始化配置(可选byte/halfword/word宽度) |
| uart_baudrate_config | UART 波特率配置 |
| uart_frame_config | UART 帧格式配置(数据位/停止位/校验位) |
| uart_polling_send_data | 轮询方式发送一个Byte数据 |
| uart_polling_receive_data | 轮询方式接收一个Byte数据 |
| uart_polling_send_word | 轮询方式发送一个word数据(32位) |
| uart_polling_send_done | 等待UART发送完毕 |
| uart_tx_data | 发送单个数据(byte或word,需确保FIFO不满) |
| uart_rx_byte | 接收单个byte(需确保FIFO不为空) |
| uart_irq_mask_config | UART 中断屏蔽设置 |
| uart_clear_irq | UART 清除中断标志 |
| uart_mask_irq_state | UART 屏蔽后的中断状态查询 |
| uart_raw_irq_state | UART 原始中断(屏蔽前)状态查询 |
| uart_get_state | 读 UART 状态寄存器标志值 |
| uart_fifo_clear | 清除 UART FIFO数据 |
| uart_rxfifo_depth_config | UART 接收FIFO触发深度配置 |
| uart_txfifo_depth_config | UART 发送FIFO触发深度配置 |
| uart_txfifo_byteword_config | 设置发送FIFO数据位宽(byte/word) |
| uart_control_config | UART 控制使能(RX/TX/DMA/回环等) |
| uart_timeout_config | UART 接收超时设置(单位:bit位时间) |
| uart_set_clk_base | 根据波特率配置外设时钟并打开时钟 |
| uart_set_baud_samplerate | 设置波特率检测的过采样率 |
| uart_get_baud_dev_val / uart_get_baud_bit_num / uart_get_baud_dev_hl_state | 波特率偏差检测相关 |
4、关键类型¶
| 类型 | 说明 |
|---|---|
| uart_datawidth_t | 数据位宽:UART_DATAWIDTH_5b~8b |
| uart_stopbits_t | 停止位:UART_STOPBITS_1 / 1_5 / 2 |
| uart_parity_t | 校验位:UART_PARITY_NO / ODD / EVEN |
| uart_byteword_t | 发送模式:UART_BYTE / UART_WORD |
| uart_irq_t | 中断类型:UART_RX_IRQ、UART_TX_IRQ、UART_RX_TIMEOUT_IRQ、UART_ERROR_DATA_IRQ、UART_PARITY_ERROR_IRQ、UART_FRAMING_ERROR_IRQ、UART_OVERRUN_ERROR_IRQ、UART_BAUD_VALID_IRQ等,UART_ALL_IRQ |
| uart_flag_t | 状态标志:UART_TXFIFO_BUSY、UART_RXFIFO_EMPTY、UART_RXFIFO_FULL、UART_TXFIFO_EMPTY、UART_TXFIFO_FULL、UART_CURRTRANS_END、UART_RX_DATA_ERR、UART_RX_TIMEOUT |
| uart_crbitctrl_t | 控制位:UART_EN、UART_RX、UART_TX、UART_NCED(忽略错误数据)、UART_DMA_RX、UART_DMA_TX、UART_LOOPBACK、UART_BAUD_DTCT(波特率自适应检测) |
| uart_rxfifolevel_t | RX FIFO触发深度:UART_RXFIFOLEVEL1_BYTE / 2_BYTE / 1_8 / 1_4 / 1_2 / 3_4 / 7_8 |
| uart_dmawidth_t | DMA宽度:UART_DMAWIDTH_BYTE / HALFWORD / WORD |
5、示例¶
1) 以下代码配置UART0轮询模式,发送和接收数据,收发完毕后进行数据对比验证:
#include "ci14lp_uart.h"
void main(void)
{
int i;
unsigned char buf_send[32] = {0x0};
unsigned char buf_recv[32] = {0x0};
//初始化发送接收数据数组
for(i = 0; i < 32; i++)
{
buf_send[i] = i;
}
//初始化UART0(轮询模式),波特率115200
uart_polling_config(UART0, 115200);
//发送数据:每次发送一个byte
for(i = 0; i < 32; i++)
{
uart_polling_send_data(UART0, buf_send[i]);
}
//接收数据:每次接收一个byte
for(i = 0; i < 32; i++)
{
buf_recv[i] = uart_polling_receive_data(UART0);
}
//比较接收发送数据是否相等
for(i = 0; i < 32; i++)
{
if(buf_send[i] != buf_recv[i])
{
mprintf("Comparison of the Data Fail\n");
while(1);
}
}
mprintf("Comparison of the Data Successful\n");
while(1);
}
2) 以下代码配置协议串口为中断模式(示例工程串口协议初始化,projects\offline_asr_sample\src\user_msg_deal.c):
//协议串口初始化(中断模式),波特率由user_config.h配置
uart_interrupt_config((UART_TypeDef *)UART_PROTOCOL_NUMBER, UART_PROTOCOL_BAUDRATE);
UART中断接收处理函数示例:
#include "ci14lp_uart.h"
void UART1_IRQHandler(void)
{
/*接受数据*/
if (uart_mask_irq_state(UART1, UART_RX_IRQ))
{
unsigned char rxdata = uart_rx_byte(UART1);
//协议组件按字节解析,如二代协议:vmup_receive_packet(rxdata);
uart_clear_irq(UART1, UART_RX_IRQ);
}
uart_clear_irq(UART1, UART_ALL_IRQ);
}
3) 以下代码配置UART DMA模式并使用DMA方式发送和接收数据:
#include "ci14lp_uart.h"
#include "ci14lp_dma.h"
unsigned char buf_send[2048] = {0};
unsigned char buf_recv[2048] = {0};
void main(void)
{
int i = 0;
//初始化发送接收数据数组
for(i = 0; i < 2048; i++)
{
buf_send[i] = i;
}
//初始化UART0(DMA模式)
uart_dma_config(UART0, 115200, UART_DMAWIDTH_BYTE);
//DMA接收数据(外设到内存)
dma_m2p_p2m_mode_config(DMA_CHANNEl_0, DMA_PERIPHERAL_UART0_RX, P2M_DMA,
UART0_DMA_ADDR, (uint32_t)buf_recv, 2048,
TRANSFER_WIDTH_8B, BURST_SIZE_1, DMA_AHB_MASTER_1);
//DMA发送数据(内存到外设)
dma_m2p_p2m_mode_config(DMA_CHANNEl_0, DMA_PERIPHERAL_UART0_TX, M2P_DMA,
(uint32_t)buf_send, UART0_DMA_ADDR, 2048,
TRANSFER_WIDTH_8B, BURST_SIZE_1, DMA_AHB_MASTER_1);
//等待DMA传输完成
if(RETURN_ERR == dma_wait_translate_flag(DMA_CHANNEl_0, 0xffffff))
{
mprintf("dma irq err\n");
while(1);
}
//比较接收发送数据是否相等
for(i = 0; i < 2048; i++)
{
if(buf_send[i] != buf_recv[i])
{
mprintf("Comparison of the Data Fail\n");
while(1);
}
}
mprintf("Comparison of the Data Successful\n");
while(1);
}
6、其它¶
- 常用的波特率范围:2400、4800、9600、19200、38400、57600、115200、230400、380400、460800、921600、1M、2M、3M(最大3000000)。
- 通信协议/调试串口波特率大于768000时需定义
BUILD_BOARD_PARAM_HIGH;该宏与UNDERCLOCKING_EN(降频模式)同时开启会编译报错,降频下不支持高波特率。 - 波特率自适应检测:
uart_control_config中使能UART_BAUD_DTCT后,可通过uart_get_baud_dev_val()等接口读取检测状态,SDK 上电流程中的send_baudrate_sync_req()即基于该机制实现波特率校准。
7、API 参考¶
本模块接口声明于 driver\ci14lp_chip_driver\inc\ci14lp_uart.h,实现位于 driver\ci14lp_chip_driver\src\ci14lp_uart.c。