一、UART簡介
UART是通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter)的縮寫,它是一種串行通訊接口標準。相比較其他串行通信方式,UART具有性能高、成本低的優點,在單片機、嵌入式系統、計算機外圍設備中被廣泛應用。
UART使用一種異步方式,即發送數據和接收數據的時鐘不同步,通過指定數據位,停止位,奇偶校驗位等參數,可以保證數據正確無誤地傳輸。
下面我們來詳細了解一下UART的工作原理以及在Verilog中的實現。
二、UART的工作原理
UART的工作原理可以分為兩個階段:
1、發送數據
module uart_tx( input clk, //system clock input reset, //system reset input enable, //tx enable signal input [7:0] data_in, //data to be sent output tx //tx output signal ); ...... endmodule
2、接收數據
module uart_rx( input clk, //system clock input reset, //system reset input enable, //rx enable signal input rx, //rx input signal output reg [7:0] data_out, //received data output reg receive_done //receive done signal ); ...... endmodule
三、UART Verilog實現
1、發送數據實現
UART發送數據的核心是將發送的數據按照指定的協議進行封裝,然後通過TX引腳發送出去。
以下是一個基本的UART發送模塊:
module uart_tx( input clk, //system clock input reset, //system reset input enable, //tx enable signal input [7:0] data_in, //data to be sent output tx //tx output signal ); parameter BAUD_RATE = 9600 ; //波特率 parameter SYS_CLK = 50000000 ; //系統時鐘頻率 parameter TICK = SYS_CLK / BAUD_RATE ; reg [3:0] state ; //狀態機 reg [7:0] data_reg ; //數據寄存器 reg [3:0] bit_count ; //計數器 reg tx_reg ; //TX寄存器 always@(posedge clk) begin if(reset) begin state <= 4'd0 ; tx_reg <= 1'b1 ; //發送起始位 data_reg <= 8'h00 ; bit_count <= 4'd0 ; end else begin case(state) 4'd0 : begin //等待TX越過起始位 if(enable) begin state <= 4'd1 ; end end 4'd1 : begin //發送8位數據位 tx_reg <= data_in[0] ; data_reg > 1 ; bit_count <= bit_count + 4'd1 ; if(bit_count == 4'd8) begin bit_count <= 4'd0 ; state <= 4'd2 ; end end 4'd2 : begin //發送校驗位(這裡使用奇偶校驗) tx_reg <= ~(^data_in) ; bit_count <= bit_count + 4'd1 ; if(bit_count == 4'd1) begin bit_count <= 4'd0 ; state <= 4'd3 ; end end 4'd3 : begin //發送停止位 tx_reg <= 1'b0 ; bit_count <= bit_count + 4'd1 ; if(bit_count == 4'd1) begin bit_count <= 4'd0 ; state <= 4'd4 ; end end 4'd4 : begin //等待下一次發送 if(enable) begin state <= 4'd1 ; end end endcase end end assign tx = tx_reg ; endmodule
2、接收數據實現
UART接收數據的核心是按照指定協議從RX引腳接收信號,並解析出數據內容。
一個基本的UART接收模塊如下所示:
module uart_rx( input clk, //system clock input reset, //system reset input enable, //rx enable signal input rx, //rx input signal output reg [7:0] data_out, //received data output reg receive_done //receive done signal ); parameter BAUD_RATE = 9600 ; //波特率 parameter SYS_CLK = 50000000 ; //系統時鐘頻率 parameter TICK = SYS_CLK / BAUD_RATE ; reg [3:0] state ; //狀態機 reg [7:0] data_reg ; //數據寄存器 reg [3:0] bit_count ; //計數器 reg rx_reg ; //RX寄存器 reg odd_parity ; //奇校驗位判斷 always@(posedge clk) begin if(reset) begin state <= 4'd0 ; data_reg <= 8'h00 ; bit_count <= 4'd0 ; rx_reg <= 1'b1 ; //等待起始位 end else begin case(state) 4'd0 : begin //等待起始位 if(~rx & enable) begin state <= 4'd1 ; rx_reg <= rx ; data_reg <= 8'h00 ; bit_count <= 4'd0 ; odd_parity <= 1'b0 ; end end 4'd1 : begin //接收8位數據位 rx_reg <= rx ; data_reg <= {data_reg[6:0], rx} ; bit_count <= bit_count + 4'd1 ; odd_parity <= odd_parity ^ rx ; //奇偶校驗 if(bit_count == 4'd7) begin state <= 4'd2 ; end end 4'd2 : begin //接收校驗位(這裡使用奇偶校驗) rx_reg <= rx ; odd_parity <= odd_parity ^ rx ; //奇偶校驗 bit_count <= bit_count + 4'd1 ; if(bit_count == 4'd1) begin state <= 4'd3 ; end end 4'd3 : begin //接收停止位 rx_reg <= rx ; receive_done <= 1'b1 ; //數據接收完成 data_out <= data_reg ; //輸出數據 if(rx) begin //停止位必須是邏輯0,否則認為停止位錯誤 state <= 4'd4 ; end end 4'd4 : begin //等待下一次數據接收 receive_done <= 1'b0 ; if(~rx & enable) begin state <= 4'd1 ; rx_reg <= rx ; data_reg <= 8'h00 ; bit_count <= 4'd0 ; odd_parity <= 1'b0 ; end end endcase end end endmodule
四、小結
本文主要介紹了UART通訊的基本原理,以及在Verilog中的實現方式。通過實現發送和接收兩個模塊,我們可以完成對UART通訊協議的實現。同時,我們也需要注意一些細節問題,如如何進行奇偶校驗,如何判斷起始位和停止位等等。這些問題對於保證數據傳輸的正確性非常重要。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/309896.html