FPGA串口发送代码分享

来源:互联网 发布:python class 自己 编辑:程序博客网 时间:2024/06/05 23:40

module uart_tx(

    clk,            /*系统时钟*/

    rst_n,      /*系统复位*/

    data_byte,  /*待传输8bit*/

    send_en,        /*发送使能信号*/

    baud_set,   /*波特率设置*/

   

    rs232_tx,   /*rs232信号输出*/

    tx_down,        /*发送结束信号*/

    uart_state  /*发送状态*/

    );

 

    input clk;                  /*系统时钟*/

    input rst_n;                /*系统复位*/

    input[7:0]data_byte;       /*待传输8bit*/

    inputsend_en;              /*发送使能信号*/

    input[2:0]baud_set;        /*波特率设置*/

   

    output regrs232_tx;        /*rs232信号输出*/

    output regtx_down;     /*发送结束信号*/

    output reguart_state;  /*发送状态*/

   

    reg bps_clk;            /*待发送bit位计数器控制器*/

    reg[15:0]div_cnt;      /*分频计数器*/

    reg[15:0]bps_DR;       /*分频计数最大值*/

    reg[3:0]bps_cnt;       /*待发送bit位计数器*/

    reg[7:0]r_db;          /*待传输8bit数数据寄存*/

   

    localparamSTART_BIT = 1'b0;  /*起始位*/

    localparamSTOP_BIT = 1'b1;   /*停止位*/

   

 

    /*************************波特率设置部分******************/

    /*波特率设置*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin         /*如果复位*/

            bps_DR<= 16'd5207; /*默认波特率9600*/

        end

        elsebegin

            case(baud_set)

                0:bps_DR<= 16'd5207;       /*9600*/

                1:bps_DR<= 16'd2603;       /*19200*/

                2:bps_DR<= 16'd1301;       /*38400*/

                3:bps_DR<= 16'd867;            /*57600*/

                4:bps_DR<= 16'd433;            /*115200*/

                default:bps_DR<= 16'd5207;/*默认波特率9600*/

            endcase

        end

    end

   

    /*波特率分频计数值控制*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin         /*如果系统复位*/

            div_cnt <= 16'd0;   /*分频计数器清零*/

        end

        elseif(uart_state)begin/*如果处于发送状态*/

            if(div_cnt== bps_DR)begin/*如果分频计数器计数到设置波特率计数最大值*/

                div_cnt<= 16'd0;   /*分频计数器清零*/

            end

            elsebegin

                div_cnt<= div_cnt + 16'd1;/*分频计数器计数值加加*/

            end

        end

    end

   

   

    /*********************一字节数据发送驱动部分***************/

   /*待发送一字节bit位计数器的控制器*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin     /*如果系统复位*/

            bps_clk<= 1'b0;    /*接发一字节送据bit计数器控制器置0*/

        end

        elseif(div_cnt == 16'd1)begin/*如果分频计数器值为1*/

            bps_clk<=1'b1;     /*接发一字节送据bit计数器控制器置1*/

        end

        elsebegin

            bps_clk<= 1'b0;    /*接发一字节送据bit计数器控制器置0*/

        end

    end

   

    /*待发送一字节bit位计数器*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin

            bps_cnt<= 4'd0;    /*待发送一字节bit位计数器置零*/

        end

        elseif(bps_cnt == 4'd11)begin /*一个字节的时序完成*/

            bps_cnt<= 4'd0;    /*待发送一字节bit位计数器置零*/

        end

        elseif(bps_clk)begin/*波特率时钟状态置1*/

            bps_cnt<= bps_cnt + 1'b1;/*待发送一字节bit位计数器加加*/

        end

        elsebegin

            bps_cnt<= bps_cnt; /*状态保持*/

        end

    end

   

    /*发送是否结束控制*/

    always@(posedgeclk ,negedge rst_n)begin

        if(!rst_n)begin     /*如果复位*/

            tx_down= 1'b0; /*发送未完成*/

        end

        elseif(bps_cnt == 4'd11)begin/*一个字节的时序完成*/

            tx_down= 1'b1; /*发送完成*/

        end

        else begin

            tx_down= 1'b0; /*发送未完成*/

        end

    end

   

    /*发送状态控制时序*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin         /*如果复位*/

            uart_state<= 1'b0; /*处于未发送状态*/

        end

        elseif(send_en)begin   /*如果发送使能*/

            uart_state<= 1'b1; /*处于发送状态*/

        end

        elseif(bps_cnt == 4'd11)begin/*一个字节的时序完成*/

            uart_state<= 1'b0; /*处于未发送状态*/

        end

    end

   

    /*将待发送数据传入一字节数据寄存器*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin         /*如果复位*/

            r_db<= 8'd0;           /*待传输数据寄存器清零*/

        end

        elseif(send_en)begin   /*如果发送使能*/

            r_db<= data_byte;      /*将待发送8bit数据送入待传输数据寄存器*/

        end

        elsebegin                  /*系统没有复位同时没有使能发送*/

            r_db= r_db;            /*待传输数据保持*/

        end

    end

   

    /*发送一个字节数据*/

    always@(posedgeclk,negedge rst_n)begin

        if(!rst_n)begin     /*如果复位*/

            rs232_tx    <= 1'b1; /*输出信号置1*/

        end

        elsebegin

            case(bps_cnt)/*一个字节发送计数时序*/

                0:rs232_tx<= 1'b1;

                1:rs232_tx<= START_BIT;

                2:rs232_tx<= r_db[0];

                3:rs232_tx<= r_db[1];

                4:rs232_tx<= r_db[2];

                5:rs232_tx<= r_db[3];

                6:rs232_tx<= r_db[4];

                7:rs232_tx<= r_db[5];

                8:rs232_tx<= r_db[6];

                9:rs232_tx<= r_db[7];

                10:rs232_tx<= STOP_BIT;

                default:rs232_tx<= 1'b1;

            endcase

        end

    end

   

   

endmodule 

原创粉丝点击