首页 > 编程语言 >[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-12 串口程序收发环路设计

[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-12 串口程序收发环路设计

时间:2024-07-29 15:08:59浏览次数:15  
标签:仿真 12 FPGA uart 发送 UART 安路 串口

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

 

1概述

前面两课,我们完成了我们发送程序的测试,成功给PC主机发送了"HELLO FPGA"的信息,主机显示接收成功。但是我们串口接收的程序仅仅是通过我们模拟仿真,虽然仿真结果达到了期望,但是不能直接上板测试难免差强人意。所以我们不妨将我们串口UART接收程序以及发送程序连接起来,做到能将PC端通过USB发送过来的数据接收,然后将接收到的数据再通过发送程序返回给我们的PC机。

在完成本实验前,请确保已经完成前面的实验,包括已经掌握以下能力:

1:完成了TD软件安装

2:完成了modelsim安装以及TD库的编译

3:掌握了TD仿真环境的设置

4:掌握了modesim通过do文件启动仿真

 

实验目的:

1:实现UART串口发送控制器的设计

2:实现主程序中调用串口发送控制器发送字符"HELLO FPGA"

3:实用modelsim完成仿真验证

4:编译并且固化程序到FPGA验证

1.1 UART收发环路简介

电脑USB口和FPGA串口通信示意图:

一般RS232只使用到TXD和RXD两个信号,两个设备之间的TXD和RXD必须交叉连接,例如对于PC的TX 要和FPGA的RX连接,同样PC的RX要和FPGA的TX连接才可以正常通信。

1.2硬件电路分析

参照 "UART串口发送驱动设计"硬件电路分析部分

 

2 UART收发环路程序设计

在完成以下实验前,请确保已经完成了"UART串口发送实验"和"UART串口接收实验"

2.1系统框图

上位机通过串口发送数据到FPGA开发板的UART数据接收模块,将串口接收端口(I_uart_rx)的串行数据解析回并行数据输出,再将并行数据作为输入给数据发送模块,UART数据发送模块将并行数据转成串行数据发送回上位机。通过串口发送端口(O_uart_tx)把数据发回到串口芯片,之后数据在串口调试助手上打印,实现环路测试。需要注意的是,数据并不是一直有效的,所以将UART数据接收模块的数据有效信号(O_uart_rvalid)接入到UART数据发送模块的发送数据请求信号(I_uart_wreq),当接收的信号有效时,触发UART数据发送模块,就可以发送接收的有效数据。对于发送驱动模块中的O_uart_wbusy信号,不需要使用,因为这里uart发送模块是被动发送。

2.2驱动源码

顶层模块只需要调用uart的首发模块驱动接口。并且设置uart_rdata和uart_wdata互联,uart_wreq和uart_rvalid互联。

 

 

 1 `timescale 1ns / 1ns //仿真时钟刻度和精度
 2 
 3 module uart_top
 4 (
 5 input  I_sysclk,//系统时钟输入
 6 input  I_uart_rx,//uart rx接收信号
 7 output O_uart_tx //uart tx发送信号
 8 );
 9 
10 localparam SYSCLKHZ = 25_000_000;  //系统输入时钟
11 
12 reg [11:0] rstn_cnt = 0;//上电后延迟复位
13 wire uart_rstn_i;//内部复位信号
14 wire uart_wreq,uart_rvalid;
15 wire [7:0]uart_wdata,uart_rdata;
16 
17 assign uart_wreq  = uart_rvalid;//用uart rx接收数据有效的uart_rvalid信号,控制uart发送模块的发送请求
18 assign uart_wdata = uart_rdata; //接收的数据给发送模块发送
19 assign uart_rstn_i = rstn_cnt[11];//延迟复位设计,用计数器的高bit控制复位
20 
21 //同步计数器实现复位
22 always @(posedge I_sysclk)begin
23     if(rstn_cnt[11] == 1'b0)
24         rstn_cnt <= rstn_cnt + 1'b1;
25     else 
26         rstn_cnt <= rstn_cnt;
27 end
28 
29 //例化uart 发送模块
30 uiuart_tx#
31 (
32 .BAUD_DIV(SYSCLKHZ/115200-1)    
33 )
34 uart_tx_u 
35 (
36 .I_clk(I_sysclk),//系统时钟输入
37 .I_uart_rstn(uart_rstn_i), //系统复位
38 .I_uart_wreq(uart_wreq), //uart发送驱动的写请求信号,高电平有效
39 .I_uart_wdata(uart_wdata), //uart发送驱动的写数据
40 .O_uart_wbusy(),//uart 发送驱动的忙标志
41 .O_uart_tx(O_uart_tx)//uart 串行数据发送
42 );
43 
44 //例化uart 接收
45 uiuart_rx#
46 (
47 .BAUD_DIV(SYSCLKHZ/115200-1)   
48 )
49 uiuart_rx_u 
50 (
51 .I_clk(I_sysclk), //系统时钟输入
52 .I_uart_rstn(uart_rstn_i),//系统复位
53 .I_uart_rx(I_uart_rx), //uart 串行数据接收
54 .O_uart_rdata(uart_rdata), //uart 接收数据
55 .O_uart_rvalid(uart_rvalid)//uart 接收数据有效,当O_uart_rvalid =1'b1 O_uart_rdata输出的数据有效
56 );
57     
58 endmodule

 

3 FPGA工程

fpga工程的创建过程不再重复,如有不清楚的请看前面实验,具体的FPGA型号以对应的开发板上芯片为准

米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹

01_rtl:放用户编写的rtl代码

02_sim:仿真文件或者工程

03_ip:放使用到的ip文件

04_pin:放fpga的pin脚约束文件或者时序约束文件

05_boot:放编译好的bit或者bin文件(一般为空)

06_doc:放本一些相关文档(一般为空)

4 Modelsim仿真

4.1准备工作

Modelsim仿真的创建过程不再重复,如有不清楚的请看前面实验

仿真测试文件源码如下:

 

 1 `timescale 1ns/1ns  //定义仿真时间刻度/精度
 2 
 3 module sim_top_tb();
 4  
 5 localparam     BPS       = 'd115200          ;                //波特率
 6 localparam     CLK_FRE    = 'd25_000_000     ;                //系统频率
 7 localparam     CLK_TIME   =  'd250_000_000 /CLK_FRE;          //计算系统时钟周期,以ns为单位
 8 localparam     BIT_TIME   = 'd250_000_000  / BPS ;            //计算出传输每个bit所需要的时间以ns为单位
 9 localparam     NUM_BYTES  = 3;                                //需要发送的BYTES
10 
11 reg              I_sysclk;                                    //系统时钟
12 reg              bsp_clk ;                                    //波特率时钟
13 reg              uart_tx;                                     //uart 数据发送,该信号接入到,FPGA的uart 接收
14 wire             uart_rx;                                     //uart 数据接收,该信号接入到,FPGA的uart 发送
15 reg [8*NUM_BYTES-1:0] uart_send_data;                         //需要发送的数据
16 reg [7:0]            uart_send_data_r;                        //寄存每次需要发送的BYTE
17 
18 integer i,j;
19 
20 //例化顶层模块
21 uart_top uart_top_inst
22 (
23 .I_sysclk(I_sysclk),
24 .I_uart_rx(uart_tx),
25 .O_uart_tx(uart_rx)
26 );
27 
28 //仿真初始化
29 initial begin  
30 
31 //初始化REG寄存器
32 I_sysclk =0;
33 bsp_clk  = 0;  
34 uart_tx  = 1;
35 i=0;
36 j=0;
37 
38 uart_send_data   =0;
39 uart_send_data_r =0;
40 
41 #20000;//延迟20000ns,等待uart测试代码中的复位延迟
42 
43 uart_send_data[(0*8) +: 8] = 8'b1001_0101;//初始化需要发送的第1个BYTE
44 uart_send_data[(1*8) +: 8] = 8'b0000_0101;//初始化需要发送的第2个BYTE
45 uart_send_data[(2*8) +: 8] = 8'b1000_0100;//初始化需要发送的第3个BYTE
46 
47 //uart tx 发送数据
48   for(i=0; i<NUM_BYTES;i=i+1)
49   begin
50 
51       uart_send_data_r = uart_send_data[(i*8) +: 8];//寄存需要发送的数据到寄存器
52       $display("uart_send_data : 0x%h",uart_send_data_r);//打印准备发送的数据
53 
54       @(posedge bsp_clk);  //发送起始位1bit
55       uart_tx = 1'b0;
56 
57       for(j=0;j<8;j=j+1)begin//发送数据8bits
58       @(posedge bsp_clk);  //发送
59       uart_tx = uart_send_data_r[j];
60       end
61 
62        @(posedge bsp_clk);//发送停止位1bit
63        uart_tx = 1'b1;  
64 
65   end
66        @(posedge bsp_clk); 
67        #200 $finish;               
68 end
69  
70 always #(CLK_TIME/2) I_sysclk = ~I_sysclk;     //产生主时钟
71 always #(BIT_TIME/2) bsp_clk  = ~bsp_clk;         //产生波特率时钟
72  
73 
74 endmodule

 

 

 

 

4.2启动modelsim仿真

启动后,右击需要观察的信号,添加到波形窗口

设置restart

设置运行2.2ms(如果时间太长需要找下数据位置,时间太短需要继续跑直到波形出来)

5下载演示

下载程序前,先确保FPGA工程已经编译。

5.1硬件连接

(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)

请确保下载器和开发板已经正确连接,并且开发板已经上电(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)

5.2运行结果

标签:仿真,12,FPGA,uart,发送,UART,安路,串口
From: https://www.cnblogs.com/milianke/p/18330128

相关文章

  • P10812 【MX-S2-T3】跳 题解
    题目分析考虑DP。显然当没有\(i\)连向\(i+1\)的边时,整个图是一个DAG,可以直接DP。所以我们DP要解决的唯一问题,就是考虑上\(i\)到\(i+1\)的边。考虑从\(n\)走到\(1\)的过程。当我们从\(i\)向前跳到\(j\)后,此时我们要么向前跳,要么往回走。又因为不能经过重复......
  • LeetCode LCR 124.推理二叉树(哈希表 + 建树)
    某二叉树的先序遍历结果记录于整数数组 preorder,它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。注意:preorder 和 inorder 中均不含重复数字。示例1:输入:preorder=[3,9,20,15,7],inorder=......
  • 12个Python数据类型转换实战演练
    文末赠免费精品编程资料~~在Python编程中,数据类型转换是处理数据时必不可少的技能。掌握如何灵活地在不同类型之间转换,能让你的代码更加高效和灵活。下面,我们将通过一系列实战演练,学习并实践12种常见的Python数据类型转换。1.整数转字符串实战案例:将年龄转换为字符串......
  • 912、基于51单片机的温度控制(PID,模拟控制,除雾器)
    完整资料或代做滴滴我(有偿)目录一、设计功能二、proteus仿真三、原理图四、程序源码五、资料包括一、设计功能设计中镜片除雾器,当温度过低时启动镜片上的加热膜进行加热,从而实现对镜片上温度的控制,实现只能除雾;保持镜片温度为25度。二、proteus仿真三......
  • 【从0制作自己的ros导航小车:上、下位机通信篇】上、下位机串口DMA通信
    从0制作自己的ros导航小车前言一、准备工作二、下位机端(STM32)三、上位机端(旭日x3派)四、测试前言下位机的电机驱动、轮速读取、偏航角读取都已经完成,接下来就是上下位机的桥梁:串口通信。使用USB转TTL模块连接上位机(旭日x3派)和下位机(stm32),只需要连接RX、TX、GND即可......
  • Python\Python312\Lib\site-packages\torch\lib\fbgemm.dll
    在此处输入图像描述我正在尝试从HuggingFace导入GPT-2变压器模型,但当我尝试导入它时,遇到错误。即使当我尝试仅导入Torch时,我也会收到相同的错误。我已尝试重新安装Torch并完成了所有操作,包括更新VisualC++Redistributable软件包和更新我的驱动程序,但问题......
  • 实验7-1-12 组个最小数
    给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:给定两个0,两个1,三个5,一个8,我们得到的最小的数就是10015558。现给定数字,请编写程序输出能够组成的最小的数。输入格式:输入在一行中给出10个非负整数,......
  • codeforces 1209E2 Rotate Columns (hard version)
    codeforces1209E2RotateColumns(hardversion)题解题目传送门:codeforcces,luogu思路状压dp,贪心。贪心对于所有列,只有列中最大值在所有列的最大值中前\(n\)大才可能对答案有贡献。证明:若有非前\(n\)大的列对某行最大值产生了贡献,则用没有被取的前\(n\)大的列代......
  • 鸣潮游戏错误126:加载x3daudio1_7.dll失败的全面解析与修复指南
    在畅玩鸣潮游戏时,不少玩家可能会遭遇错误代码「126」,提示“加载x3daudio1_7.dll失败,该文件缺失或损坏”。这个问题看似棘手,实则有迹可循,通过本文,我们将深入探讨其成因,并提供详细的解决步骤,帮助你重拾游戏乐趣。x3daudio1_7.dll是什么?x3daudio1_7.dll是一个与DirectX音频组件......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-01 软件工具环境搭建
    ​ 软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!本教程使用了米联客-MLK-L1-CZ06-DR1M90G开发板,购买链接:https://milianke.tmall.com/​1代码编辑vscode工具软件......