手撕原子弹 发表于 2021-8-30 10:58:07

【Zynq】关于ZYNQ的PS GPIO编程实践(MIO部分)

关于ZYNQ的PS GPIO编程实践(MIO部分)上一篇文章我讲述了如何在Vivado中开启ZYNQ的PS部分自带的GPIO MIO外设。本节我来讲讲如何在SDK中使用ZYNQ自带的库,实现有关GPIO MIO的各种功能。一、如何创建SDK工程1.首先导出已经开启了GPIO MIO功能的硬件平台(关于如何开启GPIO MIO功能请看这篇帖子→点击跳转)。2.然后打开SDK,SDK启动时会自动分析我们导出的硬件平台,生成相应的文件。从名字来看,这些文件与初始化有关,我们暂时不深入展开。3.接着我们按如下步骤创建SDK工程。4.然后在出现的界面输入工程名:PS_GPIO。然后点击Next>按钮。5.在出现的工程模板界面选择空白工程,然后点击“完成”按钮。6.这样,一个工程就创建完成了。我们来观察一下左边的源文件目录。7.这里多了两个文件夹,上面那个是工程文件夹,我们编写的代码和自己添加的库文件都会放在里面。下面那个后缀带有“_bsp”的文件夹是板级支持包(BoardSupport Package),缩写为“BSP”,它里面包含了这个工程的官方库文件以及一些辅助文件,如果没有BSP的话,主程序是无法正常运行的。然后我们点开PS_GPIO文件夹,在下面创建一个C文件来存放主函数代码。8.将这个文件命名为main.c,点击“完成”。二、使用的相关函数讲解
由于本节内容是使用官方自带的库实现有关GPIO MIO的各种功能,因此我们需要先找到官方的GPIO库所在位置PS_GPIO_bsp-> ps7_cortexa9_0 -> libsrc -> gpiops_v3_4。库里面的内容很多,这里只选择最基础的三个部分讲解:(1)初始化GPIO外设。(2)控制特定的GPIO输出高/低电平。(3)读取特定的GPIO采集到的电平高低。1.GPIO初始化,简单理解就是开启GPIO功能的意思。根据官方提供的教程,GPIO初始化分为三步:(1)创建GPIO设备的驱动程序实例以及它的“配置信息”结构体变量;
         XGpioPs Gpio;         XGpioPs_Config *ConfigPtr;
(2)根据GPIO设备的ID查找到它的配置信息,并将配置信息存储在第一步创建的“配置信息”结构体变量中;
         ConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
(3)根据GPIO设备的驱动程序实例和“配置信息”结构体变量完成了Gpio驱动程序的初始化。
         XGpioPs_CfgInitialize(&Gpio,ConfigPtr, ConfigPtr->BaseAddr);
这三步看不懂也没关系,用一句话来解释:在使用GPIO之前,必须先输入这4行代码,否则GPIO无法使用。2.GPIO的写功能,简单理解就是控制某个管脚输出高/低电平。要想使用GPIO输出高/低电平,同样需要三个步骤:(1)设置特定GPIO的方向为“输出”;
         XGpioPs_SetDirectionPin(&Gpio,GPIO的管脚编号, 1);
这里GPIO的管脚标号与MIO编号相等,且范围为0~53。(2)开启这个GPIO的输出使能;
         XGpioPs_SetOutputEnablePin(&Gpio,GPIO的管脚编号, 1);
这里的管脚标号与上一句中的一致。(3)设置这个GPIO输出的电平为高/低。
         XGpioPs_WritePin(&Gpio, GPIO的管脚编号,高电平填1低电平填0);   
这里的管脚标号与上一句中的一致,后面电平自己设置,高电平填1,低电平填0即可。使用这三步就可控制任何GPIO输出高/低电平了。需要注意的是,在使用了上述三句话控制某个GPIO输出某电平后,再想改变此GPIO的电平时可免去(1)(2)语句,直接使用第(3)句即可。一句话解释:先完成GPIO初始化,然后使用上面三句代码即可控制GPIO输出高/低电平,若多次控制同一GPIO管脚进行输出,只需在第一次控制时使用(1)(2)语句,后续直接使用(3)即可改变该管脚输出的电平。3.GPIO的读功能,也就是读取某个管脚的输入电平。读取管脚也只需要三步即可完成:(1)设置某特定的GPIO管脚方向为输入
         XGpioPs_SetDirectionPin(&Gpio,GPIO的管脚编号,0);
(2)创建一个变量来存放读取的电平值。
         u8 State;
(3)读取特定管脚的输入电平值,存放在(2)中创建的变量里。
         State = XGpioPs_ReadPin(&Gpio,GPIO的管脚编号);
“0”表示低电平,“1”表示高电平,由此便可以通过State的值得知电平的高低。三、编程实例设计功能:通过按键控制LED的亮灭,按键按下=灭,按键松开=亮。补充信息:(1)按键绑定在MIO47上,按键按下时,MIO47为低电平,松开为高电平;(2)LED灯绑定在MIO7上,且MIO7为高电平时LED灯亮,低电平时熄灭;这里大家可以先分析一下按键与LED的对应关系:按键按下→MIO47=0→LED灭→MIO7=0,即MIO47=0=MIO7按键松开→MIO47=1→LED亮→MIO7=1,即MIO47=1=MIO7可以很简单得到一个关系:MIO47=MIO7因此思路很明显,读取MIO47的电平值,将其赋予MIO7即可。参考代码:
#include"xgpiops.h"         //GPIO_PS函数相关的头文件
#include"xparameters.h"    //设备信息相关的头文件   
int main(void)
{      
      u8 State;//存放按键(MIO47)的电平状态,0为低电平,1为高电平         
      //GPIO初始化      
      XGpioPs Gpio;      
      XGpioPs_Config *ConfigPtr;      
      ConfigPtr= XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
      XGpioPs_CfgInitialize(&Gpio,ConfigPtr,ConfigPtr->BaseAddr);      
      //设置LED(MIO7)为输出并且初始为低电平      
      XGpioPs_SetDirectionPin(&Gpio,7,1);   //设置GPIO7方向为输出(0为输入,1为输出)
      XGpioPs_SetOutputEnablePin(&Gpio,7,1); //开启GPIO7的输出功能(0为关闭,1为开启)
      XGpioPs_WritePin(&Gpio,7,0);          //设定GPIO7输出低电平(0为低电平,1为高电平)
      //设置按键(MIO47)为输入
      XGpioPs_SetDirectionPin(&Gpio,47,0);//设置GPIO47方向为输入(0为输入,1为输出)
      while(1)
      {
                State = XGpioPs_ReadPin(&Gpio,47); //读取GPIO47的电平值并存储到State变量里
                XGpioPs_WritePin(&Gpio,7,State);//将State变量的值赋予GPIO7来输出   
      }

      return 0;
}
页: [1]
查看完整版本: 【Zynq】关于ZYNQ的PS GPIO编程实践(MIO部分)