电子说
芯片型号:XC7Z010-1CLG400C
Vivado版本:2016.1
点亮流水灯,共使用了三种方式:
(1)PS通过MIO点亮PS端LED
(2)PS通过EMIO点亮PL端LED
(3)PS通过AXI点亮PL端LED。
1. MIO与EMIO
首先来理清楚MIO与EMIO的关系。MIO是PS的I/O引脚,一共有54个,分为Bank0与Bank1,可以接许多外设比如UART、SPI或GPIO等,另外可以引脚复用。当我们想通过PS来访问PL又不想浪费AXI总线时,就通过EMIO接口来访问。在54个I/O中,有一些只能用于MIO,大部分可以用于MIO与EMIO,一些接口信号线只能通过EMIO访问。
EMIO依然属于PS,只是连接到了PL,再从PL输出信号。
2. PS通过MIO点亮PS端LED
从电路中看得很清楚,这两个LED直接连接在MIO0和MIO13上,所以直接在这两个端口输出高低电平就可以控制灯闪烁了。
首先建立.bd文件,添加zynq的ip核,去掉PL的资源(包括PS-PL configuration——general——Enable Clock Resets中的FCLK_RESET0_N以及AXI None Secure Enablement——GP Master AXI Interface中的GP0以及Clock Configuration——PL Fabric Clocks中的FCLK_CLK0)。
在外设I/O中,打开UART1,对应MIO48、49口,打不打开都无所谓,打开调试用。此时在MIO中已经看到UART1已经分配了管脚,然后在GPIO里,打开MIO。
最后在DDR里,找到所用的DDR芯片,比如我用的是HA-125。这样所有的平台就搭好了。直接generate out products——create HDL wrapper——export Hardware——lanuch SDK。
进入SDK,建立工程。首先引头文件xgpiops.h
对MIO0和MIO13,初始化引脚。
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr, u32 EffectiveAddr);
这个函数初始化gpio,第一个参数需要一个XGpioPs的结构体指针,直接在函数开头实例化就好了,结构体的组成在.h文件。第二个参数是一个XGpioPs_Config类型结构体指针,这个结构体的内容:
typedef struct { u16 DeviceId; /**< Unique ID of device */ u32 BaseAddr; /**< Register base address */ } XGpioPs_Config;
包括gpio分配的ID和基地址。第三个参数就是基地址。
如何获得这些信息,首先ID的获得,打开xparameter.h头文件,里面定义了分配的各种资源的ID。
基地址就在配置信息查了,如何获得gpio的配置信息:
首先实例化一个XGpioPs_Config类型的指针。使用XGpioPs_LookupConfig函数,它能够在配置信息中找到对应ID的配置信息:
所以就很明确了:
xgpio_config = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);//找分配的MIO配置信息(基地址) status = XGpioPs_CfgInitialize(&xgpio, xgpio_config,xgpio_config->BaseAddr);//初始化 if(status!=XST_SUCCESS)//初始化成功 return XST_FAILURE;
然后就是定义gpio口的属性,包括输入输出和端口使能:
XGpioPs_SetDirectionPin(&xgpio, LED1, 1);//output XGpioPs_SetDirectionPin(&xgpio, LED2, 1);// XGpioPs_SetOutputEnablePin(&xgpio, LED1, 1);//enable XGpioPs_SetOutputEnablePin(&xgpio, LED2, 1);
再后面就在while(1)中循环点灯,用XGpioPs_WritePin函数输出高低电平。
这是纯PS点流水灯。
3. PS通过EMIO点亮PL端LED
通过EMIO点PL端LED,在配置zynq ip核时,基本步骤差不多,包括去到PL资源等,唯一不同的是,在GPIO里,勾上EMIO并且分配宽度是4(因为我的小板子PL端有四个LED)。
生成了新的系统:
接下来,分配管脚!!因为这里GPIO_0在PL端。看看pdf:
把刚分配的带宽4的EMIO(GPIO_0)绑定到这四个管脚上。
然后输出bitstream文件,导入到SDK中时,要加上这个比特流文件。进入SDK
初始化程序还是一样,头文件也是xgpiops.h,这还是PS操作。
xgpio_config = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID); status = XGpioPs_CfgInitialize(&xgpio, xgpio_config, xgpio_config->BaseAddr); if(status!=XST_SUCCESS) return XST_FAILURE;
后面就是设置引脚工作模式:
这里的引脚号从54开始,因为从54后才是EMIO引脚:
0—53是MIO,53—...是EMIO。
之后点灯就可以了。在运行之前先下载比特流文件到FPGA,另外这个黑金的小板子,PL和PS协同仿真时,总报错,只需要在Reset entire system和Program FPGA打上勾,并且这个比特流文件要绝对地址!!
4. PS通过AXI点亮PL端LED
这个就是PL与PS协同点灯了。
首先配置zynq ip核,PL部分保留,因为用到了AXI,另外MIO gpio都去掉。其余配置都一样。添加AXI gpio IP核,并且设置宽度为4,最后Run connection Automation,加入其它必要组件,调整连线:
之后再绑定gpio_led管脚到四个LED上,综合并生成bitstream文件,导入到SDK。
引用头文件:XGpio.h
然后还是对引脚进行初始化和设置工作模式:
XGpio_Initialize(&GpioOutput, XPAR_AXI_GPIO_0_DEVICE_ID); XGpio_SetDataDirection(&GpioOutput,1,0x0);//output XGpio_DiscreteWrite(&GpioOutput,1,0x0);
协同点灯还是要先下载比特流文件,在运行SDK程序。
5. 总结
① 对MIO或EMIO gpio进行操作,都属于PS,引用xgpiops.h文件,对AXI_gpio引用xgpio.h
② 涉及PL引脚或操作时,生成比特流文件并且导入SDK,运行时先下载FPGA。
③ PL输出信号绑定引脚。
全部0条评论
快来发表一下你的评论吧 !