【基本知识】UART接口

1.简介

  (1)UART一种通用异步串口数据总线,最低采用两路信号(TX/RX)即可实现全双工通信,十分简单;

  (2)UART采用LSB模式传输,串口数据传输格式如下图所示:

    

    起始位:长度为1位的时间,用于表示发送字符的开始;

    数据位:长度长度不固定,一般是8位;

    校验位:可以加也可以不加。

    停止位:一般是1位、1.5位、2位长度,用于告知接收端字符传输结束;

  (3)每个字符的发送都需要有起始位和停止位,对于连续数据也是如此;

 

2.内部结构

    

 

 3.实现

   发送模块代码如下:

  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
UART_TX_PATH

   接收模块代码如下:

  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
UART_RX_PATH

 

4.参考资料

  《通信IC设计》 李庆华著

posted on 2019-06-04 10:33  要努力做超人  阅读(1999)  评论(0编辑  收藏  举报

导航