一、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
微信掃一掃
支付寶掃一掃