uart的具体实现代码

来源:互联网 发布:nba张伯伦数据 编辑:程序博客网 时间:2024/05/22 10:45

1.

module  speed_setting(    input   clk,    input   rst_n,    input   bps_start,    output  clk_bps);`define BPS_9600`define CLK_PERIOD  40  //  时钟周期为40ns(25MHZ)`define BPS_SET     96`define BPS_PA  (10_000_000/`CLK_PERIOD/`BPS_SET)   //10_000_000/`CLK_PERIORD/96;       //波特率为9600时的分频计数值                                                                                                       //  1s=1000_000_000ns       上下同时约去个100就变成250000/96`define BPS_PA_2    (`BPS_PA/2) //BPS分频计数的1/2reg [12:0]      cnt;reg clk_bps_r;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)      cnt <=  13'd0;    else    if(cnt  ==  `BPS_PA ||  !bps_start) cnt <=  13'd0;    else    cnt <=  cnt +   1'b1;endalways@(posedge clk or  negedge rst_n)begin    if(!rst_n)      clk_bps_r   <=  1'b0;    else    if(cnt  ==  `BPS_PA_2)  clk_bps_r   <=  1'b1;    else    clk_bps_r   <=  1'b0;endassign  clk_bps =       clk_bps_r;endmodule

2.

//拿到一个多位数据 即并行数据    通过uart_tx端口串行输出module  my_uart_tx(    input   clk,    input   rst_n,    input   clk_bps,//等同于clk_div    input   rx_int,//对方的接收反馈,接收过程中正常高电平,结束或者异常低电平    output  reg bps_start,//波特率的复位    input   [7:0]   rx_data,//拿到的并行数据    output  uart_tx//串行输出端口);//----------------------------------//对rx_int的滤波reg rx_int0,rx_int1,rx_int2;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)  begin        rx_int0 <=  1'b0;        rx_int1 <=  1'b0;        rx_int2 <=  1'b0;    end    else    begin        rx_int0 <=  rx_int;        rx_int1 <=  rx_int0;        rx_int2 <=  rx_int1;    endendwire    nege_edge   =       rx_int2 &   ~rx_int1;  //当对方把数据发送完,捕捉其标志位的下降沿//----------------------------------------------------//设置相关使能,将接收到的并行数据存储用于下一步 串行发出reg tx_en;reg [7:0]   tx_data;reg [3:0]   num;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)  begin        tx_en   <=  1'b0;        tx_data <=  8'd0;        bps_start   <=  1'b0;    end    else    if(nege_edge)begin        tx_en   <=  1'b1;        tx_data <=  rx_data;        bps_start   <=  1'b1;    end    else    if(num  ==  4'd10)begin        tx_en   <=  1'b0;        bps_start   <=  1'b0;    endend//-------------------------------------------------------//把并行的数据拆开一拍发一位reg uart_tx_r;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)  begin        uart_tx_r   <=  1'b0;        num <=  1'b0;    end    else    if(tx_en)begin        if(clk_bps)begin            num <=  num +   1'b1;            case(num)                4'd0: uart_tx_r <= 1'b0;    //发送起始位                4'd1: uart_tx_r <= tx_data[0];  //发送bit0                4'd2: uart_tx_r <= tx_data[1];  //发送bit1                4'd3: uart_tx_r <= tx_data[2];  //发送bit2                4'd4: uart_tx_r <= tx_data[3];  //发送bit3                4'd5: uart_tx_r <= tx_data[4];  //发送bit4                4'd6: uart_tx_r <= tx_data[5];  //发送bit5                4'd7: uart_tx_r <= tx_data[6];  //发送bit6                4'd8: uart_tx_r <= tx_data[7];  //发送bit7                4'd9: uart_tx_r <= 1'b1;    //发送结束位                default: uart_tx_r <= 1'b1;            endcase        end    end    else    if(num  ==  4'd10)begin        num <=  4'd0;    endendassign  uart_tx =       uart_tx_r;endmodule

3.

//接收到一个串行端口传来的数据,存下来 存够约定的位数后一次输出       即串行变并行module  my_uart_rx(    input   clk,    input   rst_n,    input   uart_rx,    input   clk_bps,    output  reg bps_start,  //波特率启动和复位高 电平有效    output  [7:0]   rx_data,    output  reg rx_int  //  标志位 用来表示正在接收数据  高电平         接收中断或结束为低电平);//----------------------------------------------------------------------//本部分将  uart_rx 接收进来的信号进行滤波reg uart_rx0,uart_rx1,uart_rx2,uart_rx3;    //用来滤波always@(posedge clk or  negedge rst_n)begin    if(!rst_n)      begin        uart_rx0    <=  1'b0;        uart_rx1    <=  1'b0;        uart_rx2    <=  1'b0;        uart_rx3    <=  1'b0;    end    else    begin        uart_rx0    <=  uart_rx;        uart_rx1    <=  uart_rx0;        uart_rx2    <=  uart_rx1;        uart_rx3    <=  uart_rx2;    endendwire    nege_edge   =       uart_rx3        &   uart_rx2        &   ~uart_rx1  &   ~uart_rx0;//----------------------------------------------------------------//bps_start 和   rx_int的控制reg[3:0]    num;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)      begin        bps_start   <=  1'b0;        rx_int  <=  1'b0;    end    else    if(nege_edge)begin        bps_start   <=  1'b1;        rx_int  <=  1'b1;    end    else    if(num  ==  4'd9)begin        bps_start   <=  1'b0;        rx_int  <=  1'b0;    endend//--------------------------------------------------------//把串行的uart_rx进来的数据变成并行//其实就是把uart_rx一拍一拍进来的存进寄存器中//然后以输出8位reg[7:0]    rx_temp_data,rx_data_r;always@(posedge clk or  negedge rst_n)begin    if(!rst_n)  begin        rx_temp_data    <=  8'd0;        rx_data_r   <=  8'd0;        num <=  4'd0;    end    else    if(rx_int)begin        if(clk_bps)begin            num <=  num +   1'b1;            case(num)                4'd1: rx_temp_data[0] <= uart_rx;   //锁存第0bit                4'd2: rx_temp_data[1] <= uart_rx;   //锁存第1bit                4'd3: rx_temp_data[2] <= uart_rx;   //锁存第2bit                4'd4: rx_temp_data[3] <= uart_rx;   //锁存第3bit                4'd5: rx_temp_data[4] <= uart_rx;   //锁存第4bit                4'd6: rx_temp_data[5] <= uart_rx;   //锁存第5bit                4'd7: rx_temp_data[6] <= uart_rx;   //锁存第6bit                4'd8: rx_temp_data[7] <= uart_rx;   //锁存第7bit                default: ;            endcase        end    end    else    if(num  ==  4'd9)   begin        rx_data_r   <=  rx_temp_data;        num <=  4'd0;    endendassign  rx_data =   rx_data_r;endmodule

4.

module cy4ex12_uart(            input clk_25m,  //外部输入25MHz时钟信号            input ext_rst_n,    //外部输入复位信号,低电平有效            input uart_rx,      // UART接收数据信号            output uart_tx      // UART发送数据信号        );                                                  //-------------------------------------//下面的四个模块中,speed_rx和speed_tx是两个完全独立的硬件模块,可称之为逻辑复制//(不是资源共享)wire bps_start1,bps_start2; //接收到数据后,波特率时钟启动信号置位wire clk_bps1,clk_bps2;     // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点 wire[7:0] rx_data;  //接收数据寄存器,保存直至下一个数据来到wire rx_int;        //接收数据中断信号,接收到数据期间始终为高电平    //UART接收信号波特率设置speed_setting       speed_rx(                               .clk(clk_25m),  //波特率选择模块                            .rst_n(ext_rst_n),                            .bps_start(bps_start1),                            .clk_bps(clk_bps1)                        );    //UART接收数据处理my_uart_rx          my_uart_rx(                                 .clk(clk_25m),  //接收数据模块                            .rst_n(ext_rst_n),                            .uart_rx(uart_rx),                            .clk_bps(clk_bps1),                            .bps_start(bps_start1),                            .rx_data(rx_data),                            .rx_int(rx_int)                        );//-------------------------------------    //UART发送信号波特率设置                                                 speed_setting       speed_tx(                               .clk(clk_25m),  //波特率选择模块                            .rst_n(ext_rst_n),                            .bps_start(bps_start2),                            .clk_bps(clk_bps2)                        );    //UART发送数据处理my_uart_tx          my_uart_tx(                                 .clk(clk_25m),  //发送数据模块                            .rst_n(ext_rst_n),                            .clk_bps(clk_bps2),                            .rx_int(rx_int),                            .bps_start(bps_start2),                            .rx_data(rx_data),                            .uart_tx(uart_tx)                        );endmodule

这里写图片描述

原创粉丝点击