跳转至

通用异步收发传输器(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。