跳转至

实验4 UART 实验

实验4:UART串口实验

计算机内部数据通常以字或字节为单位并行进行访问,但与外部设备进行数据交互或与其他计算机进行通信时,也经常需要串行数据通信。串行接口是一类使用相对简单的接口,THINPAD-Cloud教学计算机上也配置了基本的串口,作为连接终端设备的接口。本实验主要完成串行接口的访问。

串口实验目的

  1. 熟悉THINPAD-Cloud教学计算机串行接口的配置及与总线的连接方式;

  2. 掌握教学机串口UART的访问时序和方法;

  3. 理解总线数据传输的基本原理。

实验环境

  1. 硬件环境:PC计算机,Windows10或者Linux操作系统;THINPAD-Cloud教学计算机或者云实验平台;

  2. 软件环境:FPGA开发工具软件Vivado;串口调试精灵或THINPAD-Cloud远程实验平台。

实验内容

使用教学计算机上的FPGA芯片,编写代码完成对教学机UART的访问,实现和PC机上运行的串口程序(例如putty)的通信。要求分别实现如下功能:

  1. 将拨码开关设置为起始地址 Addr,地址单位为 32 位 word。

  2. 单击复位按钮。

  3. 测试程序向 FPGA 的串口发送 10 个字节的随机数,FPGA 将随机数存储到 BaseRAM 地址从 Addr 的连续 10 个 word 上(存储进最低 8 位,高 24 位不使用)。

  4. 程序从 FPGA 的串口接收 10 个字节(若超过 200ms 未收到记为超时)。

  5. 程序读取 BaseRAM 中对应位置的数据,并将 SRAM 中数据、串口接收到的数据与初始随机数进行对比,对比时只考虑 SRAM 数据的最低 8 位。

实验原理

THINPAD-Cloud教学计算机的FPGA芯片通过基本总线连接了存储器芯片Base_RAM以及控制模块中的UART串口模块。UART模块连接到教学机的Micro USB接口,可作为串口与其他设备连接。本实验中,该Micro USB接口将连接PC机的USB口后虚拟了一个串口RS-232接口,从而完成与PC机上运行的串口通信软件进行通信。

由于UART和Base_RAM共享基本总线,因此,需要有控制信号来区分在一个总线周期内是Base_RAM工作还是UART工作,是进行读操作还是写操作。在THINPAD-Cloud教学计算机中,给出了3位控制信号Base_RAM_EN、Base_RAM_OE、Base_RAM_WE来实现这个功能。

和普通的串口芯片8251不同,教学机上的UART不具备可编程的性质(它本身就是由控制模块编程实现的)。下面简单介绍一下串口收发的原理。

异步接收/发送器(UART),可完成并行数据和串行数据之间的相互转换,还能检测串行通信在传送过程中可能发生的错误。UART主要由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。本实验主要涉及UART中最重要的发送部分和接收部分, 其功能包括发送缓冲器(tbr)、发送移位寄存器(tsr)、帧产生、奇偶校验、并转串、数据接收缓冲器(rbr)、接收移位寄存器(rsr)、帧产生、奇偶校验、串转并等。

数据的发送由UART中的微处理器控制,微处理器给出wrn信号,发送器根据此信号将并行数据din[7..0]锁存进发送缓冲器tbr[7..0],并通过发送移位寄存器tsr[7..0]发送串行数据至串行数据输出端sdo。在数据发送过程中用输出信号tbre、tsre作为标志信号,当一帧数据由发送缓冲器tbr[7..0]送到发送移位寄存器tsr[7..0]时,tbre信号为1,而数据由发送移位寄存器tsr[7..0]串行发送完毕时,tsre信号为1,通知CPU在下个时钟装入新数据。发送器结构下图所示。

UART发送器结构

串行数据帧和接收时钟是异步的,发送来的数据由逻辑1变为逻辑0可以视为一个数据帧的开始。接收器先要捕捉起始位,确定rxd输入由1到0,逻辑0要8个CLK16时钟周期,才是正常的起始位,然后在每隔16个CLK16时钟周期采样接收数据,移位输入接收移位寄存器rsr,最后输出数据dout。还要输出一个数据接收标志信号标志数据接收完。接收器结构如下图所示。

UART接收器结构

另外需要注意的是,UART和Base_RAM都是通过基本总线和FPGA相连,本实验仅仅是完成UART的访问,请一定通过控制信号让Base_RAM不工作(不往总线上发送数据)。

实验中要使用的主要芯片的连接关系下图所示。

实验主要芯片连接关系。

主要实验步骤

本实验的操作比较复杂,首先要将教学机和PC机通过Micro-USB线连接好,并正确配置串口的参数(端口、波特率等),然后,在编写Verilog代码时,要正确理解UART的工作原理,设计好UART发送和接收数据的状态转换关系,以及各状态与对应的信号之间的关系。如果使用Thinpad-Cloud云平台的话,上述的设置已经在平台中预置完成,只需要打开串口使用即可。在此基础上,设计好实现的代码,再将代码下载到FPGA中,进行调试。因为是读写串口,所以始终要保持Base_RAM_EN为1(即内存处于禁用状态)。

  1. 写串口:用Verilog语言编写往串口发送数据的代码,将拨码开关上的数据发送到串口,并在PC端显示。

提示:在reset的时候进行初始化,把wrn置为1,以及把Base_RAM_EN、Base_RAM_OE、Base_RAM_WE置为1,为发送数据做好准备;具体写串口可设计4个状态:

  • 第1个状态给Base_RAM数据总线赋要发送的值,置wrn为0,wrn的下降沿UART将待发送数据送入到发送器tbr[7..0]并锁存;

  • 第2个状态为置wrn为1,使UART能够把读入的数据串行输出到串口;

  • 第3个状态等待被发送数据进入移位寄存器tsr[7..0],即等待tbre信号变为1;

  • 最后1个状态等待数据发送完毕tsre信号变为1。

状态转移如下图所示:

串口控制器写操作状态图

  1. 读串口:用Verilog语言编写读串口数据的代码,将从PC端发送过来的数据读出,并显示到LED灯上。

提示:可设计3个状态。

  • 第1个状态位为初始化,置rdn为1,并让接收串口数据的变量赋为高阻态,准备接收数据;

  • 状态2,检查data_ready信号量,判断UART是否准备好数据,若果data_ready为1,则说明UART已经准备好数据,此时置rdn为0,使移位寄存器rsr中的数据输出到数据总线dout,进入状态3,否则回到状态1,继续准备接收数据;

  • 状态3,从数据总线读取数据,输出到LED灯,回到状态1继续准备接收数据。

状态机如下图所示:

串口控制器读操作状态图

③ 综合上面两个操作,以及上一张的内容,利用一个大的状态机,控制读串口、写RAM、读RAM、写串口等状态,将从PC发送过来的10字节数据,顺序存入BaseRAM中,再从BaseRAM依次读出,送回到PC。具体步骤如下:

  • 系统复位后,从拨码开关获得初始内存地址,保存到自己定义的寄存器中(以下称为Addr);

  • 读串口,将收到的数据保存到自己定义的寄存器中(以下称为Data);

  • 将Data写入到BaseRAM中,地址为Addr的字上。为了简化实现,只使用32位中的低8位存储数据,高24位空间不使用。写入完成后把Addr加一;

  • 重复读串口、写内存的步骤10次,也就是说总共从串口接收10个字节,保存到BaseRAM的连续10个字的空间中;

  • 将Addr重新设为初始地址(可以从拨码开关获得);

  • 读取BaseRAM中地址为Addr的字,将低8位保存到Data寄存器;

  • 写串口,把Data发送出去,发送完成后把Addr加一;

  • 重复读内存、写串口的步骤10次,即把内存中的10字节数据依次发送出去;

实验中需要交替访问BaseRAM和UART,状态机必须控制好两者的使能信号,以及FPGA自身的数据线高阻态,避免发生冲突。

实验数据

将实验过程中对串口读写的数据记录在下表中:

写串口 读串口
拨码开关数据 收到数据 发送数据 数码管显示数据



思考题

  1. 请总结教学机上的UART和普通的串口芯片8251的异同点?(不做要求,可以先参考阅读8251的相关资料。)

  2. 如果要求将PC端发送过来的数据存入到Base_RAM的某个单元,然后从该单元中读出,再加1送回到PC端,则代码需要进行怎样的修改?有兴趣可以试着做一下。

实验提示

上述实验过程实际上将状态机和需要实现的功能一并叙述了。在实际的工作过程中,串口控制器也最好需要接入50MHz的时钟,这也是为了下一步的处理器实验打下基础,获得感性认识。

首先一定要理解下面的输入输出信号(可以在thinpad_top项目中看到)

    //CPLD串口控制器信号
    output wire uart_rdn,         //读串口信号,低有效
    output wire uart_wrn,         //写串口信号,低有效
    input wire uart_dataready,    //串口数据准备好
    input wire uart_tbre,         //发送数据标志
    input wire uart_tsre,         //数据发送完毕标志

其中uart_rdn和uart_dataready来控制从串口读取,一个为输入,一个为输出。

uart_wrn,uart_tbre,uart_tsre来控制往串口上写数据,其中uart_wrn说明需要写,uart_tbre和uart_tsre是串口的反馈信号。

串口读的流程:1. 探测到uart_dataready,说明串口有数据,cpld已经将数据准备好,等待控制器读取。2. 设置总线base_ram_data_wire为高阻态,控制器拉低uart_rdn,开始读取。3. 控制器读取数据,拉高uart_rdn,说明读取完毕。

串口写的流程:1. 首先要准备好数据。2. 拉低uart_wrn。3. 拉高uart_wrn。4. 等待uart_tbre拉高。5. 等待uart_tsre拉高。

下面是本实验的工作截图:

1 串口的输出。

2 选择共享总线CPLD模拟,不是直连的串口。

3 打开/关闭串口。

4 发送按钮(可以自行选择,按照程序要求)。

5 需要发送的数据。

6 LED显示。


最后更新: 2021年10月25日