ZYNQ开发(二)GPIO配置

GPIO的结构体系

zynq的GPIO,分为两种,MIO(multiuse I/O)和EMIO(extendable multiuse I/O)。

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的组成

图1 GPIO的组成

GPIO的内部结构和内部数据流及寄存器结构如图2所示。上半部分为GPIO中断相关的寄存器,下半部分为GPIO查询方式读写的寄存器。

图2 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时,输出无效。

GPIO使用实例

ZYNQ核的添加及配置

Step1:新建一个名为为Miz701_sys的工程

Step2:选择RTL Project 勾选Do not specify source at this time

Step3:选择芯片型号xc7z010clg400-1

Step4:单击Finish

使用IP Integrator创建硬件系统

Step1:单击Create Block Design

Step2:输入system

Step3:添加IP按钮

Step4:搜素单词z选择ZYNQ7 Processing System,然后双击

Step5:添加进来了ZYNQ CPU IP,双击ZYNQ CPU IP。

Step6: 修改时钟输入为50MHZ,可以看到ARM时钟为650MHZ DDR为525MHZ(1050MHZ),并且修改FCLK_CLK0 为100MHZ

step7:修改内存型号为MT41K256M16RE-125 M,单击OK。

Setp8:选择MIO Configuration选项卡,再看到I/O Peripherals 中的GPIO一栏,勾选上其中的EMIO一栏,并选择4位引脚输出(最多可以选择64位,但是这个使用只需要4位足够了)。

Setp9:按照上图设置好了之后,点击OK,仔细观察发现的zynq核心多出一组引脚名为GPIO_0,这个正是我们刚刚设置的一组EMIO,我们右击该引脚,选择make external把GPIO_0引脚引出(或者单击该引脚处,按快捷键Ctrl +t,也可以将引脚引出)。效果如下图所示:

step10::单击Run Block Automation 进行自动连线,VIVADO软件会根据信号的命名规则智能连线。

Step11:在你点击了OK后,你会发现DDR以及FICED_IO自动的延伸出来,然后把时钟FCLK_CLK0和M_AXI_GPI0_ACLK连接,其实就是给M_AXI_GP0_ACLK提供一个时钟。方法:当把鼠标靠近的时候会自动连接。

产生HDL和约束文件

Setp1:接下来依然是,右键单击Block文件,文件选择Generate the Output Products,是文件得到一定的约束。

Setp2:弹出如下对话框,直接点击Generate

Setp3:继续右键单击Block文件,选择Create a HDL wrapper,根据Block文件内容产生一个HDL 的顶层文件:

Setp4:并选择让vivado自动完成

Setp5:这里我们看到,Vivado给我创建了这样的顶层文件,其中的gpio_0_tri_io就是我们配置的EMIO

EMIO的管脚约束修改

我们发现,之前引出的EMIO叫做GPIO_0,到了顶层他的名字gpio_0_tri_io,而不是GPIO_0。所以分配引脚的时候就要注意了名字别错了,创建一个约束文件,分配引脚如下:

产生bit文件

此时可以,开始生成bit文件了:

导出bit文件

编译成功之后,依然是导出硬件:

加载到SDK

通过4个GPIO口输出高低电平到引出的引脚上。

配置GPIO的步骤如下:

通过GPIO的外设ID找到对应的外设信息;

填充GPIO外设寄存器基地址和一些相关信息;

配置GPIO口的方向为输出方向;

配置GPIO口的输出使能;

设置GPIO口输出高低电平;

打开SDK,然后新建一个工程,以及添加一个main.C文件。

添加程序如下:

文章转载自:FPGA技术联盟

推荐阅读