1.简介
(1)UART一种通用异步串口数据总线,最低采用两路信号(TX/RX)即可实现全双工通信,十分简单;
(2)UART采用LSB模式传输,串口数据传输格式如下图所示:
起始位:长度为1位的时间,用于表示发送字符的开始;
数据位:长度长度不固定,一般是8位;
校验位:可以加也可以不加。
停止位:一般是1位、1.5位、2位长度,用于告知接收端字符传输结束;
(3)每个字符的发送都需要有起始位和停止位,对于连续数据也是如此;
2.内部结构
3.实现
发送模块代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 module uart_tx_path # 2 ( 3 parameter BAUD_DIV = 13'd9, //baud 4 parameter BAUD_DIV_CAP = 13'd4 //baud capture point 5 ) 6 ( 7 input clk, //main clk 8 input rst_n, //reset 9 input uart_tx_en, //send one byte data enable 10 input[7:0] uart_tx_byte, //one byte data 11 output uart_txd, //the txd pin 12 output uart_tx_done //send one byte data done 13 ); 14 15 //------------------------- Baud rate generator ------------------------- 16 reg[12:0] cnt_baud_div; 17 reg baud_cap; 18 reg baud_start; 19 20 always@(posedge clk or negedge rst_n) 21 begin 22 if(!rst_n) begin 23 cnt_baud_div <= 13'd0; 24 end 25 else begin 26 if(baud_start) begin 27 if(cnt_baud_div >= BAUD_DIV) begin 28 cnt_baud_div <= 13'd0; 29 end 30 else begin 31 cnt_baud_div <= cnt_baud_div + 1'b1; 32 end 33 end 34 else begin 35 cnt_baud_div <= 13'd0; 36 end 37 end 38 end 39 40 always@(posedge clk or negedge rst_n) 41 begin 42 if(!rst_n) begin 43 baud_cap <= 1'b0; 44 end 45 else begin 46 if(cnt_baud_div==BAUD_DIV_CAP) begin 47 baud_cap <= 1'b1; 48 end 49 else begin 50 baud_cap <= 1'b0; 51 end 52 end 53 end 54 55 //-------------------------capture the uart_tx_en posedge------------------------- 56 reg uart_tx_en_r0,uart_tx_en_r1; 57 wire uart_tx_en_p; 58 59 always@(posedge clk or negedge rst_n) 60 begin 61 if(!rst_n) begin 62 uart_tx_en_r0 <= 1'b0; //uart_tx_en of the idle state is low 63 uart_tx_en_r1 <= 1'b0; 64 end 65 else begin 66 uart_tx_en_r0 <= uart_tx_en; 67 uart_tx_en_r1 <= uart_tx_en_r0; 68 end 69 end 70 71 assign uart_tx_en_p = (~uart_tx_en_r1 & uart_tx_en_r0)? 1'b1:1'b0; //capture the uart_tx_en posedge 72 73 //------------------------- capture the txd data ------------------------- 74 localparam TX_IDLE = 1'b0; 75 localparam TX_WORK = 1'b1; 76 77 reg state_tx; 78 reg uart_tx_done_r; 79 reg[9:0] send_data; 80 reg[3:0] tx_bit; 81 82 always@(posedge clk or negedge rst_n) 83 begin 84 if(!rst_n) begin 85 state_tx <= TX_IDLE; 86 send_data <= 10'b1111_1111_11; 87 uart_tx_done_r <= 1'b0; 88 end 89 else begin 90 case(state_tx) 91 TX_IDLE: if(uart_tx_en_p) begin 92 baud_start <= 1'b1; 93 send_data <= {1'b1,uart_tx_byte,1'b0}; 94 state_tx <= TX_WORK; 95 uart_tx_done_r <= 1'b0; 96 end 97 else begin 98 baud_start <= 1'b0; 99 send_data <= 10'b1111_1111_11; 100 state_tx <= TX_IDLE; 101 uart_tx_done_r <= 1'b0; 102 end 103 TX_WORK: if(tx_bit == 4'd10) begin 104 baud_start <= 1'b1; 105 send_data <= 10'b1111_1111_11; 106 state_tx <= TX_WORK; 107 uart_tx_done_r <= 1'b0; 108 end 109 else if(tx_bit>=4'd11) begin 110 baud_start <= 1'b0; 111 send_data <= 10'b1111_1111_11; 112 state_tx <= TX_IDLE; 113 uart_tx_done_r <= 1'b1; 114 end 115 else begin 116 baud_start <= 1'b1; 117 send_data <= send_data; 118 state_tx <= TX_WORK; 119 uart_tx_done_r <= 1'b0; 120 end 121 default: ; 122 endcase 123 end 124 end 125 //------------------------- the uart txd work ------------------------- 126 reg uart_txd_r; 127 128 always@(posedge clk or negedge rst_n) 129 begin 130 if(!rst_n) begin 131 uart_txd_r <= 1'b1; //uart_txd of the idle state is high 132 tx_bit <= 4'd0; 133 end 134 else begin 135 if(state_tx == TX_WORK) begin 136 if(baud_cap) begin 137 if (tx_bit <= 4'd9) 138 uart_txd_r <= send_data[tx_bit]; 139 else 140 uart_txd_r <= 1'b1; 141 tx_bit <= tx_bit + 1'b1; 142 end 143 else begin 144 uart_txd_r <= uart_txd_r; 145 tx_bit <= tx_bit; 146 end 147 end 148 else begin 149 uart_txd_r <= 1'b1; 150 tx_bit <= 4'd0; 151 end 152 end 153 end 154 155 assign uart_tx_done = uart_tx_done_r; 156 assign uart_txd = uart_txd_r; 157 158 endmodule
接收模块代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 module uart_rx_path # 2 ( 3 parameter BAUD_DIV = 13'd9, //baud 4 parameter BAUD_DIV_CAP = 13'd4 //baud capture point 5 ) 6 ( 7 input clk, //main clk 8 input rst_n, //reset 9 input uart_rxd, //the rxd pin 10 output uart_rx_done, //receive one byte data done 11 output[7:0] uart_rx_byte //one byte data 12 ); 13 14 //------------------------- Baud rate generator ------------------------- 15 reg[12:0] cnt_baud_div; 16 reg baud_cap; 17 reg baud_start; 18 19 always@(posedge clk or negedge rst_n) 20 begin 21 if(!rst_n) begin 22 cnt_baud_div <= 13'd0; 23 end 24 else begin 25 if(baud_start) begin 26 if(cnt_baud_div >= BAUD_DIV) begin 27 cnt_baud_div <= 13'd0; 28 end 29 else begin 30 cnt_baud_div <= cnt_baud_div + 1'b1; 31 end 32 end 33 else begin 34 cnt_baud_div <= 13'd0; 35 end 36 end 37 end 38 39 40 41 always@(posedge clk or negedge rst_n) 42 begin 43 if(!rst_n) begin 44 baud_cap <= 1'b0; 45 end 46 else begin 47 if(cnt_baud_div==BAUD_DIV_CAP) begin 48 baud_cap <= 1'b1; 49 end 50 else begin 51 baud_cap <= 1'b0; 52 end 53 end 54 end 55 56 //------------------------- capture the uart start bit ------------------------- 57 reg uart_rxd_r0,uart_rxd_r1,uart_rxd_r2,uart_rxd_r3; 58 wire uart_rxd_n; 59 60 always@(posedge clk or negedge rst_n) 61 begin 62 if(!rst_n) begin 63 uart_rxd_r0 <= 1'b1; //uart_rxd of the idle state is high 64 uart_rxd_r1 <= 1'b1; 65 uart_rxd_r2 <= 1'b1; 66 uart_rxd_r3 <= 1'b1; 67 end 68 else begin 69 uart_rxd_r0 <= uart_rxd; 70 uart_rxd_r1 <= uart_rxd_r0; 71 uart_rxd_r2 <= uart_rxd_r1; 72 uart_rxd_r3 <= uart_rxd_r2; 73 end 74 end 75 76 assign uart_rxd_n = (uart_rxd_r3 & uart_rxd_r2 & ~uart_rxd_r1 & ~uart_rxd_r0)? 1'b1 : 1'b0; //capture the uart_rxd negedge 77 78 79 //------------------------- the uart rxd work ------------------------- 80 localparam[3:0] UART_IDLE = 4'd0; //IDLE 81 localparam[3:0] UART_START= 4'd1; //START BIT 82 localparam[3:0] UART_BIT0 = 4'd2; //BIT0 83 localparam[3:0] UART_BIT1 = 4'd3; //BIT1 84 localparam[3:0] UART_BIT2 = 4'd4; //BIT2 85 localparam[3:0] UART_BIT3 = 4'd5; //BIT3 86 localparam[3:0] UART_BIT4 = 4'd6; //BIT4 87 localparam[3:0] UART_BIT5 = 4'd7; //BIT5 88 localparam[3:0] UART_BIT6 = 4'd8; //BIT6 89 localparam[3:0] UART_BIT7 = 4'd9; //BIT7 90 localparam[3:0] UART_STOP = 4'd10; //STOP BIT 91 92 reg[3:0] state_rx; 93 reg uart_rx_done_r; 94 reg[7:0] uart_rx_byte_r0; 95 reg[7:0] uart_rx_byte_r1; 96 97 always@(posedge clk or negedge rst_n) 98 begin 99 if(!rst_n) begin 100 state_rx <= UART_IDLE; 101 uart_rx_done_r <= 1'b0; 102 uart_rx_byte_r0 <= 8'd0; 103 uart_rx_byte_r1 <= 8'd0; 104 baud_start <= 1'b0; 105 end 106 else begin 107 case(state_rx) 108 UART_IDLE: if(uart_rxd_n) begin 109 uart_rx_done_r <= 1'b0; 110 baud_start <= 1'b1; 111 state_rx <= UART_START; 112 end 113 else begin 114 uart_rx_done_r <= 1'b0; 115 baud_start <= 1'b0; 116 state_rx <= UART_IDLE; 117 end 118 UART_START: if(baud_cap) begin 119 state_rx <= UART_BIT0; 120 end 121 else begin 122 state_rx <= UART_START; 123 end 124 UART_BIT0: if(baud_cap) begin 125 uart_rx_byte_r0[0] <= uart_rxd; 126 state_rx <= UART_BIT1; 127 end 128 else begin 129 uart_rx_byte_r0 <= uart_rx_byte_r0; 130 state_rx <= UART_BIT0; 131 end 132 UART_BIT1: if(baud_cap) begin 133 uart_rx_byte_r0[1] <= uart_rxd; 134 state_rx <= UART_BIT2; 135 end 136 else begin 137 uart_rx_byte_r0 <= uart_rx_byte_r0; 138 state_rx <= UART_BIT1; 139 end 140 UART_BIT2: if(baud_cap) begin 141 uart_rx_byte_r0[2] <= uart_rxd; 142 state_rx <= UART_BIT3; 143 end 144 else begin 145 uart_rx_byte_r0 <= uart_rx_byte_r0; 146 state_rx <= UART_BIT2; 147 end 148 UART_BIT3: if(baud_cap) begin 149 uart_rx_byte_r0[3] <= uart_rxd; 150 state_rx <= UART_BIT4; 151 end 152 else begin 153 uart_rx_byte_r0 <= uart_rx_byte_r0; 154 state_rx <= UART_BIT3; 155 end 156 UART_BIT4: if(baud_cap) begin 157 uart_rx_byte_r0[4] <= uart_rxd; 158 state_rx <= UART_BIT5; 159 end 160 else begin 161 uart_rx_byte_r0 <= uart_rx_byte_r0; 162 state_rx <= UART_BIT4; 163 end 164 UART_BIT5: if(baud_cap) begin 165 uart_rx_byte_r0[5] <= uart_rxd; 166 state_rx <= UART_BIT6; 167 end 168 else begin 169 uart_rx_byte_r0 <= uart_rx_byte_r0; 170 state_rx <= UART_BIT5; 171 end 172 UART_BIT6: if(baud_cap) begin 173 uart_rx_byte_r0[6] <= uart_rxd; 174 state_rx <= UART_BIT7; 175 end 176 else begin 177 uart_rx_byte_r0 <= uart_rx_byte_r0; 178 state_rx <= UART_BIT6; 179 end 180 UART_BIT7: if(baud_cap) begin 181 uart_rx_byte_r0[7] <= uart_rxd; 182 state_rx <= UART_STOP; 183 end 184 else begin 185 uart_rx_byte_r0 <= uart_rx_byte_r0; 186 state_rx <= UART_BIT7; 187 end 188 UART_STOP: if(baud_cap) begin 189 uart_rx_done_r <= 1'b1; 190 uart_rx_byte_r1 <= uart_rx_byte_r0; 191 baud_start <= 1'b0; 192 state_rx <= UART_IDLE; 193 end 194 else begin 195 uart_rx_done_r <= 1'b0; 196 uart_rx_byte_r1 <= uart_rx_byte_r1; 197 baud_start <= 1'b1; 198 state_rx <= UART_STOP; 199 end 200 default: state_rx <= UART_IDLE; 201 endcase 202 end 203 end 204 205 assign uart_rx_done = uart_rx_done_r; 206 assign uart_rx_byte = uart_rx_byte_r1; 207 endmodule
4.参考资料
《通信IC设计》 李庆华著