当前位置:   article > 正文

FPGA协议篇:UART通信及Verilog最易懂实现方式/通用于任何工程/带握手信号 ----UART_TX_uart异步通信fpga verilog

uart异步通信fpga verilog

概述:

        UART(Universal Asynchronous Receiver/Transmitter)是一种通用的异步收发传输协议,用于在计算机系统和外部设备之间进行串行数据传输。UART 协议定义了数据的传输格式和通信规则,使得不同设备之间能够进行可靠的数据交换。

首先先把设计代码放到这里:UART_TX完整代码下载

以下是 UART 协议的几个关键要素:

        1、异步传输:UART 使用异步传输方式,不需要共享时钟信号来进行数据同步。发送端和接收端通过起始位、数据位和停止位进行数据的有效传输。

        2、起始位和停止位:在每个数据字节的开始之前,UART 使用一个起始位来标识传输的起始点。而在数据字节的末尾,UART 添加一个或多个停止位以标识传输的结束。起始位和停止位的数量可以根据协议和设置进行配置。

        3、数据位:UART 协议规定了数据位的传输顺序和位数。数据位是实际传输的数据位数,典型的位数为 5、6、7 或 8 位,具体取决于协议和配置。重要的一点:UART的传输数据为:

        4、波特率:UART 通信的波特率指的是每秒传输的位数。发送端和接收端必须以相同的波特率进行通信,以确保数据的正确传输。常见的波特率包括 9600、115200 等。

        5、校验位(可选):为了增加数据传输的可靠性,UART 还可以使用校验位进行错误检测。校验位是在数据位之后添加的一个位,用于验证数据的准确性。常见的校验方式包括奇校验和偶校验。

UART 协议在许多应用中得到广泛应用,例如串口通信、嵌入式系统、传感器和外围设备等。它提供了一种简单而有效的数据传输方式,允许设备之间进行可靠的异步通信。

本章将介绍如何使用Verilog实现UART发送部分并进行下板验证:

一、UART构成

根据概述可以简单的提取出来,如下图:UART接受传输的数据格式:

讲解几个关键点:

        1、UART传输数据顺序:

                LSB → MSB,从最低位到最高位

                例如:d=8'b1011_0011    :传输顺序:d[0],d[1] ....... d[6],d[7]

        2、通信方式:

                异步通信:“不需要额外的时钟线进行数据的同步传输”

                全双工传输:UART 只需要两条信号线:RXD 和 TXD ,可以同时进行传输

        3、传输数据速率:

                采用波特率作为传输数据的速率(每秒传输二进制位数的多少),单位:BPS,常用波特率有9600、14400、38400、57600...115200。

        例如波特率=115200,则它传输一位数据位(1bit)的时间为1/115200s

        两个设备通过UART传输的时候,必须是相同波特率。

二、时钟与波特率的计算

        涉及到两个量:

        1、FPGA时钟主频率:FPGA 主频指的是 FPGA 设备上时钟信号的频率,通常以赫兹(Hz)为单位。

        2、波特率:波特率指的是数据传输的速率,以位每秒(bps)为单位。

根据这两个量,可以计算出数据传输的时间,所需要的时钟周期:、

        例如:时钟频率100M,波特率115200bps

                bps_cnt = 100_000_000 / 9600 = 868 

        可以得出:FPGA传输数据,需要翻转868个时钟周期,才可以传输一位数据。

简单一点就是时钟频率除以波特率就是需要的计数。

三、Verilog实现

1、UART_TX设计框图        ​​​​​

端口名称端口属性介绍
i_clk输入端口FPGA输入时钟
i_reset输入端口FPGA输入复位,高有效
i_data[7:0]输入端口

UART发送数据

i_valid输入端口输入数据有效
o_ready输出端口数据传输完成
o_txd输出端口UART输出接口

部分代码:

  1. module uart_tx #(
  2. parameter CHECK_BIT = "None", //“None”无校验 “Odd”奇校验 “Even”偶校验
  3. parameter BPS = 115200, //系统波特率
  4. parameter CLK = 25_000_000, //系统时钟频率 hz
  5. parameter DATA_BIT = 8, //数据位(6、7、8)
  6. parameter STOP_BIT = 1 //停止位 (1、2、3... 整数)
  7. )(
  8. input i_reset,
  9. input i_clk,
  10. input [DATA_BIT-1:0] i_data,
  11. input i_valid,
  12. output reg o_ready,
  13. output reg o_txd
  14. );
  15. endmodule

2、UART_TX状态转移图

 

代码中采用三段式状态机:

IDLE:空闲状态,无数据传输,输出高电平,当i_valid信号到来时跳转到START状态;

START:起始位,无数据传输,输出低电平为 ,无条件跳转至DATA状态;

DATA:数据位,进行数据传输,先发送低比特,根据数据输出高低电平,假如有校验位,跳到CHECK状态,假如数据传输不设校验位,跳转到STOP状态;

CHECK:奇偶校验位处理状态,根据CHECK_BIT参数进行添加校验位值。

STOP:停止位状态,输出STOP_BIT个高电平。 

部分代码:

  1. reg [3:0] c_state, n_state;
  2. parameter IDLE = 0,
  3. STATE = 1,
  4. DATA = 2,
  5. CHECK = 3,
  6. STOP = 4;
  7. ///* FSM *3 *//
  8. always @(posedge i_clk, posedge i_reset) begin
  9. if (i_reset)
  10. c_state <= 0;
  11. else
  12. c_state <= n_state;
  13. end
  14. always @(*) begin
  15. case (c_state)
  16. IDLE : begin
  17. if (tx_en && i_valid)
  18. n_state = STATE;
  19. else
  20. n_state = IDLE;
  21. end
  22. STATE : begin
  23. if (tx_en)
  24. n_state = DATA;
  25. else
  26. n_state = STATE;
  27. end
  28. DATA : begin
  29. if (tx_en && tx_cnt >= DATA_BIT && CHECK_BIT == "None")
  30. n_state = STOP;
  31. else if (tx_en && tx_cnt >= DATA_BIT)
  32. n_state = CHECK;
  33. else
  34. n_state = DATA;
  35. end
  36. CHECK : begin
  37. if (tx_en)
  38. n_state = STOP;
  39. else
  40. n_state = CHECK;
  41. end
  42. STOP : begin
  43. if (tx_en && stop_cnt == 1)
  44. n_state = IDLE;
  45. else
  46. n_state = STOP;
  47. end
  48. default : n_state = 0;
  49. endcase
  50. end

3、发送数据格式

此模块用于辅助大家更好的运用UART_TX模块,展示了握手信号的工作方式,以及串口发送模块的调用方法。

为了方便大家理解,给大家画了一个发送数据的时序图:

在数据发送过程中,握手信号的细致描述如下:(接收端即UART_TX模块)

初始状态:发送端准备好发送数据,并将VALID信号置高,表示数据有效。接收端处于等待状态,READY信号为低电平,表示接收端尚未准备好接收数据。

数据传输开始:发送端在VALID信号置高后,开始传输数据。发送端将要发送的数据值放置在DATA线上,并保持稳定。VALID信号保持高电平,表示数据一直有效。

握手信号等待:接收端检测到VALID信号置高后,开始等待READY信号的响应。接收端会持续监测READY信号状态,直到它被置高。

数据接收和响应:一旦接收端检测到READY信号置高,它表示接收端已经准备好接收数据。在READY信号置高后,发送端可以改变DATA的值,并且VALID信号也可以跟随着改变。这表示发送端可以发送下一个数据。

握手信号完成:发送端发送数据后,继续保持VALID信号的高电平,表示数据仍然有效。接收端在接收完数据后,如果准备好接收下一个数据,则保持READY信号的高电平。这样一个完整的握手信号周期就完成了。

通过这种握手信号的交互,发送端和接收端能够进行同步的数据传输。VALID信号的高电平表示数据有效,READY信号的高电平表示接收端准备好接收数据。只有在READY信号置高后,发送端才能改变数据并发送下一个数据。

这种握手机制确保了数据的可靠传输,发送端和接收端在数据传输过程中能够以协调的方式进行通信。

部分代码:

  1. module UART_tx_gen_data(
  2. input clk_a,
  3. input rst_n,
  4. output txd
  5. );
  6. reg [7:0] temp_data;
  7. reg [7:0] tx_data;
  8. reg tx_valid;
  9. wire ready;
  10. reg [3:0] c_state, n_state;
  11. parameter S0 = 0,
  12. S1 = 1;
  13. uart_tx #(
  14. .CHECK_BIT ("None" ) , //“None”无校验 “Odd”奇校验 “Even”偶校验
  15. .BPS (115200 ) , //系统波特率
  16. .CLK (25_000_000) , //系统时钟频率 hz
  17. .DATA_BIT (8 ) , //数据位(6、7、8)
  18. .STOP_BIT (1 ) //停止位
  19. ) TX (
  20. .i_reset(!rst_n),
  21. .i_clk(clk_a),
  22. .i_data(tx_data),
  23. .i_valid(tx_valid),
  24. .o_ready(ready),
  25. .o_txd(txd)
  26. );
  27. always @(posedge clk_a, negedge rst_n) begin
  28. if (!rst_n)
  29. c_state <= 0;
  30. else
  31. c_state <= n_state;
  32. end

四、下板验证

通过上面两个模块,既可以对串口发送进行验证,把UART_tx_gen_data置为顶层,然后对端口进行引脚约束,生成下载文件,然后下载到板卡:

同时打开串口调试助手,选择波特率115200,数据位8,停止位1,校验位none,按16进制显示:

然后运行程序,即可在接收窗口收到连续变换的数据:

这样的话,此UART_TX设计已经完全完成了,下一期将更新UART_RX的设计和讲解。

如果感觉文章对您有用,麻烦三连支持一下,方便下次用到的时候,就可以快速找到我,非常感谢您的支持!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/417378
推荐阅读
相关标签
  

闽ICP备14008679号