一、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 <= data_in >> 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通讯协议的实现。同时,我们也需要注意一些细节问题,如如何进行奇偶校验,如何判断起始位和停止位等等。这些问题对于保证数据传输的正确性非常重要。