0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于FPGA开发板DE23-Lite的串口通信设计

友晶FPGA 来源:友晶FPGA 2025-10-15 10:57 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1开发板串口简介

DE23-Lite开发板提供了一个UART通信接口(物理接口是下图的Type C接口),用户能够通过主机与Agilex 3 FPGA进行串口通信

272e8206-a643-11f0-8c8f-92fbcf53809c.png

该接口使用DE23-Lite板载的USB Blaster III电路中的FT2232H芯片作为UART转USB的桥梁。将USB线连接到DE23-Lite板的Type-C接口和主机之间,即可启用USB Blaster III和FPGA UART功能,此时无需串行驱动程序,但用户在使用UART功能前需要确保已安装USB Blaster III驱动程序。

2790766e-a643-11f0-8c8f-92fbcf53809c.png

连接USB线后,通常在PC设备管理器中会显示USB Blaster III和一个COM端口号。

27f86828-a643-11f0-8c8f-92fbcf53809c.png

2实验任务

设计一个串口回环实验,实现上位机发送数据给开发板串口,串口接收数据后又通过串口发送给上位机。

284feef4-a643-11f0-8c8f-92fbcf53809c.png

串口时序图如下:

28abb928-a643-11f0-8c8f-92fbcf53809c.png

要求:数据位为8位, 停止位1位,无校验位,波特率115200bps。

3模块设计

DE23-Lite的串口回环设计主要是2个模块:串口发送模块(发送数据时将并行的数据转换成串行数据进行传输)和串口接收模块(在接收数据时将接收到的串行数据转换成并行数据)。

291115a2-a643-11f0-8c8f-92fbcf53809c.png

系统时钟是50MHz,波特率是115200bps,那么串口发送和接收时,数据的每个位将占用50000000/115200 ≈ 434个时钟周期。

在串口接收模块设置一个4状态的状态机:

空闲状态:在空闲状态下,检测起始位(低电平)。一旦检测到起始位,进入START状态,并设置计数器在半位时间后采样,这样可以确保在位的中心点采样,提高抗噪能力。

起始位检测状态:等待半个位周期后,再次检查线路状态。如果仍然是低电平,确认是有效的起始位,进入DATA状态;否则认为是噪声干扰,返回IDLE状态。

数据位接收状态:在每个位周期的中心点采样数据位,并存入移位寄存器。接收完8位数据后,进入STOP状态。

停止位处理状态:等待一个完整的位周期(停止位),然后将接收到的数据输出,并产生一个时钟周期的接收完成信号

296577fa-a643-11f0-8c8f-92fbcf53809c.png

接收模块工程代码:

moduleuart_rx(
 input clk,
 input rst_n,
 input uart_rx,
 output reg [7:0] rx_data,
 output reg rx_done
);


parameterCLK_FREQ=50000000;
parameterBAUD_RATE=115200;
 
 //波特率计数器
 localparam BAUD_CNT_MAX=CLK_FREQ/BAUD_RATE;
 localparam HALF_BAUD_CNT=BAUD_CNT_MAX/2;
 reg [15:0] baud_cnt;
 
 //状态定义
 localparam IDLE=2'd0;
 localparam START = 2'd1;
 localparam DATA=2'd2;
 localparam STOP = 2'd3;
 
 reg [1:0] state;
 reg [2:0] bit_cnt;
 reg [7:0] rx_reg;
 reg uart_rx_sync1, uart_rx_sync2;
 
 //同步输入信号
always @(posedge clkornegedge rst_n)begin
 if(!rst_n)begin
  uart_rx_sync1<= 1'b1;
    uart_rx_sync2 <= 1'b1;
  end else begin
    uart_rx_sync1 <= uart_rx;
    uart_rx_sync2 <= uart_rx_sync1;
  end
end
    
    // 状态机
always @(posedge clk or negedge rst_n) begin
  if(!rst_n) begin
    state <= IDLE;
    rx_data <= 8'd0;
    rx_done <= 1'b0;
    baud_cnt <= 0;
    bit_cnt <= 0;
    rx_reg <= 0;
  end
  else begin
    rx_done <= 1'b0;     
    case (state)
      IDLE: begin
        if(uart_rx_sync2 == 1'b0) begin  // 检测起始位
          state <= START;
          baud_cnt <= HALF_BAUD_CNT - 1;  // 半位时间后采样
        end
      end
                
      START: begin
        if(baud_cnt == 0) begin
          if(uart_rx_sync2 == 1'b0) begin  // 确认起始位
            state <= DATA;
            baud_cnt <= BAUD_CNT_MAX - 1;
            bit_cnt <= 0;
          end
          else begin
            state <= IDLE;  // 假起始位
          end
        end else begin
          baud_cnt <= baud_cnt - 1;
        end
      end
                
      DATA: begin
        if(baud_cnt == 0) begin
          rx_reg[bit_cnt] <= uart_rx_sync2;
          if (bit_cnt == 3'd7) begin
            state <= STOP;
          end
          else begin
            bit_cnt <= bit_cnt + 1;
          end
          baud_cnt <= BAUD_CNT_MAX - 1;
        end 
        else begin
          baud_cnt <= baud_cnt - 1;
        end
      end
                
      STOP: begin
        if(baud_cnt == 0) begin
          rx_data <= rx_reg;
          rx_done <= 1'b1;
          state <= IDLE;
        end
        else begin
          baud_cnt <= baud_cnt - 1;
        end
      end
    endcase
  end
end


endmodule

串口发送模块同样设置了一个4状态的状态机:

空闲状态:空闲状态保持高电平。

起始位发送状态:发送起始位,低电平。

数据发送状态:数据位从最低位(LSB)开始发送,这是UART的标准格式。

停止位发送状态:发送停止位,高电平。

29bee39e-a643-11f0-8c8f-92fbcf53809c.png

串口发送模块的工程代码:

module uart_tx(
 input clk,
 input rst_n,
 input tx_start,
 input [7:0] tx_data,
 output reg uart_tx,
 output tx_busy
);


parameterCLK_FREQ =50000000;
parameterBAUD_RATE =115200;
 
  // 波特率计数器
 localparam BAUD_CNT_MAX = CLK_FREQ / BAUD_RATE;
 reg [15:0] baud_cnt;
 wire baud_tick = (baud_cnt ==0);
 
  // 状态定义
 localparam IDLE =2'd0;
 localparam START = 2'd1;
 localparamDATA=2'd2;
 localparam STOP = 2'd3;
 
 reg [1:0] state;
 reg [2:0] bit_cnt;
 reg [7:0] tx_reg;
 
  // 波特率计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
  baud_cnt <= 0;
  end
  elseif(state != IDLE) begin
    if(baud_cnt == 0) begin
      baud_cnt <= BAUD_CNT_MAX - 1;
    end
    else begin
      baud_cnt <= baud_cnt - 1;
    end
  end
  else begin
    baud_cnt <= 0;
  end
end
    
    // 状态机
always @(posedge clk or negedge rst_n) begin
  if(!rst_n) begin
    state <= IDLE;
    uart_tx <= 1'b1;
    bit_cnt <= 0;
    tx_reg <= 0;
  end
  else begin
    case(state)
      IDLE: begin
        uart_tx <= 1'b1;
        if (tx_start) begin
          state <= START;
          tx_reg <= tx_data;
        end
      end
                
      START: begin
        if(baud_tick) begin
          uart_tx <= 1'b0;
          state <= DATA;
          bit_cnt <= 0;
        end
      end
                
      DATA: begin
        if(baud_tick) begin
          uart_tx <= tx_reg[bit_cnt];
          if (bit_cnt == 3'd7) begin
            state <= STOP;
          end
          else begin
            bit_cnt <= bit_cnt + 1;
          end
        end
      end
                
      STOP: begin
        if(baud_tick) begin
          uart_tx <= 1'b1;
          state <= IDLE;
        end
      end
    endcase
  end
end
    
    assign tx_busy = (state != IDLE);


endmodule

top文件代码要完成的任务是:

只有在检测到接收完成信号的上升沿时才启动发送

只有在发送器不忙时才启动新的发送

实现了接收数据到发送数据的无缝衔接

moduleDE23_Lite_uart(
 input clk,
 input rst_n,
 input uart_rx,
 output uart_tx
);


/* synthesis keep */wire [7:0] rx_data;
 wire rx_done;
 wire rx_done_rise,tx_start;
 wire tx_busy;
 
 // UART接收模块
 uart_rx#(
  .CLK_FREQ(50000000),
  .BAUD_RATE(115200)
  ) uart_rx_inst (
  .clk(clk),
  .rst_n(rst_n),
  .uart_rx(uart_rx),
  .rx_data(rx_data),
  .rx_done(rx_done)
 );
 
 // UART发送模块
 uart_tx#(
  .CLK_FREQ(50000000),
  .BAUD_RATE(115200)
 ) uart_tx_inst (
  .clk(clk),
  .rst_n(rst_n),
  .tx_start(tx_start),
  .tx_data(rx_data),
  .uart_tx(uart_tx),
  .tx_busy(tx_busy)
 );
 
 // 回环控制逻辑
 reg rx_done_reg;
 always @(posedge clkornegedge rst_n)begin
 if(!rst_n) begin
   rx_done_reg <= 1'b0;
    end else begin
      rx_done_reg <= rx_done;
    end
  end
    
    // 检测接收完成的上升沿
  assign rx_done_rise = rx_done && !rx_done_reg;
    
    // 发送启动信号
  assign tx_start = rx_done_rise && !tx_busy;


endmodule

仿真代码:

`timescale1ns/1ps


module DE23_Lite_uart_tb;


 // 输入
 reg clk;
 reg rst_n;
 reg uart_rx;
 
 // 输出
 wire uart_tx;
 
 // 测试参数
 parameter CLK_PERIOD =20; // 50MHz时钟周期
 parameter BIT_PERIOD =8680;// 115200波特率的位周期(1/115200 ≈ 8.68μs)
 
 // 实例化顶层模块
DE23_Lite_uartuut(
 .clk(clk),
 .rst_n(rst_n),
 .uart_rx(uart_rx),
 .uart_tx(uart_tx)
 );
 
 // 时钟生成
 always begin
  clk =0;
 #(CLK_PERIOD/2);
  clk =1;
 #(CLK_PERIOD/2);
 end
 
 // 测试任务:发送一个字节
 task send_byte;
  input [7:0] data;
  integer i;
  begin
     // 发送起始位
   uart_rx =0;
  #(BIT_PERIOD);    
     // 发送8个数据位
  for(i =0; i < 8; i = i + 1) begin
        uart_rx = data[i];
        #(BIT_PERIOD);
      end
            
            // 发送停止位
      uart_rx = 1;
      #(BIT_PERIOD);
    end
  endtask
    
    // 主测试程序
  initial begin
        // 初始化
    rst_n = 0;
    uart_rx = 1;
        
        // 复位
    #100;
    rst_n = 1;
    #100;
        
        // 测试1:发送字节 8'h55
    send_byte(8'h55);
        
        // 测试2:发送字节 8'hAA
    send_byte(8'hAA);
        
        // 测试3:发送字节 8'hF0
    send_byte(8'hF0);
        
        // 测试4:发送字节 8'h0F
    send_byte(8'h0F);
        
        // 结束仿真
    #10000;
    $stop;
  end


endmodule

modelsim仿真波形:

2a24923e-a643-11f0-8c8f-92fbcf53809c.png

可以看到:

第一个波特位时间内,rx先发送低电平起始位,然后发送8bit数据01010101(低位在前,8'h55),最后发送高电平停止位;tx则一直是高电平。

第二个波特位时间内,rx先发送低电平起始位,然后rx发送第二个测试数据10101010(低位在前,8'hAA),最后发送高电平停止位;tx则接收到8bit数据01010101。

第三个波特位时间内,rx先发送低电平起始位,然后rx接收第二个测试数据11110000(低位在前,8'hF0),最后发送高电平停止位;tx则接收到8bit数据10101010。

第四个波特位时间内,rx先发送低电平起始位,然后rx接收第二个测试数据00001111(低位在前,8'h0F),最后发送高电平停止位;tx则接收到8bit数据11110000。

第五个波特位时间内,rx保持高电平;tx则接收到8bit数据00001111。

Quartus版本选择:25.1,具体操作参考文章最新版Quartus Prime Pro 25.1 的安装和使用演示(含Questa仿真)

引脚分配:

2a7c8d5e-a643-11f0-8c8f-92fbcf53809c.png

4下板测试

2ad727c8-a643-11f0-8c8f-92fbcf53809c.png

打开串口工具比如Putty或者是下面截图所示的XCOM,然后按照如下操作去测试:

选择正确的COM口

波特率设置为115200

停止位设置为1位

无校验位

点击打开串口

在发送窗口随便发送数据,可以看到上面接收窗口得到同样的数据显示,表示测试成功。

2b3dcad2-a643-11f0-8c8f-92fbcf53809c.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1655

    文章

    22287

    浏览量

    630317
  • 接口
    +关注

    关注

    33

    文章

    9446

    浏览量

    156146
  • 串口通信
    +关注

    关注

    34

    文章

    1657

    浏览量

    57639
  • 开发板
    +关注

    关注

    25

    文章

    6125

    浏览量

    113381
  • Agilex
    +关注

    关注

    0

    文章

    26

    浏览量

    3981

原文标题:2-基于FPGA开发板DE23-Lite的串口通信设计 (FT2232H)

文章出处:【微信号:友晶FPGA,微信公众号:友晶FPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于FPGA开发板TSP的串口通信设计

    本文详细介绍基于Terasic FPGA开发板TSP(又名C5P和OSK)和其板载CP2102N USB-UART桥接芯片的串口通信系统设计与实现。系统采用Verilog HDL编写U
    的头像 发表于 10-15 11:05 4152次阅读
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>开发板</b>TSP的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>设计

    基于FPGA开发板DE10-Standard和T-Core的串口通信设计

    本文适用于DE10-Standard、T-Core、DE1-SOC以及DE10-Nano等有GPIO引脚外扩的FPGA开发板
    的头像 发表于 10-28 11:15 4099次阅读
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>开发板</b><b class='flag-5'>DE</b>10-Standard和T-Core的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>设计

    基于DE1-SOC开发板的太空射击游戏

    今天继续常春藤名校之一——康奈尔大学的FPGA课程ECE 5760典型案例分享:基于DE1-SOC开发板的太空射击游戏。
    的头像 发表于 08-04 10:47 3462次阅读
    基于<b class='flag-5'>DE</b>1-SOC<b class='flag-5'>开发板</b>的太空射击游戏

    出售DE2-70 FPGA开发板

    开发板型号为友晶DE2-70,FPGA为EP2C70,本人于2010年购入,现长期闲置,故打算出售。有意者可QQ联系,价格面议。联系QQ:26638773
    发表于 02-12 00:37

    Altera DE2 开发板测试说明

    1 安装 Quartus II 5.1 Web Edition Full;2 将 DE2 System 光盘中的全部内容复制到PC 机上,其中DE2_control_panel文件夹内容最为重要;3 将开发板的电源和 USB 线
    发表于 07-21 16:35 0次下载

    fpga开发板电路图

    最全面的fpga开发板电路图,一共有10多份fpga开发板电路图。
    发表于 04-19 12:50 133次下载
    <b class='flag-5'>fpga</b><b class='flag-5'>开发板</b>电路图

    基于FPGA了解DE2开发板

    DE2 是以CycloneII 2C35FPGA为特点的672 针引脚的包装。上所有重要的部件都与上的芯片相连,使用户能够控制
    发表于 09-01 16:32 25次下载
    基于<b class='flag-5'>FPGA</b>了解<b class='flag-5'>DE</b>2<b class='flag-5'>开发板</b>

    fpga开发板用途,fpga开发板价格

    (host),一个是目标平台(target)即开发板。在此描述的开发平台指的是使用计算机,通过传输的界面,例如串口(RS-232)、USB、并口、或者网络(Ethernet)与目标平台连接,f
    发表于 10-23 17:18 4748次阅读

    ALTERA公司的DE1 SoC FPGA开发板的培训教程免费下载

    本文档的主要内容详细介绍的是ALTERA公司的DE1 SoC FPGA开发板的培训教程免费下载包括了:第1章 DE1-SOC 快速入门,第2章 DE
    发表于 07-08 08:00 45次下载
    ALTERA公司的<b class='flag-5'>DE</b>1 SoC <b class='flag-5'>FPGA</b><b class='flag-5'>开发板</b>的培训教程免费下载

    使用小凌派开发板wifi进行tcp通信的步骤

    开发过程中想要与开发板进行通信一般使用串口通信,当开发板使用
    的头像 发表于 05-16 09:35 2891次阅读

    上位机和FPGA开发板--串口通信实验

    首先,上位机发送数据给FPGA开发板;然后,FPGA开发板收到数据,再回发给上位机。
    发表于 05-11 18:26 12次下载
    上位机和<b class='flag-5'>FPGA</b><b class='flag-5'>开发板</b>--<b class='flag-5'>串口</b><b class='flag-5'>通信</b>实验

    基于STM32F4开发板的激光测距模块串口通信(三)

    在我们使用外设时怎样将外设的数据返回给开发板呢? 今天以STM32F4开发板为例,讲解激光测距模块如何通过串口通信将数据发送给开发板。PS
    发表于 05-17 09:50 7次下载
    基于STM32F4<b class='flag-5'>开发板</b>的激光测距模块<b class='flag-5'>串口</b><b class='flag-5'>通信</b>(三)

    fpga开发板与linux开发板区别

    FPGA开发板与Linux开发板是两种不同的硬件开发平台,各自具有不同的特点和应用场景。在以下的文章中,我将详细介绍FPGA
    的头像 发表于 02-01 17:09 3966次阅读

    fpga开发板使用教程

    FPGA开发板的使用教程主要包括以下几个关键步骤。
    的头像 发表于 03-14 15:50 2431次阅读

    fpga开发板是什么?fpga开发板有哪些?

    FPGA开发板是一种基于FPGA(现场可编程门阵列)技术的开发平台,它允许工程师通过编程来定义和配置FPGA芯片上的逻辑电路,以实现各种数字
    的头像 发表于 03-14 18:20 4414次阅读