实验十四 UART串行通信 14.2 UART串口发送实验

一、实验设计目标

(1)在FPGA中实现串口协议,通过Anlogic_FPGA开发板上的“UART2USB”口向计算机发送数据。

二、实验设计思路

在学习了实验4.1中UART串口接收实验的基础上,理解UART串口发送实验就较为简单了。本实验设计使用FPGA向计算机重复发送六个数据“0A、0B、0C、0D、0E、0F”,每隔0.5秒发送一个,在计算机上使用“串口助手”接收数据并验证是否正确。

图4.10为发送一帧数据时的简单示意图。可以看出,串口的发送时序和接收时序是一样的,而串口接收和发送的不同点就在于,接收是把数据从时序中提取出来,发送是把数据添加到时序中去。

img

4.10 串口发送时序示意图

​ 同串口接收一样,进行串口发送实验首先需要产生一个BPS_CLK信号,然后根据BPS_CLK实现TX的时序即可。以下为串口发送的简单步骤:

(1)由TX产生一个下降沿变化,作为一帧数据的开始,“开始位”时,TX信号置为0。

(2)把要发送的数据按照先低位后高位的顺序一位一位送给TX。

(3)“校验位”和“停止位”无操作,TX信号置为1。

(4)一帧数据发送完毕,等到下一次发送开始时,回到步骤(1)。

图4.11是本实验设计的串口发送系统的示意图,包含数据控制模块U1、波特率控制模块U2和发送控制模块U3。

img

4.11 串口发送系统示意图

数据控制模块内有一个计数器Count,控制系统每隔0.5秒发送一次数据。TX_Data为要发送的8位并行数据;TX_En_Sig为发送使能标志位,它的上升沿将驱动模块U2开始产生BPS_CLK信号,同时驱动U3模块开始发送数据;TX_Done_Sig为发送完成标志位,当一帧数据发送完毕后,TX_Done_Sig信号被置

为1,这将驱动TX_En_Sig信号变为0 直到开始发送下一组数据。

波特率控制模块与实验4.1节串口接收实验中模块功能相同,U2模块的输入信号Count_Sig即为U1模块的输出信号TX_En_Sig。

发送控制模块将TX_Data的值一位一位(LSB先导)的送给TX_Out信号,当一帧数据发送完毕时,TX_Done_Sig被置为1。

三、功能模块图与输入输出引脚说明

在FPGA中实现此系统,顶层模块为tx_top,底层模块data_control_module、tx_bps_module、tx_control_module从左至右依次对应于图4.11中的U1~U3。下面介绍一下顶层模块输入输出引脚的功能:

(1)CLK:50MHz的时钟信号输入。

(2)RSTn:复位输入信号,低电平有效。当RSTn信号为0时,TX_Out恒为1。

(3)TX_In:发送输出信号。连接到串口的TX线。

四、程序设计

​ 串口发送程序中的大部分代码功能都已在实验4.1节串口接收实验中使用过,容易理解,此处仅简单说明。图4.12是截取自底层模块data_control_module的部分代码:

img

4.12 data_control_module核心代码

​ 28-32:isTX是一个寄存器型信号,最终将赋给TX_En_Sig。当一帧数据发送完毕后,将isTX信号置为0,禁止系统发送数据。

33-35:分频数T05S的值为25000000,当距离上一次发送数据过去0.5秒后,将isTX信号置为1,开始新一轮数据的发送。

37-40:i的取值范围是0~5,用于从六组数据中选择一组发送。

五、FPGA管脚配置

以下是使用Anlogic的IO Constraint,CLK信号与开发板上的50MHz的晶振时钟相连;RSTn信号与SW0相连;TX_Pin_Out信号与R6管脚相连。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { RSTn } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { TX_Pin_Out } { LOCATION = D12; IOSTANDARD = LVCMOS33; }

六、实验结果

类似于串口接收实验,直接使用2根USB数据线分别将开发板上的JTAG接口和UART2USB接口与计算机相连,在计算机上安装一个“串口调试助手”,即可进行实验。

图4.13是使用“串口调试助手”接收数据“0A、0B、0C、0D、0E、0F”的结果。波特率选择9600,选择8位数据位,1位校验位和1位停止位。实验结果与程序设计相符。

img

4.1****3 串口发送实验结果

同样的,下面我们使用ChipWatcher来观察时序关系,加深对程序的理解:

img

4.1****4 串口发送实验ChipWatcher设置

设置ChipWatcher,采样时钟为500KHz,触发条件为TX的下降沿到来且i==4’b0000,也就是我们要看发8’h0A的时序,如果要观察8’h0C的发送时序,需要设置触发条件为TX的下降沿到来且i==4’b0010;

设置完成后点击Single Trigger我们可以看到发送“0A”的完整时序:

img

4.1****5 发送0A的完整时序

下面我们按照发送流程依次解读程序:

\1. (21-43)每0.5秒拉高一次isTX(也即TX_EN_Sig),发送完毕后再拉低TX_EN_Sig;(33-52)每发送一次,i自加1,i在0-5里循环,从而在0A - 0F里切换发送数据。

img

4.1****6 产生TX_EN_Sig和数据循环发送控制

\2. 当TX_EN_Sig为高时,Count_BPS计数,当Count_BPS=26时,BPS_CLK置1;注意跟UART收数不同的地方在于,收数时Count_BPS是在RX_EN_Sig为高且起始条件到来时(neg_sig==1)才开始计数。

img

4.1****7 产生BPS_CLK

\3. 当BPS_CLK为高时,State自加1,同时拉低TX,发出起始位:

img

4.1****8 产生TX开始标志(TX由高到低)

第一步到第三步的时序解释如下:

img

4.1****9 使能发送数据并发送起始位的时序

\4. State=1到8,从低位到高位发送TX_Data的数据:

img

图**4.**20 由低位到高位发送TX_Data

img

图**4.**21 由低位到高位发送TX_Data

\5. State=9到10,发送校验位和停止位

img

\6. State=11,发出TX_Done_Sig标志,State=12,拉低TX_Done_Sig,State归零

img

img

七、思考与拓展

(1)仔细阅读tx_control_module模块的程序,并参考图4.6绘出本实验中发送过程的简单示意图。

(2)目前是发送完一组数据等待计时到达0.5秒再发送下一组数据,更改程序,实现发送完一组数据后立刻发送下一组数据的功能,并使用ChipWatcher验证从0A发到0F的完整过程。

(3)建立一个工程,将接收到计算机发来的数据立即返还给计算机。

八、实验小结

实验14.1与实验14.2节分别描述了串口接收实验与串口发送实验,但仍存在部分限制。例如,当计算机使用UART连续向FPGA写入100个数据时,缺少一个存储区域把这100个数据有效存储起来。