CrazyBingo

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

0
阅读(12853)

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竟然可以发送成功!

Baidu
map