串口通讯协议
1赞串口通讯协议
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 |
