《FPGA经典例程及解读--基于xilinx K325T平台》系列导航
本专栏主要针对与想学习FPGA的同学,从基础的点灯到之后的复杂功能实战例程,从入门到进阶,通过这些例程的学习和了解,希望可以帮助你从一个FPGA小白进阶到FPGA中级阶段,能够处理工作中大多数的FPGA使用场景。
本篇是该系列的第六篇内容
上一篇:FPGA例程(5):时钟(clock)分频倍频(PLL/MMCM)实验--vivado行为级仿真、综合后仿真和实现后仿真说明_xilinx fpga 时钟倍频时钟方案-CSDN博客
**下一篇:**关注我,第一时间获取更新!!
1 引言
串口自诞生以来由于其简单可靠的传输方式,被大量使用,对于现在这个充满高速通信设备的时代来说,串口依然不过时。老早以前的台式机和笔记本都是有串口的,虽然现在很多台式机串口没有了,笔记本也没有串口了,但是串口从来没有被丢弃,只是以另外一种形式存在,这就是USB转串口芯片。串口只需要2跟线就可以实现一收一发,使用简单,可靠方便,在低速场合大量使用。
2 串口通信
本文所述的串口是指异步串行通信,异步串行是指UART(Universal Asynchronous Receiver/Transmitter),通用异步接收/发送。
UART是一个并行输入称为串行输出的芯片,通常集成在主板上。UART包含TTL电平的串口和RS232电平的串口。TTL电平是3.3V的,而RS232是负逻辑电平,它定义+5~+12V为低电平,而-V~-V为高电平。
串行接口按照电气标准及协议来分包括RS-232-C RS-422 RS485等。RS-232-C RS-422 RS485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。
对于米联客MK7160FA开发板,使用USB转串口的模式,来实现FPGA部分的串口通信实验(请不要和ZYNQ PS ARM端的串口混淆,ARM的串口是不需要你写FPGA程序就可以工作的,而FPGA部分实现串口是需要自己写串口收发器的),如下图所示,NK7160FA开发板USB转串口部分的原理图,FPGA通过两个IO与其相连。

2.1 串口通信协议解析
通常串口的一次发送或接收由四个部分组成:起始位S(一般为逻辑"0")、数据位D0~D7(一般为6位~8位之间可变,数据低位在前)、校验位(奇校验、偶校验或不需要校验位)、停止位(通常为1位,也有可能是2位)。停止位必须为逻辑1。
**发送:**消息帧从一个低位起始位开始,后面是7个或者8个数据位,一个可用的奇偶位和一个或几个高位停止位。如果选择了奇偶校验,UART就在数据位后面加上奇偶位。奇偶位可以用来帮助错误校验。
**接收:**接收器发现起始位时它就知道数据准备发送,在接收过程中,UART 从消息帧中去掉起始位和结束位,对进来的字节进行奇偶校验,并将数据字节从串行转换成并行。
++UART 传输时序如下图所示:++

从波形上可以看出起始位是低电平,停止位和空闲位都是高电平,也就是说没有数据传输时是 高电平,利用这个特点我们可以准确接收数据,当一个下降沿事件发生时,我们认为将开始数据传输。
2.2 串口通信波特率
在一次串口通信过程中,数据接收与发送双方没有共享时钟,因此,双方必须协商好数据传输波特率,发送和接收波特率必须保持一致才能保证正确通信,根据双方协议好的传输速率,接收端即可对发送端的数据进行采样。
波特率即数据传输速率,是指1秒最大传输的数据位数,包括起始位、数据位、校验位和停止位。
如果波特率设定为115200bps
那么一个数据位(一个bit)的时间长度为1/115200:单位(s)
假设UART时钟50MHz对应20ns,那么一个bit位持续周期为
1s/115200 /20ns = 434
即434个50MHz时钟对应一个数据位
常见的波特率标准为 300bps,600bps,800bps,9600bps,115200bps,19200bps 等。当然,更块的速度意味着对采样的要求更高,有可能误码率会逐渐提高。
2.3 串口通讯具体工作流程
串口在具体工作中,常见的工作流程如下:
首先:发送端按照预先设定好的波特率,发送起始位(Start)+数据位(data)+奇偶校验位+结束位。其中,起始位为逻辑0,结束位为逻辑1,发送端在空闲状态为1。发送数据包格式如下图所示。

数据的奇偶校验位是可以选择的,如果不使用奇偶校验,那么就没有这个数据位。
其次:接收端通过检测电平'1'到'0'的跳变来确定一个数据包的开始。确定开始位接收完成之后,依次接收数据,使用更高的采样时钟,完成数据采集。接受完数据位后,继续接收奇偶校验位和停止位。
串口的接收与发送,其主要时序设计包括两个部分:
1)波特率的产生时序;
2)数据传输时序,包括接收与发送。
波特率产生时序设计:
假设FPGA输入时钟100MHz,为得到常用的波特率,仍然采用计数分频来得到。
BAUD_DIV=100_000000/波特率。
**数据接收模块:**在设置好传输波特率的情况下,根据串口传输时序,进行解串。空闲状态时,接收数据为逻辑高电平,等待起始位逻辑低电平的到来。当起始位到达后,由低位到高位,依次采集8位数据,并进行相应的解串,存入临时寄存器。接收有效数据完成后,判断结束位,接收完毕。
**数据发送模块:**设置发送使能信号和待发送的数据。通过计数器,标识10个数据发送的周期。这10个数据依次为起始位+8位数据位+1位结束位,实现数据位的逐个发送。
**验证:**采用PC机的串口调试助手,发送数据位至FPGA,FPGA接收到数据位之后,立即回传至PC机。
3 下篇预告
有关UART串口的具体设计原理和实现源码,在下一篇进行详细介绍,敬请期待!!!!