UART 使用指南

概述

UART (Universal Asynchronous Receiver and Transmitter)

BK7238 包括两个通用异步收发器(UART)接口,可提供波特率高达6Mbps的全双工异步串行通信。它们支持5/6/7/8位数据,以及偶数、奇数或无奇偶校验。停止位可以是1位或2位。UART1支持Flash下载。

UART Connection

UART Connection

上图为UART串口TTL电平硬件连接,其中:

  • TXD:用于发送数据,应连接到接收设备的RXD 引脚上;

  • RXD:用于接收数据,应连接到发送设备的TXD 引脚上;

  • GND:为双方提供一个相同的参考电平。

UART配置

为了使用 UART 进行数据传输,通常需要配置下述参数:

  • 波特率:每秒传输的bit数,一般有9600, 19200, 115200等选项

  • 数据位:可以有5, 6, 7或8位的数据,一般我们是按字节(8位)传输数据,发送方一位一位的改变数据线上的状态(高电平或低电平)将它们发送出去,传输数据时先传最低位,最后传送最高位

  • 校验位:用来校验数据传送的正确性,只能检错,不能纠错

  • 停止位:用来表示当前数据传输完毕,为逻辑电平”1”

UART时序

UART Timing

UART Timing

上图为 8位数据位+1位偶校验位+1位停止位 发送’A’(0x41) 的波形 ‘A’的二进制是01000001,小端传输,即低位(LSB)在前,高位(MSB)在后

  • 空闲时,数据线上为高电平

  • 起始位,当需要发送数据时,UART将改变TXD的状态,变为低电平,通常为1bit

  • 数据位,发送方一位一位的改变数据线上的状态(高电平或低电平)将它们发送出去,先传bit[0],其值为1;再发送bit[1],其值为0,以此类推

  • 校验位,偶校验:数据位 + 校验位 值为“1”的bit数为偶数,因此校验位为低电平

  • 停止位,因配置停止位为1bit,因此停止位为1bit高电平

UART 发包通路

发包通路如下:

  • 应用程序可调用 bk_uart_send() 进行发包

  • UART 硬件发包

UART 收包通路

UART Receive Data

UART Receive Data

UART 收包通路如上图所示:

  • UART 中断收包: 当 UART RX 或者 UART RX Finish 中断产生时,软件进入 UART 中断处理函数。 UART 中断从硬件 FIFO 中读取数据,并放入 RX FIFO。如果此时有应用程序在等 待数据,则唤醒应用程序进行收包。

  • UART 应用收包: 当应用调用 bk_uart_recv() 时,会从 UART RX FIFO 中读取数据,当 UART RX FIFO 中没有数据时,如果 timeout 设置为 0,则 bk_uart_recv() 立即返回,否则会等待,直到超时或者 UART RX FIFO 中收到新数据。

UART 收包流控

当 UART 中断从 UART HW FIFO 中取包速率小于 UART 硬件向 HW FIFO 中填包速率时,UART HW FIFO 会 Full。 如果 UART 硬件流控使能,则 UART 硬件会通知发送方停止发包,否则会出现丢包。

同理,当 UART 应用从 SW FIFO 中取包速率小于 UART 中断向 SW FIFO 中填包速率时,UART SW FIFO 会 Full。 当 SW FIFO Full 时,中断会读取硬件 FIFO 中的数据并丢弃,此时会打出 “rx kfifo is full” 的log,当这种情况出现时可能会影响 应用程序功能,通常解决方案是提高应用程序处理速率,如提升应用任务的优先级等。

UART 应用场景

目前 UART 支持三种不同的应用方式:

  • 使用默认 UART 中断处理流程: 使用默认的 bk_uart_send()/bk_uart_recv 来处理 UART 收发包,收发包通路如 UART 收包通路一节所述,通常这种方式能满足大部分应用的需求。

  • 使用默认 UART 中断处理流程,同时注册用户 callback: 同第一方式,唯一不同的点是,在产生 UART 中断之后,会调用用户注册的 callback。

使用例程

const bk_uart_config_t uart1_config[] =
{
  [0] =
  {
      .baud_rate     = 115200,
      .data_width    = BK_DATA_WIDTH_8BIT,
      .parity  = BK_PARITY_NO,
      .stop_bits = BK_STOP_BITS_1,
      .flow_control = FLOW_CTRL_DISABLED,
      .flags   = 0,
  }
}

char send_buf[4]={0x11,0x22,0x33,0x44};

bk_uart_initialize(UART1_PORT, &uart1_config[0], NULL);  //初始化串口

bk_uart_send(UART1_PORT, send_buf, 4);   //uart 

bk_uart_recv(UART1_PORT, send_buf, 4, 0);  //uart