一、什么是串口(UART)?
1. 什么是串口通信?
串口通信(Serial Communication)是指数据通过一根或几根线按顺序(逐位)传输的一种方式。常见的串口通信有 UART(通用异步收发传输器)和 RS-232 等。
UART是串口通信中最常用的一种标准,它通过两个线来进行通信:
- TX(Transmit): 数据发送线,用于将数据从一个设备发送到另一个设备。
- RX(Receive): 数据接收线,用于接收从另一个设备发送过来的数据。
通过这两根线,两个设备可以以特定的速率(波特率)交换数据。
2. 为什么叫“串口”?
"串口"的意思是数据按顺序(一个接一个地)传输。和“并口”(多个数据位并行传输)不同,串口是逐位传输的。
二、UART的工作原理
1. 数据传输过程:
在UART通信中,数据的传输是按字节(8位)进行的。每次传输一个字节的数据时,通常会包括:
- 起始位(Start bit):通知接收方数据开始了。
- 数据位(Data bits):实际的数据,通常是8位。
- 停止位(Stop bit):通知接收方数据结束了。
比如,传输一个字节的数据0x41(对应ASCII字符A),它在物理层面上会按以下顺序传输:
| Start | Data | Stop |
- 起始位通常是 0(标记数据的开始)。
- 数据位就是8位有效数据。
- 停止位是1或2位 1(标记数据的结束)。
-
2. 异步传输:
UART是“异步”传输的意思,数据传输不需要共享时钟信号。发送和接收方通过事先约定好的波特率(Baud rate)来同步数据传输。(也就是说,我们只要发送/接收的速度一样就行,没必要一模一样的同步)常见的波特率包括9600、115200等。传输双方需要保持相同的波特率,才能正确地接收和解码数据。
三、UART的基本连接
1. 连接方式
- 在发送方(例如,微控制器、计算机等)上,有一个TX引脚用于发送数据。
- 在接收方(例如,另一个微控制器、传感器、调试工具等)上,有一个RX引脚用于接收数据。
简单的连接方式:
- 将TX连接到接收方的RX。
- 将RX连接到接收方的TX。
- 确保**地线(GND)**也连接在一起,保证电气上的参考一致。
2. UART设备之间的连接
假设有两个设备通过UART进行通信:
- 设备A的TX连接到设备B的RX;
- 设备A的RX连接到设备B的TX;
- 设备A和设备B的地线GND连接在一起。
四、配置和使用UART
1. 设置波特率
波特率(Baud Rate)是指数据传输的速率,单位是“每秒传输多少位”(bps)。例如,9600波特率表示每秒传输9600位数据。
波特率必须在通信的两端保持一致。如果发送方设置的是9600波特率,接收方也必须设置为9600波特率,才能正确接收数据。
常见的波特率包括:
- 9600
- 115200
- 19200
- 57600
- 4800等
2. 数据位、停止位、校验位
- 数据位(Data Bits):通常是8位,表示一个完整的数据字节。
- 停止位(Stop Bits):可以是1位或2位,用来标记数据的结束。
- 校验位(Parity Bit):用于检测传输过程中是否发生了错误。常见的有“无校验”、“偶校验”和“奇校验”。
通常情况下,8数据位,1停止位,未使用校验位是最常见的设置。
五、UART模块的Verilog实现
1. UART发送模块(TX)
这个模块将数据从并行格式转换为串行格式,并在给定的波特率下通过TX线发送。
module uart_tx (
input wire clk, // 时钟信号
input wire rst, // 重置信号
input wire [7:0] data_in, // 要发送的数据
input wire send, // 发送数据的触发信号
output reg tx, // 串口输出
output reg busy // 发送状态指示
);
// 状态机定义
typedef enum reg [3:0] {
IDLE = 4'b0000,
START_BIT = 4'b0001,
DATA_BITS = 4'b0010,
STOP_BIT = 4'b0100
} state_t;
reg [3:0] state, next_state;
reg [3:0] bit_counter; // 计数器,跟踪发送的位数
reg [7:0] shift_reg; // 移位寄存器,存储要发送的数据
// 状态机
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
bit_counter <= 0;
shift_reg <= 0;
tx <= 1; // 空闲时TX线为高
busy <= 0;
end else begin
state <= next_state;
if (state == DATA_BITS) begin
bit_counter <= bit_counter + 1;
shift_reg <= {1'b0, shift_reg[7:1]}; // 移位发送数据
end
end
end
// 状态转换逻辑
always @(*) begin
case (state)
IDLE: begin
if (send) begin
next_state = START_BIT;
busy = 1;
end else begin
next_state = IDLE;
busy = 0;
end
end
START_BIT: begin
next_state = DATA_BITS;
end
DATA_BITS: begin
if (bit_counter == 8) begin
next_state = STOP_BIT;
end else begin
next_state = DATA_BITS;
end
end
STOP_BIT: begin
next_state = IDLE;
end
default: next_state = IDLE;
endcase
end
// 输出逻辑
always @(state or bit_counter or shift_reg) begin
case (state)
IDLE: tx = 1; // 空闲时TX为高电平
START_BIT: tx = 0; // 发送起始位为低电平
DATA_BITS: tx = shift_reg[0]; // 发送数据位
STOP_BIT: tx = 1; // 发送停止位为高电平
default: tx = 1;
endcase
end
endmodule
2. UART接收模块(RX)
这个模块用来接收串行数据,并将其转换为并行格式。接收数据时,我们也需要一个波特率生成器来确保接收的时序正确。
module uart_rx (
input wire clk, // 时钟信号
input wire rst, // 重置信号
input wire rx, // 串口输入
output reg [7:0] data_out, // 接收到的数据
output reg received, // 数据接收完成信号
output reg busy // 接收状态指示
);
// 状态机定义
typedef enum reg [3:0] {
IDLE = 4'b0000,
START_BIT = 4'b0001,
DATA_BITS = 4'b0010,
STOP_BIT = 4'b0100
} state_t;
reg [3:0] state, next_state;
reg [3:0] bit_counter; // 计数器,跟踪接收的位数
reg [7:0] shift_reg; // 移位寄存器,存储接收到的数据
// 状态机
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
bit_counter <= 0;
shift_reg <= 0;
data_out <= 0;
received <= 0;
busy <= 0;
end else begin
state <= next_state;
if (state == DATA_BITS) begin
bit_counter <= bit_counter + 1;
shift_reg <= {rx, shift_reg[7:1]}; // 接收并移位
end
end
end
// 状态转换逻辑
always @(*) begin
case (state)
IDLE: begin
if (rx == 0) begin // 检测到起始位(低电平)时,进入接收状态
next_state = START_BIT;
busy = 1;
end else begin
next_state = IDLE;
busy = 0;
end
end
START_BIT: begin
next_state = DATA_BITS;
end
DATA_BITS: begin
if (bit_counter == 8) begin
next_state = STOP_BIT;
end else begin
next_state = DATA_BITS;
end
end
STOP_BIT: begin
next_state = IDLE;
received = 1; // 数据接收完成
data_out = shift_reg; // 保存接收到的数据
end
default: next_state = IDLE;
endcase
end
endmodule
3. 发送模块工作流程(TX)
- 当
send信号为1时,模块进入START_BIT状态,开始发送起始位(低电平)。 - 然后进入DATA_BITS状态,逐位发送数据。每发送一个数据位,计数器
bit_counter加1,直到发送完整个字节(8位)。 - 最后进入STOP_BIT状态,发送一个停止位(高电平),标志着数据发送完成。
4. 接收模块工作流程(RX)
- 接收模块在空闲状态时(IDLE)等待接收数据。当检测到RX信号为低电平时,表示接收方准备开始接收数据(起始位)。
- 进入START_BIT状态后,接收模块开始接收数据位,并将其保存在
shift_reg中。 - 当接收到8个数据位后,进入STOP_BIT状态,接收模块判断停止位(应为高电平),然后将接收到的数据传送到
data_out并发出received信号,表示接收完成。
27万+

被折叠的 条评论
为什么被折叠?



