串口通信与FPGA

一、什么是串口(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信号,表示接收完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值