差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 后一修订版 两侧同时换到之后的修订记录 | ||
串口监视系统设计 [2018/10/22 16:14] anran [实验原理] |
串口监视系统设计 [2018/10/22 16:24] anran [实验现象] |
||
---|---|---|---|
行 115: | 行 115: | ||
**节拍模块Baud设计实现:** | **节拍模块Baud设计实现:** | ||
+ | |||
节拍模块Baud的端口程序实现如下: | 节拍模块Baud的端口程序实现如下: | ||
<code verilog> | <code verilog> | ||
行 161: | 行 162: | ||
**发送模块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: | 行 209: | ||
{{:6-UART发送功能设计实现.png?600|UART发送功能设计实现}} | {{:6-UART发送功能设计实现.png?600|UART发送功能设计实现}} | ||
- | |||
**接收模块Uart_Rx设计实现:** | **接收模块Uart_Rx设计实现:** | ||
行 292: | 行 293: | ||
===系统总体实现=== | ===系统总体实现=== | ||
+ | 刚刚学习了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设计框图}} | ||
行 306: | 行 359: | ||
====实验现象==== | ====实验现象==== | ||
+ | |||
+ | 使用两根Micro-USB线同时连接核心板和底板的USB接口,将程序下载到FPGA中,数码管处于不显示的状态,打开电脑上的串口调试助手,按照前面图片配置相应参数,在数据发送窗口输入数字,点击发送观察底板数码管的变化,重新输入数字,点击发送再次观察底板数码管的变化。 |