Lovewen1314

串口通讯协议

1
阅读(2527)

串口通讯协议

1.  什么是UART?

UART : Universal Asynchronous Receiver Transmiter ,通用异步收发器

2.       UART的内容是什么?

异步协议一帧数据的格式如图10-3所示。

异步协议的特点是一个字符一个字符地传输,而且每传送一个字符都是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有1位起始位(低电平,逻辑值0),字符本身由5~8位数据位组成,数据有效位后面是1位校验位,也可以无校验位,最后是停止位,停止位宽度为1位、1.5位或2位,停止位后面是不定长度的空闲位。停止位和空闲位都规定为高电平(逻辑1),这样就保证起始位开始处一定有一个下跳沿。这种格式是靠起始位和停止位来实现字符的界定或同步的,故称为起止式协议。

UART通信协议是用来进行通信的,那么肯定有接收端发送端。在UART通信协议中,接收端和发送端只是两个设备,它们可以互为接收端和发送端。这就涉及到UART通信的硬件知识。

UART通信时,通常只用到三根线,分别为RXD、TXD、GND,即接收端、发送端、地。

1 UART通信硬件常用接法 

当设备1作为发送设备时,设备2就是接收设备,反之设备2作为发送设备时,设备1就是接收设备。当然,这两个动作可以是同时的,即设备可以同时发送和接收。

现假设设备1是发送设备,设备2是接收设备。设备1首先发送一个起始位,然后发送八位数据位,最后发送一位停止位。当设备2检测到设备1发送的起始位时就准备接收数据,然后接收八位数据位。

由于设备1和设备2是异步通信,设备1和设备2必定要以相同的速率进行发送和接收数据。这个相同的速率就是波特率。即首先在设备1上设置好一个波特率,然后在设备2上设置好相同的波特率,这样就能保证设备1和设备2进行数据传输时能够以相同的速度进行发送和接收数据。

波特率,波特率是指每秒传输的符号数。

现在选择一倍的波特率。

1.      怎么触发发送模块发送数据

发送模块流程图:

           当发送模块可以发送数据的时候,TXD首先在波特率的节拍下,分别发送起始位(0)、数据位、结束位(1)。

           然后发送模块什么时候开始发送数据呢,当需要发送数据的时候。那么发送模块怎么知道什么时候可以发送数据呢?因此,我们不得不在发送模块中先加一个使能端。因此暂时可以得出发送模块的引脚连接如下图所示。


定义好了输入输出之后下面就可以开始写程序了。

 

发送部分程序如下:

module txd(clk,rst_n,baud_clk,data_in,send_en,txd,baud_en);

    input   clk;

    input   rst_n;

    input   baud_clk;

    input [7:0]   data_in;

    input   send_en;

    output   txd;

    output   baud_en;

   

    reg [7:0]   data_send;

    reg [3:0]   send_cnt;

    reg   txd;

    reg   baud_en;

   

    always@(posedge   clk or negedge   rst_n)

        if(!rst_n)

              data_send<=8'b0;

        else if(send_en)

              data_send<=data_in;

 

    always@(posedge   clk or negedge   rst_n)

        if(!rst_n)

              baud_en<=1'b0;

        else if(send_en)

              baud_en<=1'b1;

        else if(send_cnt==4'd9)

              baud_en<=1'b0;

   

    always@(posedge   clk or negedge   rst_n)

        if(!rst_n)

              send_cnt<=4'd0;

        else if(baud_clk)

            begin

            if(send_cnt==4'd9)

              send_cnt<=4'b0;

            else

              send_cnt<=send_cnt+1'b1;

            end

           

   

    always@(posedge   clk )

        if(baud_clk)

                

                case(send_cnt)

                      4'd0:txd <= 1'b0;

                      4'd1:txd <=   data_send[0];

                      4'd2:txd <=   data_send[1];

                      4'd3:txd <=   data_send[2];

                      4'd4:txd <=   data_send[3];

                      4'd5:txd <=   data_send[4];

                      4'd6:txd <=   data_send[5];

                      4'd7:txd <=   data_send[6];

                      4'd8:txd <=   data_send[7];

                      4'd9:txd <= 1'b1;

                default:txd   <= 1'b1;

                endcase

               

endmodule    

 

        波特率部分程序如下所示:

module baud_generator(clk,rst_n,baud_en,baud_clk);

    input clk;

    input rst_n;

    input baud_en;

    output baud_clk;

   

    reg baud_clk;

    reg [8:0] baud_cnt;

   

    always@(posedge clk or negedge rst_n)

        if(!rst_n)

            baud_cnt<=9'b0;

        else if(baud_en)

            begin

                if(baud_cnt==9'd433)

                baud_cnt<=9'd0;

                else   

                baud_cnt<=baud_cnt+1'b1;;

            end

   

    always@(posedge clk or negedge rst_n)

        if(!rst_n)

           baud_clk<=1'b0;

        else if(baud_cnt==1'b1)

            baud_clk<=1'b1;

        else

            baud_clk<=1'b0;

 

    endmodule

                                   

顶层文件

module uart(clk,rst_n,txd);

    input clk;

    input rst_n;

    output txd;

   

    wire baud_en;

    wire baud_clk;

   

    reg send_en;

    reg [7:0] data_in;

    reg [1:0] cnt;

   

    always@(posedge clk or negedge rst_n)

        if(!rst_n)

        begin

            cnt<=2'b0;

        end

        else

            begin

            if(cnt==2'd2)

                cnt<=cnt;

            else

                cnt<=cnt+1'b1;

            end

   

    always@(posedge clk or negedge rst_n)

        if(!rst_n)

            begin

            send_en<=1'b0;

            data_in<=8'b0;

            end

        else if(cnt<=2'b1)

            begin

            send_en<=1'b1;

            data_in<=8'b1101_1010;

            end

        else

            begin

            send_en<=1'b1;

            data_in<=8'b1101_1010;

            end

   

    txd u_txd(

                    .clk(clk),

                    .rst_n(rst_n),

                    .baud_clk(baud_clk),

                    .data_in(data_in),

                    .send_en(send_en),

                    .txd(txd),

                    .baud_en(baud_en)

                    );

   

    baud_generator   u_baud_generator(

                                                .clk(clk),

                                                .rst_n(rst_n),

                                                .baud_en(baud_en),

                                                .baud_clk(baud_clk)

                                                );

        endmodule