您的位置:首页 > 其它

FPGA第四篇:异步串口的实现

2016-04-21 20:54 204 查看

参考文章:

(1)基于Verilog下的串口通信实验-踏雪无痕的博客

(2)【FPGA黑金开发板】Verilog HDL那些事儿——串口模块
(3)黑金动力社区

在此进行进行感激而涕零(嘻嘻)!谢谢你们提供了如此好的资源。

一、串口通信的原理

1、应用:

串口通信是目前比较重要的一种通信方式,主要是用于计算机和外部的通信。串口用于ASCII码字符的传输。

2、物理层面:

通信使用3根线完成:

(1)地线(GND);

(2)发送(TXD);

(3)接收(RXD),

由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其它线用于握手,但是不是必须的。

3、四个重要参数

串口通信最重要的参数是波特率、数据位、停止位和奇偶校验位。对于两个进行通信的端口,这些参数必须匹配: 

a,波特率:

这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率。例如如果协议需

要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波

特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信。

————————————————————————————————

——————————————分割线——————————————---

补充:码元、比特位、波特率、比特率

码元 —— 在数字通信中常常用时间间隔相同的符号来表示数字。这样的时间间隔内的信号称为码元,这个间隔称为码元长度

比特位 —— 单一位二进制数0或1

波特率——是码元传输速率单位,他说明单位时间传输了多少个码元

比特率——是信息量传送速率单位,即每秒传输二进制代码位数,bit/s

如何区分波特率和比特率?

如果在数字传输过程中,用0V表示数字0,5V表示数字1,那么每个码元有两种状态0和1. 每个码元代表一个二进制数字。此时的每秒码元数和每秒二进制代码数是一样的,这叫两相调制,波特率等于比特率。

如果在数字传输过程中,0V、2V、4V和6V分别表示00、01、10和11,那么每个码元有四种状态00、01、10和11. 每个码元代表两个二进制数字。此时的每秒码元数是每秒二进制代码数是一半的,这叫四相调制,波特率等于比特率一半。

——————————————分割线——————————————---

————————————————————————————————

 b,数据位:

这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不一定是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码

是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数

据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。

 c,停止位:

用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因

此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。 

d,奇偶校验位:

在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一

个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位位1,这样就有3个

逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收

数据是否不同步。

4、串口通信的数据传输时序图:



在串口的总线上“高电平”是默认的状态,当一帧数据的开始传输必须先拉低电平,表示有数据输入串口开始接收数据,这就是起始位设为低电平的原因。

5、对波特率的理解:

常用的波特率有9600 bps 和 115200 bps ( bit per second )。“9600 bps” 表示每秒可以传输9600位。

一个位的周期 = 1 / bps= 1/ 9600= 0.000104166666666667

从上述的公式,我们明白一个事实 9600 bps ,一位数据占用 0.000104166666666667s 时间。如果是一帧11位的数据,就需要

0.000104166666666667 x 11 = 0.00114583333333334

那么一秒钟内可以传输

1 / 0.00114583333333334 = 872.727272727268个帧数据。

当然这只是在数字上计算出来而已,但是实际上还有许多看不见的延迟因数。

二、串口模块的Verilog实现(1)——串口接收模块



Rx_module

1、子模块介绍

(1)detect_module.v ——电平检测模块

它主要检测一帧数据的第0位,也就是起始位,然后产生一个高脉冲经 H2L_Sig 给接收控制模块,以表示一帧数据接收工作已经开始。

(2)rx_bps_module.v ——波特率定时模块

是产生波特率定时的功能模块。换一句话说,它是配置波特率的模块。当接收控制模块拉高 Count_Sig, 波特率控制模块通过 BPS_CLK 对接收控制模块产生定时。

(3) rx_control_module.v ——接收控制模块

是核心控制模块,对串口的配置主要是1帧11位的数据,重视八位数据位,忽略起始位,校验位和结束位。当RX_En_Sig 拉高,这个模块就开始工作,他将采集来自
RX_Pin_In 的数据,当完成一帧数据接收的时候,就会产生一个高脉冲给 RX_Done_Sig。

2、串口接收模块到底是如何实现数据采集的呢?



数据采集时序图

如上图所示,数据采集都是在“每位数据的中间”进行着。在上图中 RX_Pin_In 输入一帧数据,当 detect_module.v 检测到低电平(起始位),rx_control_module.v 和
rx_bps_module.v 就产生定时(与RX_Pin_In的波特率一致),而rx_bps_module.v 产生的定时是在每个位时间的中间。
在第0位数据,采取忽略的态度,然后接下来的8位数据位都被采集,最后校验位和停止位,同样采取了忽略的操作。有一点需要注意,串口传输数据“从最低位开始,到最高位
结束。

3、串口接收模块源码(代码在博客开头的连接中)

(1)detect_module.v ——电平检测模块

(2)rx_bps_module.v ——波特率定时模块

(3) rx_control_module.v ——接收控制模块

(4)rx_module.v——顶层模块

4、串口发送模块源码(代码在博客开头的连接中)
(1)tx_bps_module.v ——波特率定时模块
(2)tx_control_module.v ——发送控制模块
(3)tx_module.v——顶层模块
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息