FPGA项目四:串口通信(上)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
简介: FPGA项目四:串口通信

第四章 串口通信


第1节 项目背景


信息数据被逐位按顺序传送的通讯方式称为串行通信。串行接口(Serial Interface),简称串口,即是采用串行通信方式的扩展接口。其采用一位一位的方式顺序的传送数据,又可称串行通信接口或串行通讯接口(通常指 COM 接口)。串行接口的特点是通信线路简单,只要一对传输线就可以实现双向通信,并且可以直接利用电话线作为传输线,从而大大降低了成本,因此非常适用于远距离通信,但传送的速度较慢。


1980 年前后串口首次出现,其数据传输率是 115kbps~230kbps。初期,串口是为了实现计算机外设的连接,一般用来连接鼠标和外置 Modem 以及老式摄像头和写字板等设备,也可以应用于两台计算机(或设备)之间的互联及数据传输。目前,串口多用于工控和测量设备以及部分通信设备中。


根据通信方式的不同,串口可分成同步串行接口(Synchronous Serial Interface,SSI)和异步串行接口(Universal Asynchronous Receiver/Transmitter,UART)。SSI 常用于工业通信,UART通用于异步接收/发送。按照电气标准及协议的不同,串口包括 RS-232-C、RS-422、RS485 等。其中,RS-232-C、RS-422 与 RS-485 标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。


下面将具体介绍一下这些常用的串口。

RS-232:RS-232 是 1970 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准,其全称为“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”,又被称为标准串口。RS-232 是最常用的一种串行通讯接口,采用标准 25 芯 D 型插头座(DB25),后简化为 9 芯 D 型插座(DB9),现 25 芯插头座在应用中已很少采用。RS-232 采取不平衡的传输方式,即所谓的单端通讯。由于其发送电平与接收电平仅差 2V 至 3V 左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约 15 米,最高速率为 20kb/s。RS-232 是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为 3~7kΩ,因此其适合本地设备之间的通信。


RS-422:RS-422 标准的全称是“平衡电压数字接口电路的电气特性”,其对接口电路的特性进行了定义,采用 DB9 连接器。典型的RS-422 是四线接口,实际上还存在一根信号地线,共为 5根线。由于接收器采用高输入阻抗和发送驱动器,RS-422 比 RS232 的驱动能力更强,因此其可在相同传输线上连接多个接收节点(最多可接 10 个)。RS-422 支持点对多的双向通信,主设备(Master)一台,其余为从设备(Slave),且从设备之间不能通信。接收器的输入阻抗为 4k,故最大负载能力是 10×4k+100Ω(终接电阻)。由于采用单独的发送和接收通道,RS-422 四线接口不必控制数据方向,各装置之间的信号交换均可以通过软件方式(XON/XOFF 握手)或硬件方式(一对单独的双绞线)实现。RS-422 的最大传输距离为 1219 米,最大传输速率为 10Mb/s。其平衡双绞线的长度与传输速率成反比,只有在很短的距离下才能获得最高速率传输,一般 100 米长的双绞线上所能获得的最大传输速率仅为 1Mb/s,在 100kb/s 速率以下才可能使用规定最长的电缆长度。


RS-485:RS-485 从 RS-422 基础上发展而来,因此其许多电气规定与 RS-422 相仿,如都采用平衡传输方式、都需要在传输线上接终接电阻等。与 RS-422 相同,其最大传输距离约为 1219 米,最大传输速率为 10Mb/s,平衡双绞线的长度与传输速率成反比,只有在很短的距离下才能获得最高速率传输。RS-485 可以采用二线与四线两种连接方式:二线制可实现真正的多点双向通信,而四线制与 RS-422 一样只能实现点对多的通信,即只能有一台主(Master)设备,其余为从设备。但无论四线还是二线连接方式总线上可多接到 32 个设备,与 RS-422 相比有一定的提升。此外,RS-485与 RS-422 的共模输出电压不同,RS-485 的输出范围是-7V 至+12V,而 RS-422 是-7V至+7V。RS- 485 接收器最小输入阻抗为 12kΩ,而 RS-422 是 4kΩ。可以看出 RS-485 满足 RS-422 的所有规范,因此其可以在 RS-422 网络中应用。


CH340:由于串口(COM)不支持热插拔及传输速率较低,目前大部分新主板和便携电脑已开始取消 CH340 接口,只有工控和测量设备以及部分通信设备中还保留有串口。因此,为了使用该串口,需要使用 USB 转串口的芯片来使电脑把 USB 当串口来使用。这种类型的芯片很多,本书使用的是 CH340 芯片。CH320 是一个 USB 总线的转接芯片,用来实现 USB 转串口、USB 转 IrDA 红外或者 USB 转打印口等功能。在串口方式下,CH340 可以为计算机扩展异步串口提供常用的 MODE 联络信号,或将普通的串口设备直接升级到 USB 总线。本书的串口功能原理如下图所示,通过 USB 线将电脑与教学板上的 USB 接口相连,USB 接口的另一端与 CH340 芯片连接,CH340 芯片与 FPGA 相连。从 FPGA 的角度来看,串口其实就是两根线:输入线 USB_RXD 和输出线 USB_TXD,通过 USB_RXD 接收来自电脑过来的串口数据,通过 USB_TXD 将数据传送给电脑。其他电气特性、电平转换的工作,都可以通过 CH340 完成。

1670859916146.jpg

进行传输数据时,USB_RXD 和 USB_TXD 将数据字符按位传输,其串口时序如下图所示。USB_RXD 的时序由 CH340 芯片产生,FPGA 依此来接收数据。反过来,FPGA 芯片按规范产生 USB_ TXD 的时序,使得 CH340 可以正确地接收。其中,产生时序的为MASTER(主),接收数据为 SLAVE(从)。

1670859925572.jpg

串口时序主要包括:空闲、起始位、数据拉、校验位和停止位。下面逐一解释每个时序位的状态。


空闲:空闲状态下,数据线一直处于高电平状态。


起始位:当 MASTER 准备发送数据时,会先将数据线拉低“一段时间”,以此来告知 SLAVE做好数据传输的准备。


数据位:起始位之后是数据位,其位数由主从双方共同约定,支持 4、5、6、7、8 位等,完成约定后才能正确地传输。传输顺序是从低位开始,每个数据位传输时都会占用“一段时间”。从图 3. 4-2 中可以看出,传输从 LSB 开始,至 MSB 结束,LSB 即表示低位,MSB 表示高位。以数据 8’b00000001 为例,传输该数据时最先传送的即是最低位的“1”。


检验位:顾名思义,校验位是用于数据校验。目前简单常用的数据校验方式是奇偶校验,分为奇校验和偶校验。奇校验需要保证传输数据总共有奇数个逻辑高电平,偶校验则需保证传输数据有偶数个逻辑高电平。即“奇偶”指的是数据中(包括该校验位)1 的个数。例如:传输的数据是 0100_0011。如果校验方式是奇校验则校验位是 0,若是偶校验则校验位是 1。传输中校验位不是必须项,双方可以约定不需要校验位,或者使用奇/偶校验方式。


停止位:字符帧的最后一位是停止位。由于每台设备都有其自身时钟,在通信中两台设备间可能出现了小小的不同步,从而影响了数据传输结果。因此,MASTER 必须保证有停止位,即数据线需拉高“一段时间”。停止位不仅仅是表示传输的结束,也是一个校正时钟同步的机会,让 SLAVE 可以正确地识别下一轮数据的起始位。假如没有停止位,若校验码刚好是 0,数据连续发送时 SLAVE无法判断下一轮的起始位。对于 SLAVE 来说,数据位或校验位接收后就已经完成接收工作,在停止位无需任何操作,只需等待下一轮起始即可。


上文中提到每个数据都会传输“一段时间”,这段时间并不是随便定义的,需要传输双方做好约定,否则就不能正确地进行通信。那么“一段时间”究竟是指多长时间呢?这与波特率有关。波特率在串口通信中是一个非常重要的概念,其为模拟信号线路的速率。在串口通信中常用的波特率是 9600、19200、38400、57600、115200,代表每个码元传输的速率。在二进制数据传输中,波特率和比特率相同都为每个比特数据传输的速率,其倒数为 1bit 数据的位宽,也就是 1bit 数据持续的时间。确定了这一时间,就可用 FPGA 构造计数器实现比特周期的延时,从而实现特定波特率的数据传输。


举个例子,假设波特率为 9600,数据位为 8 位,无校验位。电脑要传送数据 8’b00110001 给 FPGA。由于波特率为 9600,每位占用时间为 1s/9600=104166ns。那么 FPGA 的 USB_RXD(图中的 uart_rxd)将如下图所示进行变化。

1670859934316.jpg

在使用开发板的串口前,需要安装 CH340 的驱动程序(下载链接:点击),下载后直接解压安装就可以进行使用。


使用 USB 线将电脑和开发板进行连接后将开发板上电,打开电脑的“设备管理器”。当出现如下图所示的界面时表示驱动程序安装成功并且已经被电脑正确地识别。

1670860006496.jpg

在“设备管理器”中可以查看串口号,点击“USB Serial Port(COM3)”,如下图所示。

1670860034764.jpg

随后点击“端口设置”选择“高级”选项,如下图所示。

1670860045650.jpg

下图中可见端口号的具体设置信息,其串口号为 COM3。

1670860053560.jpg

点击 CON 端口号,可以对串口号进行修改,如下图所示。

1670860061341.jpg

电脑发送数据给 FPGA 这一操作中需要使用串口调试助手(下载链接:点击),其界面如下图所示,下面对其具体参数设置进行说明。

1670860077846.jpg

串口:选择串口号,支持串口号 1~4。如果连接的串口号不在此范围,则需要在设备管理器中修改串口号,详细参见前文描述。

波特率:选择串口的波特率,支持 9600、19200、38400、57600、115200。该选项决定了每一位码元占用的时间。

校验位:可选择“没有检验位”、“奇校验”和“偶校验”。

数据位:设置数据位的位数,可选择 4~8 位的数据拉。

停止位:设置停止位的时间长度。可选择 1 位、1.5 位和 2 位。

打开/关闭串口:打开软件时,该串口默认是关闭状态。这里要注意有关串口使用的方法:一定要先设置好参数后,才能打开串口;反之,一定要先关闭串口后,才能关掉教学板电源和拔掉 USB线。

十六进制显示:本软件支持 ASCII 显示和十六进制显示。若勾选了十六进制显示,软件就会显示十六进制。例如 FPGA 发送数据 8’b00110001,软件收到后会显示为十六进制,即 31。反之如果不勾选十六进制显示,则会显示 ASCII 码。如果 FPGA 依然发送 8’b00110001,对照下图的 ASCII表可看出其所对应的图形为“1”,因此软件会显示“1”;假设 FPGA 发送的是 8’h00100011,下表中其所对应的是图形是“#”,因此软件会显示“#”。

1670860089024.jpg

十六进制发送:同样的,本软件支持 ASCII 发送和十六进制发送。若勾选十六进制发送,软件则会以十六进制形式发送。例如填写“31”后手动发送,那么 FPGA 收到的值为 8’b00110001。如果不勾选十六进制发送,则软件以 ASCII 码形式发送。若同样填写“31”后手动发送,软件将首先发送 ASCII 码“3”所对应的十六进制值 8’h33,再发送 ASCII 码“1”所对应的十六进制值 8’h31,即 FPGA 将收到两个字节数据:8’h33 和 8’h31。


第2节 设计目标


了解了串口通信的原理后,本书将完成串口通信的设计。按照至简设计法的思路,进行设计之前首先应明确设计目标,后续设计中每一个步骤都是围绕着设计目标的实现来针对性的展开。如果没有明确设计目标就开始操作实践,最终的作品也只是东拼西凑的产物。在这种状态下的工程调试过程如果出现了问题,则需要花费大量的精力进行寻找修复。因此建议初学者在最开始学习时养成良好的工作习惯,在后续工作中会受益无穷。

本设计中串口调试助手的参数设置为:波特率 9600;数据位为 8 位;无奇偶校验位;停止位为2 比特;接收和发送都是 16 进制数。

本设计中,用户通过串口调试助手发送一个 8 位的数据 data,其可以控制开发板上的 8 个 LED灯,data[0]~data[7]分别控制 LED0~LED7 灯。当数据位为 0 时,对应的 LED 灯点亮,数据为 1 时,对应的 LED 灯熄灭。例如,用户发送数据 data=8’b10000000 后,开发板上的 LED0、LED1、LED2、LED3、LED4、LED5、LED6 保持为亮,LED7 保持为灭。这里要注意,信号的传输顺序是从低到高的,数据的最后一位“0”对应 LED0,倒数第二位“0”对应 LED1,倒数第三位“0”对应 LED2,依次类推,第一位“1”对应 LED7。

设计完成后的上板效果如下图所示。

1670860109434.jpg


第3节 设计实现


确定设计目标后,下面会逐步分析讲解工程的实现步骤。本书不仅分享案例,还会在操作过程中剖析设计理念及原理,同时也分享一些至简设计法的设计技巧以锻炼独立设计工程的能力。因此,建议初学者认真学习每一步。当然,在已经拥有扎实的功底、只是想要根据步骤完成设计的情况下可以跳过此部分,直接进入后续章节中的简略版操作步骤。


3.1 顶层信号


新建目录:D:\mdy_book\mdyBookUart,并在此目录中新建一个名为 mdyBookUart.v 的文件。并用 GVIM 打开该文件后开始编写代码。在这里再次强调,初学者一定要按照本书提供的文件路径以及文件名进行设置,避免后面出现未知错误。根据设计目标可知,用户通过串口调试助手向 FPGA 发送数据,即 CH340 控制 RX 信号让其根据串口时序变化,从而将数据信号传送至 FPGA。因此 FPGA 工程必须有一个接口信号,本书将其命名为 uart_rxd。

本设计中需要控制 8 个 LED 灯的亮灭,按照之前章节中信号与灯的对应方法,需要 8 个信号来

进行控制:led0,led1,led2,led3,led4,led5,led6,led7。

然而本设计是采用串口指令控制小灯,且 8 个信号数目过于繁多。因此,可以选择使用一个 8 比特的信号,将其命名为 led。既然如此,那之间几个章节中的工程可以用这种方法吗?答案是肯定的,可以将 led0,led1,led2,led3 四个信号转换为一个 4 比特的信号 led。虽然设计内容与需求不同,但是至简设计法一定会分享最合适最简单的方法。


硬件电路的连接关系如下表所示。本设计中采用 8 比特的信号 led 来控制 8 个 LED灯,工程的时钟管脚为 G1,对应 FPGA 工程信号为 clk;复位管脚为 AB12,对应 FPGA 工程信号为 rst_n;串口输入管脚为 D6,对应 FPGA 工程信号为 uart_rxd。因此本工程共需要 4 个信号:8 位信号 led,时钟 clk,复位 rst_n 和串口输入信号 uart_rxd。

1670860150743.jpg

将 module 的名称定义为 mdyBookUart,在顶层信号代码中将与外部相连接的输入/输出信号列出,从而实现信号与管脚的连接。已知该模块有四个信号:clk、rst_n、uart_rxd 和 led,其具体代码如下:

1670860163698.jpg

随后对信号的输入输出属性进行声明,指出对于 FPGA 来说这一信号属于输入还是输出,若为输入,声明则为 input;若为输出,声明则为 output。在本设计中由于 clk 是外部的晶振输送给 FPGA 的,因此在 FPGA 中 clk 为输入信号 input;同样地,rst_n 是外部按键FPGA 的,在 FPGA 中也是输入信号 input;同时可知 led 是 FPGA 输出给 LED 灯的,是输出信号 output。clk、rst_n、uart_rxd 三个信号的值都为 0 或 1,用一根线表示即可,而 led 信号位宽为 8。根据信号属性将输入输出端口定义补充完整,其代码如下:

1670860171337.jpg


3.2 信号设计


由前文可知,led 信号控制了 8 个 LED 灯的亮灭,然而其亮灭控制还是取决于串口发送数据。那么就存在这样一个问题:串口发送的数据是如何告知 FPGA 并与 led 对应起来呢?下面本书就来分析一下串口数据的时序,CH340 控制信号 uart_rxd 的时序如下图所示。

1670860199320.jpg

从时序图中可以看出:发送 8 位数据 data 前,信号 uart_rxd 会先变为 0 并持续一段时间(起启位),然后发送 data[0]、data[1],以此类推直至发送完 data[7],发送每位数据时都会持续一段时间,发送完毕后 uart_rxd 会变为 1 并持续一段时间(结束位)。至此,CH340 完成了数据的发送。可以看出每段有效信号的开始前和结束后,都会有特殊信号:有效数据开始前会有一段变 0 的信号,用以

告知 FPGA 开始传送数据;结束后会有一段变 1 的信号,告知 FPGA 此数据传送结束。

例如,CH340 要发送的数据为 data=8’h00110001,则 uart_rxd 的波形如下。

1670860209797.jpg

由于波特率设置为 9600,考虑时间信息,每位持续的时间是 1s/9600=104166ns。补充时间信息后的时序如下图所示。

1670860216942.jpg

本开发板的晶振时钟是 50Mz,对应时间周期为 20ns。由此可知每位数据持续时间为 104166ns/20ns =5208.3 个时钟周期,近似为 5208 个时钟周期。由于 5208 只是估计的大概数字,实际情况会产生一定的偏差。在实现过程中,应对数据位数进行计数,以此来判断开始位、数据位和停止位等。

1670860224505.jpg

通过上文分析可知:本设计一共需要 2 个计数器,1 个计数器用于计算 1 比特的位宽长度即 5208 个时钟周期,将其命名为 cnt0;另一个用于计算有多少个比特,将其命名为 cnt1。首先讨论 cnt0 的实现,至简设计法中计数器的设计只考虑两个因素:加 1 条件和计数数量。由于 1 比特的位宽长度是 5208 个时钟周期,因此 cnt0 的计数数量是 5208。

确定了计数数量后来分析一下 cnt0 的加 1 条件。为了更好理解加 1 条件的概念,这里以停车位来进行比喻。一般情况下对每个停车位置会进行对应编号,但是如果某个位置上放置了一块石头无法作为停车位时,该位置就不能获得对应的编号。反之则可以认为停车位编号的加 1 条件就是:对应位置上没有石头,其可以继续的进行编号,即 assign add_cnt0 = “没有石头”。因此如果在设计中计数器一直没有阻碍地进行计数工作,就可以认为加 1 条件是一直有效的。根据设计目标,可以确定 cnt0 的加 1 区域为其一直工作的区域,如下图灰色区域所示。

1670860245595.jpg

虽然确定了 cnt0 的加 1 区域,但现有设计中没有任何一个信号可以单独表示出这一区域。在这种情况下,进行对信号进行补充。因此本设计添加一个“flag_add”信号,该信号为 1 时表示上述灰色区域,即 cnt0 的加 1 区域。这样就可以明确计数器 cnt0 的加 1 条件为“flag_add==1“,

1670860256315.jpg

确定好 cnt0 的加 1 条件和计数数量后,就开始进行代码编写,以往都是一行行的输入相应代码。但是至简设计法有一个小技巧,可以节省代码编写时间的同时在一定程度上降低了代码的出错率。至简设计法将日常代码中常用到的固定部分制作成模板,进行代码编程时可以调用相应模板后根据逻辑输入对应设计的变量将代码补充完整。这里就可以用模板编写计数器代码,感受一下这个炫酷的功能。

打开 GVIM 工具,在命令模式下输入“:Mdyjsq”后点击回车,调出对应模板如下图所示。

1670860264689.jpg

通过上文分析可知,cnt0 的加 1 条件是“flag_add==1”,计数数量为 5208。将其填入到模板

中,可以得到完整正确的计数器 cnt0 代码如下:

1670860284761.jpg

相关文章
|
5月前
|
测试技术 异构计算
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
78 0
|
异构计算
FPGA项目五:数码管动态扫描(下)
FPGA项目五:数码管动态扫描
150 0
FPGA项目五:数码管动态扫描(下)
|
程序员 异构计算
FPGA项目五:数码管动态扫描(中)
FPGA项目五:数码管动态扫描
205 0
FPGA项目五:数码管动态扫描(中)
|
异构计算
FPGA项目五:数码管动态扫描(上)
FPGA项目五:数码管动态扫描
215 0
FPGA项目五:数码管动态扫描(上)
|
异构计算
FPGA项目四:串口通信(下)
FPGA项目四:串口通信
93 2
FPGA项目四:串口通信(下)
|
程序员 异构计算
FPGA项目四:串口通信(中)
FPGA项目四:串口通信
246 0
FPGA项目四:串口通信(中)
|
异构计算
FPGA项目三:PWM呼吸灯(下)
FPGA项目三:PWM呼吸灯
161 1
FPGA项目三:PWM呼吸灯(下)
|
9天前
|
机器学习/深度学习 算法 异构计算
m基于FPGA的多通道FIR滤波器verilog实现,包含testbench测试文件
本文介绍了使用VIVADO 2019.2仿真的多通道FIR滤波器设计。展示了系统RTL结构图,并简述了FIR滤波器的基本理论,包括单通道和多通道的概念、常见结构及设计方法,如窗函数法、频率采样法、优化算法和机器学习方法。此外,还提供了Verilog核心程序代码,用于实现4通道滤波器模块,包含时钟、复位信号及输入输出接口的定义。
28 7

热门文章

最新文章