1.简介

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

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

    【基本知识】UART接口

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

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

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

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

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

 

2.内部结构

    【基本知识】UART接口

 

 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

相关文章: