CrazyBingo

UART串口收发协议以及时序分析

0
阅读(13264)

UART串口收发协议以及时序分析

/**************************************************************************

.......IDLE.Start................................UART DATA..................................End...IDLE...

________                                                                                           ______________

              |____< D0 >< D1 >< D2 >< D3 >< D4 >< D5 >< D6 >< D7 >

Bit0  Bit1  Bit2  Bit3  Bit4  Bit5  Bit6  Bit7  Bit08  Bit9

**************************************************************************/

wps_clip_image-18787

1. 任意分频实现精确波特率

详见:http://blog.chinaaet.com/detail/21535.html

\发送&接收数据时序图

wps_clip_image-19222

2. 串口数据接收时序分析:

wps_clip_image-3169

(1)状态机:R_IDLE; R_START; R_SAMPLE; R_STOP

//---------------------------------------

//parameter of uart transfer

localparam R_IDLE = 2'd0; //detect if the uart data is begin

localparam R_START = 2'd1; //uart transfert start mark bit

localparam R_SAMPLE = 2'd2; //uart 8 bit data receive

localparam R_STOP = 2'd3; //uart transfer stop mark bit

reg [1:0] rxd_state;


wps_clip_image-21209

(2)数据采样在smp_cnt==7即数据中点!


//----------------------------------
//uart data receive in center point
reg	[7:0]	rxd_data_r;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		rxd_data_r <= 0;
	else if(rxd_state == R_SAMPLE)
		begin
		if(clken_16bps == 1 && smp_cnt == 4'd7)	//sample center point
			case(rxd_cnt)
			4'd1:	rxd_data_r[0] <= rxd_sync;
			4'd2:	rxd_data_r[1] <= rxd_sync;
			4'd3:	rxd_data_r[2] <= rxd_sync;
			4'd4:	rxd_data_r[3] <= rxd_sync;
			4'd5:	rxd_data_r[4] <= rxd_sync;
			4'd6:	rxd_data_r[5] <= rxd_sync;
			4'd7:	rxd_data_r[6] <= rxd_sync;
			4'd8:	rxd_data_r[7] <= rxd_sync;
			default:;
			endcase
		else
			rxd_data_r <= rxd_data_r;
		end
	else if(rxd_state == R_STOP)
		rxd_data_r <= rxd_data_r;
	else
		rxd_data_r <= 0;
end

(3)接收完停止标志位后:rxd_flag有效,以及rxd_data更新!

//----------------------------------
//update uart receive data and receive flag signal
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		rxd_data <= 0;
	else if(clken_16bps == 1 &&  rxd_cnt == 4'd9 && smp_cnt == 4'd15)	//Start + 8 Bit + Stop Bit
		rxd_data <= rxd_data_r;
	else
		rxd_data <= rxd_data;
end

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		rxd_flag <= 0;
	else if(clken_16bps == 1 &&  rxd_cnt == 4'd9 && smp_cnt == 4'd15)	//Start + 8 Bit + Stop Bit
		rxd_flag <= 1;
	else
		rxd_flag <= 0;
end


wps_clip_image-16222

3. 串口数据发送时序分析:

wps_clip_image-23480

(1)状态机:R_IDLE; R_SEND(R_SEND发送起始位,数据位,结束位)

//---------------------------------------

//parameter of uart transfer

localparam T_IDLE = 2'b0; //test the flag to transfer data

localparam T_SEND = 2'b1; //uart transfer data

reg [1:0] txd_state;


wps_clip_image-10892

(2)数据与rxd_cnt:0-9完全对齐,因此采用了组合逻辑输出,如下:


//--------------------------------------
//uart 8 bit data transfer
always@(*)
begin
	if(txd_state == T_SEND)
		case(txd_cnt)
		4'd0:	txd = 0;
		4'd1:	txd = txd_data[0];
		4'd2:	txd = txd_data[1];
		4'd3:	txd = txd_data[2];
		4'd4:	txd = txd_data[3];
		4'd5:	txd = txd_data[4];
		4'd6:	txd = txd_data[5];
		4'd7:	txd = txd_data[6];
		4'd8:	txd = txd_data[7];
		4'd9:	txd = 1;
		default:txd = 1;
		endcase
	else
		txd = 1'b1;	//default state
end


wps_clip_image-3097

(3)在发送完停止位后:txd_flag有效!


//-------------------------------------
//Capture the falling of data transfer over
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		txd_flag <= 0;
	else if(clken_16bps == 1 &&  txd_cnt == 4'd9 && smp_cnt == 4'd15)	//Totally 8 data is done
		txd_flag <= 1;
	else
		txd_flag <= 0;
end


4. 其他

(1)串口收发海量测试:

wps_clip_image-4169

wps_clip_image-4193

(2)收发同步时序绝对对齐,即第二个数据接受完毕的同时,第一个数据发送完毕,保持完全的滞后同步!

wps_clip_image-5265

(3)串口软件问题:

在发送字符串或者HEX长度太长的时候会出现错误,尤其是自动发送10ms,10ms时候的错误很明显,纯属软件问题!

wps_clip_image-15175

后期可以通过自行设计软件来完善,目前手动发送调试即可!

(4)很神奇的是115200的波特率但是9600竟然可以发送成功!