ZYNQ的GPIO
1 GPIO的结构体系
ZYNQ的GPIO由4个BANK组成,其体系结构如图1所示。其中Bank0有32个GPIO引脚,Bank1有22个引脚,共54个GPIO引脚直接通过MIO连接到PS上,每个引脚可以通过寄存器的设置来确定该引脚为输入、输出或者中断,因为54个MIO引脚直接连接在PS上,像其他普通ARM一样,不需要通过XPS进行硬件配置,直接通过SDK编程即可。
Bank2和Bank3通过EMIO接口将CPU的GPIO连接到PL部分的引脚上,其中每个Bank各有32个引脚,通过EMIO扩展的GPIO连接到PL上,可以在PL部分进行逻辑设计,进行特定功能的IP核制定。然后在PS部分,像控制普通MIO一样进行编程。因此,使用EMIO引脚必须通过XPS进行硬件配置,然后在PS部分使用SDK进行编程控制。
图1 GPIO的组成
GPIO的内部结构和内部数据流及寄存器结构如图2所示。上半部分为GPIO中断相关的寄存器,下半部分为GPIO查询方式读写的寄存器。
图2 GPIO寄存器数据流组成
DATA_RO寄存器是读取GPIO引脚值寄存器,不论该GPIO引脚配置为输入还是输出,都能正确读取该GPIO引脚值。如果该引脚的功能没有配置成GPIO功能,读取的值为随机值,因为该寄存器只能读取GPIO引脚值。
DATA寄存器的值是要输出到GPIO引脚上的数值,当读取该寄存器的数值时,结果是前一次写入DATA寄存器里的数值,而不是当前GPIO引脚的数值。
MASK_DATA_LSW和MASK_DATA_MSW寄存器是传统的数据寄存器(DATA)和屏蔽寄存器(MASK)的结合,该寄存器32位,分成高16位和低16位,其中高16位作为传统的MASK使用,低16位作为传统的DATA使用。因此,MASK_DATA_LSW是对GPIO的16位引脚进行设置和屏蔽寄存器。当某位在MASK_DATA_LSW高16位屏蔽时,即使修改MASK_DATA_LSW低16位的数据,也不影响该位GPIO值。
DIRM寄存器是方向控制寄存器,控制GPIO的输入或者输出,该寄存器值不影响输入,即GPIO输入功能始终有效。
OEN寄存器是输出时能寄存器,当GPIO引脚被配置成输出引脚时,该寄存器控制该引脚是否输出;当GPIO引脚被配置成输出禁止时,该引脚为三态;当OEN[x] = 0时,输出无效。
2 GPIO使用实例
实例内容:通过4个GPIO口输出高低电平到引出的引脚上。
配置GPIO的步骤如下:
- 通过GPIO的外设ID找到对应的外设信息;
- 填充GPIO外设寄存器基地址和一些相关信息;
- 配置GPIO口的方向为输出方向;
- 配置GPIO口的输出使能;
- 设置GPIO口输出高低电平;
程序源码:
//find device
mGpioPsConfig = XGpioPs_LookupConfig(XPAR_AXI_GPIO_0_DEVICE_ID);
//GPIO data config
XGpioPs_CfgInitialize(&GPIO, mGpioPsConfig,mGpioPsConfig->BaseAddr);
//set gpio direction
XGpioPs_SetDirection(&GPIO,20, 1);
//set gpio output enable
XGpioPs_SetOutputEnable(&GPIO,20, 1);
//set gpio high
XGpioPs_WritePin(&GPIO,20,1);