k在ZYQN7000系类芯片上,总共有54个MIO(multiuse I/O)供用户使用,这些IO口与PS直接相连,也就是直接连接在内核上,不需要添加引脚约束就。对他们的操作可以看作是只对PS的操作,与PL部分无关。他们位于GPIO的Bank0和Bank1隶属于PS的部分。
GPIO 的控制和状态寄存器基地址为:0xE000_A000
Bank0:MIO [31:0] GPIO PIN
脚号:
0~31
Bank1:MIO[32:53] GPIO PIN
脚号:
32~53
DATA_RO:
此寄存器使能软件观察
PIN
脚,当
GPIO
被配置成输出的时候,这个寄存器的值会反应输出的
PIN
脚情
况。
DATA:
此寄存器控制输出到
GPIO
的值,读这个寄存器的值可以读到最后一次写入该寄存器的值。
MASK_DATA_LSW:
位操作寄存器,写入
GPIO
低
16bit
其他没有改变的位置保存原先的状态
MASK_DATA_MSW:
位操作寄存器,写入
GPIO
高
16bit
其他没有改变的位置保存原先的状态
DIRM:
此寄存器控制输出的开关,当
DIRM[x]==0
时候,禁止输出
OEN:
输出使能,当
OEN[x]==0
的时候输出关闭,
PIN
脚处于三态
因 此 , 如 果 要 读
IO
状 态 就 得 读
DATA_RO
的 值 , 如 果 是 对 某 一 位 进 行 操 作 就 是 写
MASK_DATA_LSW/MASK_DATA_MSW
接下来进入实战部分,我们的目的是通过软核直接控制这个MIO扣,来点亮LED灯
首先和第一节将的一样建立一个FPGA工程
在这里不同的地方是在配置IP核的时候,我们需要配置上MIO口
后面仍然和上一篇文章一样,编译工程,生成bit文件,再将bit文件导入到SDK中接下来进行软件的设计。
在本次设计中,我们用到了更GPIO相关的文件和延时文件。所以去gpios和standalone中找相关函数。
调用了xgpios.h 和 sleep.h两个头文件,分别调用了里面声明的GPIO相关函数和延时函数。
#include "xgpiops.h"
#include "sleep.h"
int main()
{
static XGpioPs psGpioInstancePtr;
XGpioPs_Config* GpioConfigPtr;
int iPinNumber= 7; //LD9连接的是MIO7
u32 uPinDirection = 0x1; //1表示输出,0表示输入
int xStatus;
首先是
static XGpioPs psGpioInstancePtr; 这是一个指针实例,指向添加的 GPIO 端口。
其中XGpioPs是一个自定义的结构体,里面存放着各种配置IO口的信息。
结构体包含
GPIO
一些参数,分别是:
typedef struct {
XGpioPs_Config GpioConfig; /**<
设备配置
*/
u32 IsReady; /**<设备是否初始化并准备好
*/
XGpioPs_Handler Handler; /**<
所有状态的处理程序
*/
void *CallBackRef; /**<块处理程序的回调
*/
u32 Platform; /**<设备数据
*/
u32 MaxPinNum; /**< GPIO 的最大
pin
数量
*/
u8 MaxBanks; /**< GPIO 的最大的
bank
数量
*/
} XGpioPs;
下一步XGpioPs_Config* GpioConfigPtr;不难看出这是一个指针实例化,重点在这个指针的类型。
查看XGpioPs_Config我们得知此结构体存放的是 GPIO 的设备地址和基地址。所以着是一个指向要进行初始化的IO口的指针
int iPinNumber= 7;
这一句就很好理解了,这是声明了一个参数,方便我们在后期初始化IO口的时候使用,因为本次实验使用的IO口为7口,所以这里Pin的参数设置为7.
u32 uPinDirection = 0x1; //1表示输出,0表示输入
这里再进行IP核配置的时候,我们观察到7口是一个out口,所以这里把方向设置为输出。