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/2



reg [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;
end

always@(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;
end

assign  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;
    end
end

wire    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;
    end
end

//-------------------------------------------------------
//把并行的数据拆开一拍发一位
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;
    end
end

assign  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;
    end
end

wire    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;
    end
end


//--------------------------------------------------------
//把串行的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;
    end
end

assign  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

android 开发部 uart 接rs485_sed