36.UART(通用异步收发传输器)-RS232(3)

(1)串口发送模块visio视图:

(2)串口发送模块Verilog代码:

/*
常见波特率: 4800、9600、14400、115200
在系统时钟为50MHz时,对应计数为:   
(1/4800)    * 10^9 /20 -1 = 10416     
(1/9600)    * 10^9 /20 -1 = 5207
(1/14400)   * 10^9 /20 -1 = 3471
(1/115200)  * 10^9 /20 -1 = 433 
*/

module rs232_tx
(
    input   [16:0]  baud_set        ,
    input           clk             ,
    input           reset_n         ,
    input   [7:0]   tx_data         ,
    input           tx_start        ,
    
    output   reg    tx              ,
    output   reg    tx_done            
    
);
    
    reg [15:0]      BAUD_MCNT       ;
    reg [7:0]       r_tx_data       ;
    reg             en_baud_cnt     ;
    reg [15:0]      baud_cnt        ;
    reg [3:0]       bit_cnt         ;
    
    
//波特最大计数设计
    always@(posedge clk)
            begin
                case(baud_set)
                    17'd4800    :BAUD_MCNT <= 16'd10416;
                    17'd9600    :BAUD_MCNT <= 16'd5207;
                    17'd14400   :BAUD_MCNT <= 16'd3471;
                    17'd115200  :BAUD_MCNT <= 16'd433;
                    default     :BAUD_MCNT <= 16'd5207;      //当输入baud_set为其他值时,一律当成9600处理。
                endcase
            end
    
//输入信号同步化处理
    always@(posedge clk)
        if(tx_start)
            r_tx_data <= tx_data;
        else
            r_tx_data <= r_tx_data;
        
//波特率计数器使能信号设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            en_baud_cnt <= 1'd0;
        else if(tx_start)
            en_baud_cnt <= 1'd1;
        else if((bit_cnt == 4'd9)&&(baud_cnt == BAUD_MCNT))
            en_baud_cnt <= 1'd0;
        else 
            en_baud_cnt <= en_baud_cnt;
        
//波特率计数器模块设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            baud_cnt <= 16'd0;
        else if(!en_baud_cnt)
            baud_cnt <= 16'd0;
        else if(baud_cnt == BAUD_MCNT)
            baud_cnt <= 16'd0;
        else 
            baud_cnt <= baud_cnt + 16'd1;
            
//位计数器模块设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)    
            bit_cnt <= 4'd0;
        else if((baud_cnt == BAUD_MCNT) && (bit_cnt == 4'd9))
            bit_cnt <= 4'd0;
        else if(baud_cnt == BAUD_MCNT)
            bit_cnt <= bit_cnt + 4'd1;
        else 
            bit_cnt <= bit_cnt;
            
//tx输出序列机设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            tx <= 1'd1;
        else if(!en_baud_cnt)
            tx <= 1'd1;
        else if(baud_cnt == 16'd1)begin
            case(bit_cnt)
                4'd0:   tx <= 1'd0;
                4'd1:   tx <= r_tx_data[0];
                4'd2:   tx <= r_tx_data[1];
                4'd3:   tx <= r_tx_data[2];
                4'd4:   tx <= r_tx_data[3];
                4'd5:   tx <= r_tx_data[4];
                4'd6:   tx <= r_tx_data[5];
                4'd7:   tx <= r_tx_data[6];
                4'd8:   tx <= r_tx_data[7];
                4'd9:   tx <= 1'd1;
                default:tx <= 1'd1;
            endcase
        end
        else 
            tx <= tx;
            
//tx_done信号设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            tx_done <= 1'd0;
        else if((baud_cnt == BAUD_MCNT) && (bit_cnt == 4'd9))
            tx_done <= 1'd1;
        else 
            tx_done <= 1'd0;
       
endmodule

(3)串口发送模块仿真代码:

`timescale 1ns / 1ps

module rs232_tx_tb;

reg     [16:0]      baud_set    ; 
reg                 clk         ;     
reg                 reset_n     ;
reg     [7:0]       tx_data     ;  
reg                 tx_start    ;

wire                tx          ;
wire                tx_done     ;

initial clk = 1'd1;
always #10 clk = ~clk;

initial begin
    baud_set <= 17'd9600;
    reset_n <= 1'd0;
    tx_data <= 1'd0;
    tx_start <= 1'd0;
    #21;
    reset_n <= 1'd1;
    #40;
    @(posedge clk);
    //输入数据0
    tx_data <= 8'd0;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据1
    tx_data <= 8'd1;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据2
    tx_data <= 8'd2;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据3
    tx_data <= 8'd3;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据4
    tx_data <= 8'd4;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据5
    tx_data <= 8'd5;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据6
    tx_data <= 8'd6;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    //输入数据7
    tx_data <= 8'd7;
    tx_start <= 1'd1;
    #20;
    tx_start <= 1'd0;
    #(5208 * 20 * 10);
    $stop;
end

rs232_tx rs232_tx_inst
(
    .baud_set       ( baud_set)        ,
    .clk            ( clk     )        ,
    .reset_n        ( reset_n )        ,
    .tx_data        ( tx_data )        ,
    .tx_start       ( tx_start)        ,
    
    .tx             ( tx      )        ,
    .tx_done        ( tx_done )           
    
);

endmodule

(4)仿真波形:

同时,可以看见,tx一开始被赋予了高电平,在波特计数器计数为1,起始位时被拉低。

相关推荐

  1. 【国产MCU】-CH32V307-通用同步/异步收发USART

    2024-07-15 20:02:05       45 阅读
  2. STM32F103RC使用HAL库配置USART进行数据收发

    2024-07-15 20:02:05       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 20:02:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 20:02:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 20:02:05       58 阅读
  4. Python语言-面向对象

    2024-07-15 20:02:05       69 阅读

热门阅读

  1. PYTHON 常用算法 33个

    2024-07-15 20:02:05       17 阅读
  2. k8s集群创建devops项目一直等待状态,没有发现host

    2024-07-15 20:02:05       21 阅读
  3. C++:异常

    2024-07-15 20:02:05       21 阅读
  4. C++的模板(十一):算法的轨迹

    2024-07-15 20:02:05       20 阅读
  5. goframe 之ORM链式封装

    2024-07-15 20:02:05       23 阅读
  6. 高通平台android的Framework开发遇到的一些问题总结

    2024-07-15 20:02:05       20 阅读
  7. 第六章 动画【Android基础学习】

    2024-07-15 20:02:05       18 阅读
  8. 【爬虫】爬虫基础

    2024-07-15 20:02:05       19 阅读
  9. CSS 技巧与案例详解:开篇介绍

    2024-07-15 20:02:05       21 阅读
  10. 力扣刷题之2732.找到矩阵中的好子集

    2024-07-15 20:02:05       21 阅读
  11. golang基础用法

    2024-07-15 20:02:05       18 阅读
  12. shell脚本传参调用http接口

    2024-07-15 20:02:05       17 阅读