您的位置 首页 ADAS

什么是串口(UART)?串口的组成和FPGA实现

1、什么是串口(UART)? 串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试时占有重要地位。 串口(UART)全称通用异步收发传输器(Univ…

1、什么是串口(UART)?
串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试时占有重要地位。
串口(UART)全称通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),主要用于数据间的串行传递,是一种全双工传输模式。
它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。
“异步”两个字即意味着在数据传递的两个模块之间使用的不是同步时钟。
实际上在异步串口的传输中是不需要时钟的,而是通过特定的时序来标志传输的开始(起始位–由高到低)和结束(结束位,拉高)。
2、串口的组成
2.1、串口的物理层
UART 通信只有两根信号线,一根是发送数据端口线叫 tx(Transmitter),一根是接收数据端口线叫 rx(Receiver)
如图所示,对于 PC 来说它的 tx 要和对于 FPGA来说的 rx 连接,同样 PC 的 rx 要和 FPGA 的 tx 连接,如果是两个 tx 或者两个 rx 连接那数据就不能正常被发送出去和接收到。
wKgZomWU2HyAfPXUAABix8_jcLQ492

信号的传输由外部驱动电路实现。电信号的传输过程有着不同的电平标准和接口规范,针对异步串行通信的接口标准有RS232、RS422、RS485等.
它们定义了接口不同的电气特性,如RS-232是单端输入输 出,而RS-422/485为差分输入输出等。
传输距离较短时(不超过15m),RS232是串行通信最常用的接口标准。RS-232标准的串口最常见的接口类型为DB9,样式如图所示,工业控制领域中用到的工控机一般都配备多个串口,很多老式台式机也都配有串口。
但是笔记本电脑以及较新一点 的台式机都没有串口,它们一般通过USB转串口线来实现与外部设备的串口通信。
DB9接口定义以及各引脚功能说明如图所示,我们一般只用到其中的2(RXD)、3 (TXD)、5(GND)引脚,其他引脚在普通串口模式下一般不使用:
wKgZomWU2HyAQ6AnAAH7GKKe52I461

2.2、UART协议
UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图所示。
其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。
校验位分为奇校验和偶校验,用于检验数据在传输过程中是否出错。
奇校验时,发送方应使数据位中1的个数与校验位中1的个数之和为奇数;接收方在接收数据时, 对1的个数进行检查.
若不为奇数,则说明数据在传输过程中出了差错。同样,偶校验则检查1的个数是否为偶数。关于奇偶校验可参考:Verilgo实现的FPGA奇偶校验
wKgZomWU2HyAKi78AACKyR4Zjnc078

UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。
数据位可选择为5、6、7、8位,其中8位数据位是最常用的,在实际应用中一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认), 1.5或2位。
串口通信的速率用波特率表示,它表示每秒传输二进制数据的位数,单位是bps(位 /秒),常用的波特率有9600、19200、38400、57600以及115200等。
如波特率9600则代表每秒传输9600bit数据,以串口发送1个字节10bit算(起始位1bit+数据8bit+停止位1bit+NO校验位),则传输1个字节需要的时间是1*10/9600秒。
3、串口发送模块
3.1、接口定义与整体设计
发送模块整体框图、输入输出信号如下所示:
wKgZomWU2H2AN-phAAA87s65xWI812

其中信号端口如下:
wKgZomWU2H2AMUtKAAHP4zdFBgc784

需要说明的是,uart_tx_data为需要发送的一个字节的数据,uart_tx_en为发送使能位,当其拉高,则代表此时通过串口发送数据线发送数据uart_tx_data。
3.2、设计思路
该模块支持任意波特率(理论上)的发送,但需要在使用该模块时使用参数将其例化,数据位8位,起始位和停止位各1位,无奇偶校验
当使能信号有效后拉高发送标志信号,标志模块进入发送过程;当发送完10个bit后,拉低发送标志信号,标志发送过程结束。使能信号有效时将要发送的数据寄存。
假设波特率为9600,则发送一个bit的时间为1s/9600,一个数据的传输共10bit(数据位8位,起始位和停止位各1位),则共需要1s/9600;
假设系统时钟为50MHz(参数化以便适应不同的系统频率),则其周期为20ns,那么发送一个bit所需要的系统周期数为(1s/9600)/ 20ns ≈ 5208(个)。
在发送过程中使用一个计数器计数,计数区间为(0~5208-1),这样的区间一共10个(一个字节需要发送10个bit);
此外还需一个计数器对发送的bit数计数(每当上一个计数器计数到5207则表示发送完了一个bit),计数区间(0~9)
在发送过程,根据计数器的值(发送bit计数器),对发送数据线进行操作。
若发送bit计数器 = 0,则代表此时需要发送起始位;
若发送bit计数器 = 1,则代表此时需要发送发送数据的最低位LSB(数据的发送总是低位在前,高位在后);
······
若发送bit计数器 = 8,则代表此时需要发送发送数据的最高位MSB;
若发送bit计数器 = 9,则代表此时需要发送停止位;
发送数据线在不处于发送状态时需拉高,以满足UART时序的空闲状态
3.3、Verilg代码
根据上述设计思路,部分发送模块代码如下:
3.4、Testbench
Testbench的设计如下:
设定波特率230400(这样的目的是为了更方便的观察发送使能信号uart_tx_en,节约时间)
3000ns后,拉高发送使能信号uart_tx_en一个周期,同时生成1个8bit的随机数据给uart_tx_data作为要发送的数据
观察UART上TX线的时序是否满足要求
3.5、仿真结果分析
仿真结果如下图(注释很详细):
下图中可以看到发送模块发送了1个数据8’h24,一段时间后发送结束,并无法直接观察发送线TX上的时序。
wKgZomWU2H2AdUrIAABlpTt8F9A910

整体仿真时序
下图中可以看到发送模块发送了1个数据8’h24,一段时间后发送结束,且可以看到发送线TX在以符合UART时序的方式发送数据00100100(低位在前、高位在后),即8’h24。
wKgZomWU2H2Ae8SrAAGfa27dsVw031

单次发送时序
可以看到仿真结果是符合预期设计要求的。
3.6、上板实测
至此已经顺利完成了发送模块的仿真验证,接下来使用一块Altera Cyclone IV E的开发板上板实测。
编写一个发送模块测试模块,该模块调用串口发送模块,并按一定间隔(默认1s)拉高发送使能信号和生成发送数据,发送数据从0x01开始累加1,直到0xFF(溢出到0x00)。
同时在电脑上使用串口调试软件接收发送过来的数据。根据串口调试软件接收到的数据判断串口发送模块是否能成功工作。
发送模块验证模块代码如下:
串口调试软件结果如下:
依次接收到了数据01、02、03······。说明我们的发送模块工作正常。
wKgZomWU2H2AJhlDAAAm1bFRK5I049

4、串口接收模块
4.1、接口定义与整体设计
接收模块整体框图、输入输出信号如下所示:
wKgZomWU2H6AMIhWAABCJOvVXkA216

其中信号描述如下:
wKgZomWU2H6AZUUVAAGeTu3dtnQ989

需要说明的是,uart_rx_data为接收的一个字节的数据,uart_rx_done为接收完成标志位,当其拉高,则代表此时接收到的串口数据uart_rx_data有效。
4.2、设计思路
该模块支持任意波特率(理论上)的接收,但需要在使用该模块时使用参数将其例化,数据位8位,起始位和停止位各1位,无奇偶校验
串口的传输是以起始位开始的,而起始位是将数据线拉低 ,所以我们需要捕捉数据线的下降沿,将接收数据线打拍3次,捕捉其下降沿。
当捕捉到接收数据线的下降沿,拉高接收标志信号,标志模块进入接收过程;当接收完10个bit后,拉低接收标志信号,标志接收过程结束
假设波特率为9600,则传输一个bit的时间为1s/9600,一个数据的传输共10bit(数据位8位,起始位和停止位各1位),则共需要1s/960;
假设系统时钟为50MHz(参数化以便适应不同的系统频率),则其周期为20ns,那么传输一个bit所需要的系统周期数为(1s/960)/ 20ns ≈ 5208(个)。
在接收过程中使用一个计数器计数,计数区间为(0~5208-1),这样的区间一共10个(一个字节需要传输10个bit);
此外还需一个计数器对接收的bit数计数(每当上一个计数器计数到5207则表示接收完了一个bit),计数区间(0~9)。
在接收过程,根据计数器的值(接收bit计数器),在每个bit计数器的中间接收数据,将其移位寄存(在电平中间数据最稳定)
若接收bit计数器 = 0,则代表是起始位,不需要接收
若接收bit计数器 = 1,则代表此时接收到数据的最低位LSB(数据的传输总是低位在前,高位在后),将其赋值给寄存数据的最低位;
······
若接收bit计数器 = 8,则代表此时接收到数据的最高位MSB,将其赋值给寄存数据的最高位;
若接收bit计数器 = 9,则代表是停止位,不需要接收
4.3、Verilg代码
根据上述设计思路,部分代码如下:
4.4、Testbench
仿真模块的Testbench设计如下:
设定波特率230400(这样的目的是为了更方便的观察发送使能信号uart_tx_en)
定义一个任务task,该任务将输入使用波特率230400一个bit一个bit的输出,模拟上位机发送数据给FPGA
3000ns后,发送第1个随机数据
发送完了第1个随机数据后发送第2个随机数据,一共发送4个随机数据
4.5、仿真结果分析
仿真结果如下图(注释很详细):
下图中分别发送了4个数据8’h24–8’h81–8’h09–8’h63;接收模块分别接收到了4个数据8’h24–8’h81–8’h09–8’h63。发送、接收数据一致。
wKgZomWU2H-AXdnQAAGZ12GBXaY448

接收总体时序
下图是第1次接收数据(8’h24,即00100100)是的时序图。
wKgZomWU2H-AIj3yAAGx-9CNekw861

单个字节接收时序
4.6、上板测试
至此已经顺利完成了接收模块的仿真验证,接下来使用一块Altera Cyclone IV E的开发板上板测试。
首先生成一个IP核–ISSP(In-System Sources and Probes),这个IP核可以提供一个输出用来在线输出,相当于一个简单的信号发生器–Source,此外还可以提供探针Probes来在线监控信号的输出。
在本次设计中,我们使用Probes来观察串口接收数据。ISSP调用如下:
wKgZomWU2H-ACogdAACc95LD5vk170

编写一个接收模块验证模块,该模块调用接收模块,ISSP IP核。同时在电脑上使用串口调试软件发送数据,根据接收到的数据判断串口接收模块是否能成功工作。
接收模块验证模块uart_rx_test代码如下:
下载程序后,在Quartus II中打开In-System Sources and Probes Editor,然后使用串口调试软件发送数据0x55–0xaa–0x88(随机选的3个),观察 In-System Sources and Probes Editor中寄存器的值,分别如下:
wKgZomWU2H-AABqmAAGt8tcfdYs684

wKgZomWU2H-AOZKgAAG1VK03cf0433

wKgZomWU2H-AEl4CAAGjezCdYJs113

5、总结
串口作为一种常用的通信协议与调试手段,请一定要熟练掌握!
基于FPGA的串口实现不难,只要注意根据波特率合理设计计数器即可,在此计数器的调动下可以实现数据的发送与接收。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/350597.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部