串口RS232 UART通讯

272 阅读4分钟

在当今电子系统中,经常需要板内、板间或者下位机和上位机之间 进行数据的发送和接收,这就需要双方遵循一定的通信协议来保证数据传输的正确性。 常见的协议有UART(通用异步收发传输器),I2C(双向两线总线)、SPI(串行外围总线)

I2C:

I2C 为半双工,半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信。 虽然数据可以在两个方向上传送,但通信双方不能同时收发数据

半双工, 同步串行 双线

SPI:

全双工,发送数据的同时也能够接收数据,两者同步进行

全双工,同步串行,无应答机制确认数据是否接收。

UART: 是异步通信的总称。

全双工, 异步通信。

同步通信和异步通信:

同步通信:

同步通信以一串字符为传送单位,字符间不加标识符,一串字符的开始用同步字符表示。

通信连线一般为 SDA信号线 和SCL时钟线

异步通信:

以字符为传送单位,用起始位和停止位标识每个字符的开始和结束,只需字符传送同步。

同步是指: 发送方发送数据后,等接收方发回响应后才进行下一个数据包的通讯方式。

异步是指: 发送方发出数据后,不等待接受方发回响应,接着发送下个数据包的通讯方式。

同步通信 通信双方必须建立同步,即双方的时钟调整到一个频率。

UART: 通用异步收发传输器

其在数据发送时候将并行的数据 转换为串行的数据来传输,在数据接收时候,将接收到的串行数据转换成并行数据,可以实现全双工的传输和接收。

RS232 RS449等是对应各种异步通信 的接口标准和总线标准。RS232广泛用于计算机串行接口外设连接。

UART 关键参数 及时序图:

数据位数, 波特率一般通信两端设备都设为相同的波特率。

奇偶校验类型: 用来验证数据的正确性。

停止位

RS232中最常用的是 八个数据为,无奇偶校验,一个停止位。

START bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 STOP

image.png

bps_clk信号的第一个时钟沿到来时,字节发送模块开始发送起始位,接下来发送8个数据位,一个停止位。

RS232通信协议需要一定的硬件支持,早期都是RS232转TTL。现在系统集成度越来越高,多数系统已经转用USB转串口。

CH340 是一个USB总线的转接芯片,实现USB转串口。

UART串口通信发送模块设计与实现

串口发送模块设计: image.png 输入:

clk: 系统时钟

reset_n : 模块全局复位信号

send_en: 发送使能信号

baud_set: 波特率设置信号

data_byte: 待传输的8bit数据

输出:

uart_tx: 串口发送信号输出

tx_done:发送结束信号, 一个时钟周期高电平

uart_state: 发送状态,处于发送状态时为1

子模块 波特率时钟生成模块设计

波特率: 串口的波特率频率为每秒传输二进制位数

系统的时钟周期为20 ns

baud_set: 波特率分频计数值 50M系统时钟计数值

0 9600 1/9600 / 系统时钟周期20ns 5208-1

1

2

3

4

为提高模块复用性,当使用不同的波特率时,只需设置不同波特率时钟计数器的计数值。 使用查找表实现:

always@(posedge clk or posedge reset)
if(reset)
bps_DR <= 16'd5207;

else  begin
case(baud_set)
     0: bps_DR <= 16'd5207;
     1: bps_DR <= 16'd2603;
      2: bps_DR <= 16'd1301; 
      3: bps_DR <= 16'd867;
      4: bps_DR <= 16'd433;
      default: bps_DR <= 16'd5207;
endcase
end

利用计数器实现波特率时钟,div_cnt 计数。

子模块 数据输出模块:

通过对波特率时钟计数,来确定数据发送的循环状态,一个数据位传输结束后,tx_done 信号输出一个时钟的高电平。

关于数据传输状态,在正常传输时候,uart_state信号为高电平,其他情况均为低电平。

由于uart串口为异步的收发器,因此为了保证发送数据在时钟到来的时候是稳定的,需要对输入数据进行寄存。

数据发送模块

串口数据发送模块有一个10选一多路器,作用是根据bps_cnt值确定传输状态,

一位一位发送。

bps_cnt 共有11个状态:

0: uart_tx <= 1'b1;

1: uart_tx <= START;

2-9 uart_tx <= 8bit;

10: uart_tx <= STOP_bit;