本文用MIO的方式在主板上演示串口的hello world例程(适用于主板Type C 端口的UART资源)
本文在 vivado2018.3版本上 演示, 其他版本请自行研究
1.硬件资源介绍
PS端串口的映射有两种,方式一 直接通过ZYNQ的PS专用串口的IO口。 方式2 PS端的UART 通过EMIO方式映射到任意PL端口进行引出,两种方式的效果是完全一样的(方式可以拓展到PL端的任意IO口)。(因为我们的串口是连接在PS端的,所以这里我们用方式一 通过MIO将UART 映射到PL端 IO上)
2. 创建工程
1)新建一个项目,芯片型号选择按下面选择(板子生产了多个芯片型号,请根据自己板子的型号来进行选择)
- XA7Z020 (直接选择xc7z020CLG400-1,因为系统识别到的是xc7z020-1)
- XC7Z010-1 (xc7z010CLG400-1) (7010 芯片)
- XC7Z020-1 (xc7z020CLG400-1) 后续生产
- XC7Z020-2 (xc7z020CLG400-2) 后续生产
备注 (7020 车规级版在vivado2018.3识别出的是XC7Z020,如果工程选择xa7z020 ,在SDK环境下有时候会弹出警告,所以这里直接选择XC7Z020CLG400-1)
2) 创建一个BLOCK设计,并添加ZYNQ7 PROCESSING SYSTEM模块,软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-3.png)
3)在ZYNQ中设置时钟功能:
找到 设置项目中的 Clock Configuration 选项, 在PL Fabric Clocks 设置自己需要的时钟频率,这里一共有4种频率可以设置 类似于我们的PLL功能。这里我们设置50M时钟
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-50.png)
4)依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K256M16RE-125,数据位宽选择16bit 最后点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-70.png)
5) 添加 uart功能
由下图可知, 主板的UART功能接在 ZYNQ PS端的 B13脚和B9脚了,即 ZYNQ的TX是 连接MIO51,ZYNQ的RX是连接MIO50
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-79.png)
使能UART 0 并在IO选项力 选择MIO方式,下拉菜单里选择MIO50-51
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-80.png)
6)完成上述操作后, 点击“Run Block Automation”如下图所示。在弹出的选项中保持默认,点击“OK”,即可完成对ZYNQ7 Processing System的配置,并用鼠标连接FCLK_CLK和 M_AXI_GP0_ACLK,得到下图
![](http://www.hellofpga.com/wp-content/uploads/2023/01/image-81.png)
7)source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper,打包BLOCK文件并生成.v代码
8) 点击绿色箭头RUN 对代码进行编译
9) 因为这边用的是原生MIO 资源,并且没有使用任何PL的IO口,所以这边不需要额外创建管脚约束
10) 生成bit文件 :按下Generate Bitstream 完成综合以及生成bit文件(会弹出窗口要求保存 约束规则文件)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-18.png)
5.SDK程序编写
1)File→Export→Export hardware…,在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-10.png)
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-24.png)
2)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-21.png)
系统将自动打开SDK开发环境
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-22.png)
3)新建一个工程 file→new→Application Project,来新建一个“Application Project”,如下图所示。
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-23.png)
4)在新建工程名中输入自己的工程名称(UART),点击NEXT
5)选择一个空工程,点击完成
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-73.png)
6) 在空工程中创建我们自己的代码
展开我们创建的工程,在src目录上右键,选择New->Source File,如下图所示:
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-76.png)
在弹出的窗口中创建一个main.c文件
![](http://www.hellofpga.com/wp-content/uploads/2021/08/image-77.png)
7)书写自己的代码
7.1小贴士:
在初次写PS部分的代码时,如GPIO代码 和UART代码,不知道怎么写的情况下,其实可以通过打开 BSP工程下的 system.mss文件, 然后在右边导入需要的参考例程, 然后将例程中自己需要的部分(如GPIO初始化,或者UART的写和读代码COPY到自己工程的main函数中)再进行修改。
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-11-1024x607.png)
7.2 复制 下列代码 到 main.c
#include "xparameters.h" #include "xuartps.h" #include "xil_printf.h" XUartPs Uart_Ps_0; /* The instance of the UART Driver */ int UART_init(){ XUartPs_Config *Config; int Status; Config = XUartPs_LookupConfig(XPAR_XUARTPS_0_DEVICE_ID); Status = XUartPs_CfgInitialize(&Uart_Ps_0, Config, Config->BaseAddress); XUartPs_SetBaudRate(&Uart_Ps_0, 115200); return Status; } void UartPs_HelloWorld() { u8 HelloWorld[] = "Hello World "; int SentCount = 0; while (SentCount < (sizeof(HelloWorld) - 1)) { XUartPs_Send(&Uart_Ps_0, &HelloWorld[SentCount], 1); SentCount++; } } int main(void) { int Delay; UART_init(); while(1){ UartPs_HelloWorld(); for (Delay = 0; Delay < 100000000; Delay++); } }
我这边参考了官方的代码, 并做了一定的删减(删除了不必要的初始化验证等),将UART 0进行了初始化, 并且在helloworld的代码中,端口进行helloworld的字符串输出,反复循环。
8.代码下载验证
先对 RUN AS 的环境进行配置
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-12.png)
在弹出的窗口中 对4个 方框都进行勾选操作,以确保每次运行都会重新启动系统,并且重新编程FPGA, 这样就不会出现下载程序debug的时候概率性不工作的问题了(不勾选情况下,板子本身运行程序的时候,再重新debug会概率性出现下载报错的情况)PS没有出现 下图对话框,可以先点绿色箭头DEBUG一下 ,再重新 点选上图RUN CONFIGURATIONS 的选项
![](http://www.hellofpga.com/wp-content/uploads/2022/10/image-120.png)
设置好之后,选择Run As
-> Launch on Hardware (System Debugger)
或者 Launch on Hardware (GDB).
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-14.png)
经过上述操作后,串口就会正常输出数据了,此时用串口助手去查看,可以看到 系统在不停的发送 hello world字符串(串口波特率 115200)
![](http://www.hellofpga.com/wp-content/uploads/2022/07/image-15.png)
以下是本文中提到的完整工程 ,仅供参考
备注 ZYNQ芯片功能非常强大,上述仅进行简单的helloworld演示, 实际串口功能还可以调用中断,调用FIFO等,这个各自自行学习尝试了
备注 如果你使用自己的TYPE C充电线 请注意,部分市面上的TYPE C充电线 是仅充电的,不带数据传输功能,需要用TYPE C 数据线才能实现通讯