差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
串口监视系统设计 [2018/10/22 16:14]
anran [实验原理]
串口监视系统设计 [2020/01/18 21:54] (当前版本)
gongyu
行 1: 行 1:
-=====串口监视系统设计===== +### 串口监视系统设计 
------ + 
-====实验任务====+--- 
 + 
 +#### 实验任务
  
   * 任务:基于 STEP-MAX10M08核心板 和 STEP BaseBoard V3.0底板 完成串口监视系统设计并观察调试结果。   * 任务:基于 STEP-MAX10M08核心板 和 STEP BaseBoard V3.0底板 完成串口监视系统设计并观察调试结果。
行 7: 行 9:
   * 解析:通过FPGA编程驱动底板上的CP2102串口通信模块,接收来自PC(串口调试助手)或其他串口设备的数据,经过处理,最后通过驱动8位扫描式数码管模块,将接收到的数据显示在底板数码管上。   * 解析:通过FPGA编程驱动底板上的CP2102串口通信模块,接收来自PC(串口调试助手)或其他串口设备的数据,经过处理,最后通过驱动8位扫描式数码管模块,将接收到的数据显示在底板数码管上。
  
-====实验目的====+#### 实验目的
  
 本实验主要学习串口(UART)总线工作原理、协议及相关知识,练习如何使用FPGA驱动CP2102模块实现串口通信设计,同时复习上节中扫描式数码管模块的实例化应用。 本实验主要学习串口(UART)总线工作原理、协议及相关知识,练习如何使用FPGA驱动CP2102模块实现串口通信设计,同时复习上节中扫描式数码管模块的实例化应用。
行 14: 行 16:
   * 完成串口监视系统设计实现   * 完成串口监视系统设计实现
  
-====设计框图====+#### 设计框图
  
 根据前面的实验解析我们可以得知,该设计可以拆分成三个功能模块实现, 根据前面的实验解析我们可以得知,该设计可以拆分成三个功能模块实现,
行 24: 行 26:
   * Uart_Rx:根据数据传输速率节拍控制UART通信数据格式。   * Uart_Rx:根据数据传输速率节拍控制UART通信数据格式。
  
-{{:​6-Top-Down层次设计.png?​500|Top-Down层次设计}}{{:​6-模块结构设计.png?​500|模块结构设计}} +{{:​6-Top-Down层次设计.png?​600|Top-Down层次设计}}{{:​6-模块结构设计.png?​500|模块结构设计}} 
-====实验原理====+ 
 +#### 实验原理
  
-===UART接口介绍===+##### UART接口介绍
  
 {{:​6-UART通信接口.png?​400|UART通信接口}} {{:​6-UART通信接口.png?​400|UART通信接口}}
行 53: 行 56:
   * 空闲位:处于逻辑 1 状态,表示当前线路上没有资料传送。   * 空闲位:处于逻辑 1 状态,表示当前线路上没有资料传送。
  
-===UART模块连接===+##### UART模块连接
  
 STEP BaseBoard V3.0底板上的基于CP2102方案的UART通信模块电路图如下: STEP BaseBoard V3.0底板上的基于CP2102方案的UART通信模块电路图如下:
行 61: 行 64:
 上图为基于CP2102方案的UART通信模块电路图,可以看到CP2102方案非常简洁,无需外置USB通信时钟晶体(内部集成),CP2102芯片TXD和RXD分别与FPGA芯片RXD和TXD连接,同时两个信号都连接了LED灯,这样当UART通信时,随着数据传输对应LED灯也会快速闪烁,起到UART通信指示灯的作用。CP2102芯片DTR和RTS通过两个三极管搭建流控电路,连接WIFI模块ESP8266-12F,使用UART模块烧写ESP8266模块的固件时就无需手动进入固件烧写模式了,这个会在后续涉及WIFI通信的实验中详细介绍,这里可以不用理会。 上图为基于CP2102方案的UART通信模块电路图,可以看到CP2102方案非常简洁,无需外置USB通信时钟晶体(内部集成),CP2102芯片TXD和RXD分别与FPGA芯片RXD和TXD连接,同时两个信号都连接了LED灯,这样当UART通信时,随着数据传输对应LED灯也会快速闪烁,起到UART通信指示灯的作用。CP2102芯片DTR和RTS通过两个三极管搭建流控电路,连接WIFI模块ESP8266-12F,使用UART模块烧写ESP8266模块的固件时就无需手动进入固件烧写模式了,这个会在后续涉及WIFI通信的实验中详细介绍,这里可以不用理会。
  
-===UART驱动实现===+##### UART驱动实现
  
 {{:​6-串行总线对比.png?​600|串行总线对比}} {{:​6-串行总线对比.png?​600|串行总线对比}}
行 115: 行 118:
  
 **节拍模块Baud设计实现:** **节拍模块Baud设计实现:**
 +
 节拍模块Baud的端口程序实现如下: 节拍模块Baud的端口程序实现如下:
 <code verilog> <code verilog>
行 161: 行 165:
  
 **发送模块Uart_Tx设计实现:** **发送模块Uart_Tx设计实现:**
 +
 前级电路通过tx_data_valid和tx_data_in将需要发送的数据传输进来,当tx_data_valid有脉冲信号时,tx_data_in信号为有效数据,拼接起始位和停止位后赋值给tx_data_r,同时控制节拍使能信号使能并自锁,然后等发送完10bit数据后解除使能。 前级电路通过tx_data_valid和tx_data_in将需要发送的数据传输进来,当tx_data_valid有脉冲信号时,tx_data_in信号为有效数据,拼接起始位和停止位后赋值给tx_data_r,同时控制节拍使能信号使能并自锁,然后等发送完10bit数据后解除使能。
  
行 207: 行 212:
  
 {{:​6-UART发送功能设计实现.png?​600|UART发送功能设计实现}} {{:​6-UART发送功能设计实现.png?​600|UART发送功能设计实现}}
- 
  
 **接收模块Uart_Rx设计实现:** **接收模块Uart_Rx设计实现:**
行 290: 行 294:
 当我们需要UART发送数据的时候只需要实例化发送功能部分设计,需要UART接收数据的时候只需要实例化接收功能部分设计,例如本设计中FPGA驱动UART模块接收电脑串口调试助手发出的数据,所以我们就只需要实例化接收功能部分设计即可。 当我们需要UART发送数据的时候只需要实例化发送功能部分设计,需要UART接收数据的时候只需要实例化接收功能部分设计,例如本设计中FPGA驱动UART模块接收电脑串口调试助手发出的数据,所以我们就只需要实例化接收功能部分设计即可。
  
-===系统总体实现===+##### 系统总体实现
  
 +刚刚学习了UART通信模块,本设计只需要使用接收功能部分设计,每一次通信都会得到一个8位数据,怎样将8位数据对应得数据显示在数码管上呢?我来先来了解一下UART接受到的8位数据与要显示数字的关系
  
 +{{:​6-串口调试助手界面.png?​600|串口调试助手界面}}
  
-====实验步骤====+上图为电脑端友善串口调试助手的界面,当我们将硬件连接,在串口设置串口选定串口对应的端口,并按上图配置波特率、数据位、校验位、停止位、流控等,点击开始建立连接,接下来我们就可以在串口发送窗口输入要发送的数据,点击发送后数据传输出去。在发送设置有两个选项:ASCII和Hex , 
 +  * 当选择ASCII的时候,通过UART发出的数据是数据窗口中字符的ASCII码值,每个字符的ASCII码值都是8位数据,所以窗口中字符数量与UART传输的次数是相等的,同时数字的值与ASCII码值相差48,例如数字0的ASCII码值为48。 
 +  * 当选择Hex的时候,通过UART发出的数据(必须是16进制数据)就是数据窗口中的数据本身,这样每次UART传输都会发送两个数字,如果只发送一个数字,则高位补零组成8位数据,例如发送数字1,实际UART传输的数据为8‘h01。 
 + 
 +我们设计一个32位的移位寄存器对应8位数码管,按照BCD码格式每4位表示一个数字,每次接收到UART数据都存到移位寄存器中,同时控制数码管显示相应的数码管位,Decoder程序实现如下: 
 +<code verilog>​ 
 +`ifdef HEX_FORMAT //​如果用define定义过HEX_FORMAT 
 + //​采用16进制格式,接收到的数据等于数值本身 
 + wire [7:0] seg_data_r ​rx_data_out;​ 
 + 
 + //​移位寄存器,对应8位数码管数据BCD码 
 + always @ (posedge rx_data_valid or negedge rst_n) begin 
 + if(!rst_n) seg_data <1'​b0;​ 
 + else seg_data <{seg_data[23:​0],​seg_data_r};​ 
 + end 
 + 
 + //​移位寄存器,对应8位数码管数据显示使能 
 + always @ (posedge rx_data_valid or negedge rst_n) begin 
 + if(!rst_n) data_en <1'​b0;​ 
 + else data_en <{data_en[5:​0],​2'​b11};​ 
 + end 
 +`else 
 + //​采用字符格式,接收到的数据为字符ASCII码值,与数字值相差48 
 + wire [7:0] seg_data_r ​rx_data_out - 8'​d48;​ 
 + 
 + //​移位寄存器,对应8位数码管数据BCD码 
 + always @ (posedge rx_data_valid or negedge rst_n) begin 
 + if(!rst_n) seg_data <1'​b0;​ 
 + else seg_data <{seg_data[27:​0],​seg_data_r[3:​0]};​ 
 + end 
 + 
 + //​移位寄存器,对应8位数码管数据显示使能 
 + always @ (posedge rx_data_valid or negedge rst_n) begin 
 + if(!rst_n) data_en <= 1'​b0;​ 
 + else data_en <= {data_en[6:​0],​1'​b1};​ 
 + end 
 +`endif 
 +</​code>​ 
 + 
 +上面程序中`ifdef……`else……`endif语句为预编译指令,与C预演类似。如果我们使用串口助手Hex(16进制)格式发送数据,需要在程序中使用define定义参数HEX_FORMAT,如果使用ASCII格式发送数据,则不需要定义。 
 + 
 +<code verilog>​ 
 +`define HEX_FORMAT //​串口助手使用Hex格式发送时定义HEX_FORMAT,否则不定义 
 +</​code>​ 
 + 
 +综合后的设计框图如下: 
 + 
 +{{:​6-系统-RTL设计框图.png?​800|RTL设计框图}} 
 + 
 + 
 +#### 实验步骤
   - 双击打开Quartus Prime工具软件;   - 双击打开Quartus Prime工具软件;
   - 新建工程:File → New Project Wizard(工程命名,工程目录选择,设备型号选择,EDA工具选择);   - 新建工程:File → New Project Wizard(工程命名,工程目录选择,设备型号选择,EDA工具选择);
行 305: 行 361:
  
  
-====实验现象====+#### 实验现象 
 + 
 +使用两根Micro-USB线同时连接核心板和底板的USB接口,将程序下载到FPGA中,数码管处于不显示的状态,打开电脑上的串口调试助手,按照前面图片配置相应参数,在数据发送窗口输入数字,点击发送观察底板数码管的变化,重新输入数字,点击发送再次观察底板数码管的变化。