• ZYNQ_project:uart(odd,even)


    概念:

    UART(Universal Asynchronous Receiver-Transmitter):即通用异步收发器,是一种通用串行数据总线,用于异步通信。一般UART接口常指串口。

    UART在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。

    单工通信:数据只能沿一个方向传输。

    半双工通信:数据可以沿两个方向传输,但需要分时进行。

    全双工通信:数据可以同时进行双向传输。

    同步通信:带时钟端口的数据传输。

    异步通信:没有时钟端口,发送方和接收方使用各自的时钟控制数据的收发过程。

    常见串行通信接口:

     模块框图:

    时序图:

     

    代码:

    1. // uart的接收模块,要求波特率可调,回环实验
    2. // 完成回环实验后加入校验位
    3. // 然后加入led与蜂鸣器的控制模块
    4. `include "para.v"
    5. module rx (
    6. input wire sys_clk ,
    7. input wire sys_rst_n ,
    8. input wire rx ,
    9. output reg [7:0] po_data , // port_output
    10. output reg po_flag
    11. );
    12. // parameter
    13. parameter MAX_BPS_CNT = `CLOCK/`BPS ,//434 ,
    14. MAX_BIT_CNT = `BIT_CHACK ;//10 ;
    15. localparam RX_MOD = 1'b1 ,
    16. CHECK_MOD = `EVEN ;
    17. // reg signal define
    18. reg rx_r1 ;
    19. reg rx_r2 ;
    20. reg [31:0] cnt_bps ;
    21. reg work ;
    22. reg [3:0] cnt_bit ;
    23. reg [7:0] data_reg ;
    24. reg check ;
    25. reg check_reg;
    26. // wire signal define
    27. wire nege ;
    28. /*******************************************************************/
    29. // // reg signal define
    30. // reg rx_r1 ;
    31. always @(posedge sys_clk or negedge sys_rst_n) begin
    32. if(~sys_rst_n)
    33. rx_r1 <= 1'b1 ;
    34. else
    35. rx_r1 <= rx ;
    36. end
    37. // reg rx_r2 ;
    38. always @(posedge sys_clk or negedge sys_rst_n) begin
    39. if(~sys_rst_n)
    40. rx_r2 <= 1'b1 ;
    41. else
    42. rx_r2 <= rx_r1 ;
    43. end
    44. // reg work ;
    45. always @(posedge sys_clk or negedge sys_rst_n) begin
    46. if(~sys_rst_n)
    47. work <= 1'b0 ;
    48. else if(nege)
    49. work <= 1'b1 ;
    50. else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))) // 这俩条件可以用end_cnt_XXX来代替,组合逻辑赋
    51. work <= 1'b0 ;
    52. else
    53. work <= work ;
    54. end
    55. // reg [31:0] cnt_bps ;
    56. always @(posedge sys_clk or negedge sys_rst_n) begin
    57. if(~sys_rst_n)
    58. cnt_bps <= 32'd0 ;
    59. else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
    60. cnt_bps <= 32'd0 ;
    61. else if(work)
    62. cnt_bps <= cnt_bps + 1'b1 ;
    63. else
    64. cnt_bps <= 32'd0 ;
    65. end
    66. // reg [3:0] cnt_bit ; 应该会归0
    67. always @(posedge sys_clk or negedge sys_rst_n) begin
    68. if(~sys_rst_n)
    69. cnt_bit <= 4'd0 ;
    70. else if (work && (cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1)))
    71. cnt_bit <= 4'd0 ;
    72. else if (work && (cnt_bps == (MAX_BPS_CNT - 1)))
    73. cnt_bit <= cnt_bit + 1'b1 ;
    74. else if(work)
    75. cnt_bit <= cnt_bit ;
    76. else
    77. cnt_bit <= 8'd0 ;
    78. end
    79. // reg [7:0] data_reg;
    80. always @(posedge sys_clk or negedge sys_rst_n) begin
    81. if(~sys_rst_n)
    82. data_reg <= 8'd0 ;
    83. else if(work && cnt_bps == (MAX_BPS_CNT/2)) begin // 采样,采集数据的时刻
    84. case (cnt_bit)
    85. 0 : data_reg <= 8'd0 ;
    86. 1 : data_reg[cnt_bit - 1] <= rx_r2 ;
    87. 2 : data_reg[cnt_bit - 1] <= rx_r2 ;
    88. 3 : data_reg[cnt_bit - 1] <= rx_r2 ;
    89. 4 : data_reg[cnt_bit - 1] <= rx_r2 ;
    90. 5 : data_reg[cnt_bit - 1] <= rx_r2 ;
    91. 6 : data_reg[cnt_bit - 1] <= rx_r2 ;
    92. 7 : data_reg[cnt_bit - 1] <= rx_r2 ;
    93. 8 : data_reg[cnt_bit - 1] <= rx_r2 ;
    94. default: data_reg <= data_reg ;
    95. endcase
    96. end else
    97. data_reg <= data_reg ;
    98. end
    99. // // wire signal define
    100. // wire nege ;
    101. assign nege = ~rx_r1 && rx_r2 ;
    102. // reg check ;
    103. always @(posedge sys_clk or negedge sys_rst_n) begin
    104. if(~sys_rst_n)
    105. check <= 1'b0 ;
    106. else if(CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
    107. check <= ~^data_reg ;
    108. else if(~CHECK_MOD && (cnt_bit == ((MAX_BIT_CNT - 2))) && (cnt_bps == (MAX_BPS_CNT - 1)))
    109. check <= ^data_reg ;
    110. else
    111. check <= check ;
    112. end
    113. // reg check_reg;
    114. always @(posedge sys_clk or negedge sys_rst_n) begin
    115. if(~sys_rst_n)
    116. check_reg <= 1'b0 ;
    117. else if((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT /2)))
    118. check_reg <= rx_r2 ;
    119. else
    120. check_reg <= check_reg ;
    121. end
    122. // output reg [7:0] po_data , // port_output
    123. always @(posedge sys_clk or negedge sys_rst_n) begin
    124. if(~sys_rst_n)
    125. po_data <= 8'd0 ;
    126. else if((check == check_reg) && (cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1)))
    127. po_data <= data_reg ;
    128. else if(RX_MOD)
    129. po_data <= po_data ;
    130. else
    131. po_data <= 8'd0 ;
    132. end
    133. // output reg po_flag
    134. always @(posedge sys_clk or negedge sys_rst_n) begin
    135. if(~sys_rst_n)
    136. po_flag <= 8'd0 ;
    137. else if((check == check_reg) && ((cnt_bit == ((MAX_BIT_CNT - 1))) && (cnt_bps == (MAX_BPS_CNT - 1))))
    138. po_flag <= 1'b1 ;
    139. else
    140. po_flag <= 8'd0 ;
    141. end
    142. endmodule
    1. // uart的数据发送模块。停止位 1bit
    2. `include "para.v"
    3. module tx(
    4. input wire sys_clk ,
    5. input wire sys_rst_n ,
    6. input wire [7:0] pi_data ,
    7. input wire pi_flag ,
    8. output reg tx
    9. );
    10. // parameter
    11. parameter MAX_BPS_CNT = `CLOCK/`BPS ,
    12. MAX_BIT_CNT = `BIT_CHACK + 1;
    13. localparam CHECK_MOD = `EVEN ;
    14. // reg signal define
    15. reg [7:0] data_reg ;
    16. reg work ;
    17. reg [31:0] cnt_bps ;
    18. reg [3:0] cnt_bit ;
    19. /********************************************************************/
    20. // // reg signal define
    21. // reg [7:0] data_reg ;
    22. always @(posedge sys_clk or negedge sys_rst_n) begin
    23. if(~sys_rst_n)
    24. data_reg <= 8'd0 ;
    25. else if(pi_flag)
    26. data_reg <= pi_data ;
    27. else
    28. data_reg <= data_reg ;
    29. end
    30. // reg work ;
    31. always @(posedge sys_clk or negedge sys_rst_n) begin
    32. if(~sys_rst_n)
    33. work <= 1'b0 ;
    34. else if(pi_flag)
    35. work <= 1'b1 ;
    36. else if(cnt_bps == (MAX_BPS_CNT - 1) && cnt_bit == (MAX_BIT_CNT - 1))
    37. work <= 1'b0 ;
    38. else
    39. work <= work ;
    40. end
    41. // reg [31:0] cnt_bps ;
    42. always @(posedge sys_clk or negedge sys_rst_n) begin
    43. if(~sys_rst_n)
    44. cnt_bps <= 32'd0 ;
    45. else if((work && (cnt_bps == (MAX_BPS_CNT - 1)))
    46. || (work && (cnt_bit == (MAX_BIT_CNT - 1)) && cnt_bps == (MAX_BPS_CNT - 1)))
    47. cnt_bps <= 32'd0 ;
    48. else if(work)
    49. cnt_bps <= cnt_bps + 1'b1 ;
    50. else
    51. cnt_bps <= 32'd0 ;
    52. end
    53. // reg [3:0] cnt_bit ;
    54. always @(posedge sys_clk or negedge sys_rst_n) begin
    55. if(~sys_rst_n)
    56. cnt_bit <= 4'd0 ;
    57. else if(work && (cnt_bps == (MAX_BPS_CNT - 1)) && cnt_bit == (MAX_BIT_CNT - 1))
    58. cnt_bit <= 4'd0 ;
    59. else if(work && (cnt_bps == (MAX_BPS_CNT - 1)))
    60. cnt_bit <= cnt_bit + 1'b1 ;
    61. else if(work)
    62. cnt_bit <= cnt_bit ;
    63. else
    64. cnt_bit <= 4'd0 ;
    65. end
    66. // output reg tx
    67. always @(*) begin
    68. if(~sys_rst_n)
    69. tx = 1'b1 ;
    70. else if(work) begin
    71. case (cnt_bit)
    72. 4'd0: tx = 1'b0 ;
    73. 4'd1: tx = data_reg[cnt_bit - 1] ;
    74. 4'd2: tx = data_reg[cnt_bit - 1] ;
    75. 4'd3: tx = data_reg[cnt_bit - 1] ;
    76. 4'd4: tx = data_reg[cnt_bit - 1] ;
    77. 4'd5: tx = data_reg[cnt_bit - 1] ;
    78. 4'd6: tx = data_reg[cnt_bit - 1] ;
    79. 4'd7: tx = data_reg[cnt_bit - 1] ;
    80. 4'd8: tx = data_reg[cnt_bit - 1] ;
    81. 4'd9: begin
    82. if(CHECK_MOD)
    83. tx = ~^data_reg ;
    84. else
    85. tx = ^data_reg ;
    86. end
    87. default: tx = 1'b1 ;
    88. endcase
    89. end else
    90. tx = 1'b1 ;
    91. end
    92. endmodule

     

    1. module top(
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire rx ,
    5. output wire tx
    6. );
    7. // 例化间连线 Wiring between instantiations
    8. wire clk_100Mhz ;
    9. wire clk_50Mhz ;
    10. wire locked ;
    11. wire rst_n ;
    12. assign rst_n = sys_rst_n && locked ;
    13. wire [7:0] po_data ;
    14. wire po_flag ;
    15. pll pll_inst(
    16. .clk_in1 ( sys_clk ) ,
    17. .resetn ( sys_rst_n ) ,
    18. .clk_out1 ( clk_100Mhz ) ,
    19. .clk_out2 ( clk_50Mhz ) ,
    20. .locked ( locked )
    21. );
    22. rx rx_inst(
    23. .sys_clk ( clk_50Mhz ) ,
    24. .sys_rst_n ( rst_n ) ,
    25. .rx ( rx ) ,
    26. .po_data ( po_data ) ,
    27. .po_flag ( po_flag )
    28. );
    29. tx tx_inst(
    30. .sys_clk ( clk_50Mhz ) ,
    31. .sys_rst_n ( rst_n ) ,
    32. .pi_data ( po_data ) ,
    33. .pi_flag ( po_flag ) ,
    34. .tx ( tx )
    35. );
    36. endmodule

     

    仿真:

  • 相关阅读:
    git新建仓库上传项目步骤
    Python自学教程7:字典类型有什么用
    基于功能安全的车载计算平台开发:硬件层面
    压缩包系列
    stm32定时器之简单封装
    为什么使用RedisDesktopManager可以连上redis,微服务似乎无法访问redis
    可变电阻元件封装
    C语言之自定义类型_结构体篇(1)
    写给前端的 react-native 入门指南
    腾讯云GPU云服务器计算型GN7有哪些特点?适用于哪些场景?
  • 原文地址:https://blog.csdn.net/Meng_long2022/article/details/134470262