文章目录
ZYNQ AC7020
一.简介
不管学习哪一个开发板,都是从点灯开始,就如同软件起源于hello world一样,这里我使用的是7000系列的AC7020的开发板,今天就说一下7000系列的GPIO的控制
注意这里的GPIO分为三类,GPIOMIO/EMIO/AXI_GPIO
二.MIO和EMIO/AXI_GPIO
下图EMIO和MIO的结构,可以看到
- MIO总共有54个(0-53),
- 而EMIO总共有64个(54-117)
其中MIO分布在BANK0,BANK1,而EMIO则分布在BANK2、BANK3。总的个数为118个GPIO,这118个GPIO都属于PS的资源
Bank0:MI0[31:0]
Bank1:MI0[53:32]
Bank2:EMI0[31:0]
Bank3:EMI0[63:32]
1.MIO
首先、MIO在zynq上的管脚是固定的,如下图在vivado软件中可以对其进行配置,可以作为USB,SD卡,UART等等外设。
注意:MIO不占用PL的资源,也不需要进行管脚的约束配置,上电后就可以进行加载使用
2.EMIO
EMIO,是通过PL部分扩展的,所以使用EMIO时候需要在约束文件中分配管脚,所以设计EMIO的程序时,需要生成PL部分的bit文件,烧写到FPGA中
注意:EMIO占用PL的资源
3.AXI_GPIO
AXI_GPIO是通过AXI总线挂在PS上的GPIO上,AXI_GPIO相当于GPIO的IP核,我们调用时是占用相应AXI总线地址空间,如下图,占用地址为0x41200000和0x41210000
注意
EMIO和IP方式在vivado都需要绑定管脚
三.开发板IO口
再来看一下AC7020的用户可使用的IO口,3组34个IO总共112个
- PL的IO 94个
- PS的IO 8个
本章的实验是点亮开发板上的LED,先看一LED的电路
PS LED接到了MIO0
PL端的LED是接到R19的 (IO_0_34)
四.裸机开发点灯
这里控制IO可以直接使用 xgpiops.h库函数,注意PL端需要进行管脚约束
1.代码部分
#include <stdio.h>
#include "xil_printf.h"
#include "xgpiops.h"
#include "sleep.h"
//MIO共有54个,编号从0-53,所以54即是第一个EMIO口
//此宏定义对应于MIO led的编号
#define led1 0 //电源指示灯
#define led2 54 //
XGpioPs gpio_mio;
int MIO_Config(void)
{
XGpioPs_Config *gpioPtr;
int status;
//每个外设都有一个ID,GPIO的ID在xparameters.h中定义
gpioPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
status = XGpioPs_CfgInitialize(&gpio_mio, gpioPtr, gpioPtr->BaseAddr);
if(status != XST_SUCCESS)
{
xil_printf("can't config gpio\n\r");
return XST_FAILURE;
}
//配置led1为输出模式
XGpioPs_SetDirectionPin(&gpio_mio, led1, 1);
XGpioPs_SetDirectionPin(&gpio_mio, led2, 1);
//输出使能
XGpioPs_SetOutputEnablePin(&gpio_mio, led1, 1);
XGpioPs_SetOutputEnablePin(&gpio_mio, led2, 1);
//配置输入模式
//XGpioPs_SetDirectionPin(&gpio_mio, key, 0);
return XST_SUCCESS;
}
//写gpio
void MIO_LED(int led, int status)
{
//写GPIO的输出值
XGpioPs_WritePin(&gpio_mio, led, status);
}
//读gpio
int MIO_KEY( int key1 )
{
//读GPIO的值
int value = XGpioPs_ReadPin(&gpio_mio, key1);
return value;
}
int main()
{
print("====led test====\n\r");
MIO_Config();
while(1)
{
MIO_LED(led1, 0);
sleep(1);
MIO_LED(led1, 1);
sleep(1);
MIO_LED(led2, 0);
sleep(1);
MIO_LED(led2, 1);
sleep(1);
}
return 0;
}
2.测试
先用SDK添加fsbl生成fsbl.elf文件,然后vivado工程生成bit文件,再用上面代码编译生成led.elf文件三者合成为BOOT.bin文件,放到sd卡,选择sd卡启动就可以看到LED1和lLED2交替闪烁
五.linux系统GPIO控制
这里在vivado工程中对GPIO0约束了16个管脚,对GPIO1也约束了16个管脚,配置好linux系统启动文件,进入系统中我们可以在 /sys/class/gpio 目录下看到 3个gpio片 874,890,906
如何进行对应那,首先gpio号最多能够表示1024个,前面说到PS端MIO有54,EMIO64总共118个
- PS端GPIO 906-1024
- AX_GPIO0对应 16个约束管脚 890-905
- AX_GPIO1对应 16个约束管脚 874-889
所以MIO0对应的控制号为GPIO906,MIO1就为907,EMIO约束的第一个GPIO号为GPIO890,第一个就为GPIO891
注意:EMIO最多可约束64个,ax_gpio0 32个,ax_gpio1 32个
这里对控制等的程序不做说明,知道gpio号后,linux下应该层控制gpio方法都是一样的,之前文章有做说明。
六.总结
这里只是粗略的说明了一下ZYNQ7000系列GPIO在裸机和ubuntu系统下的控制,具体的操作流程没用进行说明