本文在一个工程中完成PS和PL之间通过MIO和EMIO实现的四种控制LED的方式,即:
PS控制PS的灯(MIO)
PS控制PL的灯(EMIO)
PL控制PL的灯(EMIO)
PL控制PS的灯(EMIO)
当然了还有AXI接口实现,这里不做讨论。
首先建立工程,打开MIO和EMIO
黑金AX7015开发板按键和LED分布:
核心板:一个PS-LED,一个PL-LED
底板: 一个PS-LED,四个PL-LED,一个PS-KEY,一个PL-KEY
所以这里开了6个EMIO引脚,所有LED低电平点亮,所有KEY按下为低电平。
然后给PL端连接引脚
这里要注意EMIO的GPIO是从54开始的,所以上图的EMIO_0_tri_io[0]这个引脚必须在SDK中定义为54,如下图所示,后面的EMIO_0_tri_io[1]就依次往上加即可。
SDK源码如下,注意使用时先烧录FPGA的bitstream,再Run As SDK的C程序,可能会有按键抖动问题,我们这里不关心。
#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "sleep.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
//全部GPIO pin=118,分布如下
//0 - 31, Bank 0,MIO MIO为真实引脚号
//32 - 53, Bank 1,MIO
//54 - 85, Bank 2,EMIO //EMIO寄存器从54开始编号,并非真实引脚号
//86 - 117, Bank 3,EMIO
#define MIO9_PS_LED 9 //底板PS LED
#define MIO0_PS_LED 0 //核心板PS LED
#define MIO_PS_KEY 11 //PS KEY固定引脚
#define EMIO_PL_KEY 59 //PL KEY
#define EMIO_PL_LED0 55 //核心板PL LED
#define EMIO_PL_LED1 56 //底板PL LED1
#define EMIO_PL_LED2 57 //底板PL LED2
#define EMIO_PL_LED3 58 //底板PL LED3
#define EMIO_PL_LED4 54 //底板PL LED4
int main()
{
XGpioPs_Config* ConfigPtr; //GPIO配置结构体指针
XGpioPs Gpio;
u8 PS_KEY_STATUS;
u8 PS_LED_CNT = 0;
u8 PL_KEY_STATUS;
u8 PL_LED_CNT = 0;
printf("GPIO EMIO\n\r");
//根据器件ID,查找器件的配置信息
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
//初始化GPIO驱动
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
//把KEY的方向设置为输入--0为输入
XGpioPs_SetDirectionPin(&Gpio, MIO_PS_KEY, 0);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_KEY, 0);
//把LED GPIO的方向设置为输出--1为输出
XGpioPs_SetDirectionPin(&Gpio, MIO9_PS_LED, 1);
XGpioPs_SetDirectionPin(&Gpio, MIO0_PS_LED, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_LED0, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_LED1, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_LED2, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_LED3, 1);
XGpioPs_SetDirectionPin(&Gpio, EMIO_PL_LED4, 1);
//设置GPIO的输出使能--1使能
XGpioPs_SetOutputEnablePin(&Gpio, MIO9_PS_LED, 1);
XGpioPs_SetOutputEnablePin(&Gpio, MIO0_PS_LED, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_PL_LED0, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_PL_LED1, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_PL_LED2, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_PL_LED3, 1);
XGpioPs_SetOutputEnablePin(&Gpio, EMIO_PL_LED4, 1);
while(1)
{
PS_KEY_STATUS = XGpioPs_ReadPin(&Gpio, MIO_PS_KEY);
PL_KEY_STATUS = XGpioPs_ReadPin(&Gpio, EMIO_PL_KEY);
if(PS_KEY_STATUS==0)
{
PS_LED_CNT++;
if(PS_LED_CNT > 2)
{
PS_LED_CNT = 0;
//写数据到GPIO的输出引脚--0点亮
XGpioPs_WritePin(&Gpio, MIO9_PS_LED, 1);
XGpioPs_WritePin(&Gpio, MIO0_PS_LED, 1);
}
switch(PS_LED_CNT)
{
case 1: //PS通过MIO控制PS的灯
XGpioPs_WritePin(&Gpio, MIO0_PS_LED, 0);printf("PS_LED_CNT = %d\n\r",PS_LED_CNT);
break;
case 2: //PS通过EMIO控制PL的灯
XGpioPs_WritePin(&Gpio, EMIO_PL_LED0, 0);printf("PS_LED_CNT = %d\n\r",PS_LED_CNT);
break;
default:
break;
}
sleep(1);
}
if(PL_KEY_STATUS==0)
{
PL_LED_CNT++;
if(PL_LED_CNT > 5)
{
PL_LED_CNT = 0;
XGpioPs_WritePin(&Gpio, EMIO_PL_LED0, 1);
XGpioPs_WritePin(&Gpio, EMIO_PL_LED1, 1);
XGpioPs_WritePin(&Gpio, EMIO_PL_LED2, 1);
XGpioPs_WritePin(&Gpio, EMIO_PL_LED3, 1);
XGpioPs_WritePin(&Gpio, EMIO_PL_LED4, 1);
}
switch(PL_LED_CNT)
{
case 1: //PL通过EMIO控制PL的灯
XGpioPs_WritePin(&Gpio, EMIO_PL_LED1, 0);printf("PL_LED_CNT = %d\n\r",PL_LED_CNT);
break;
case 2: //PL通过EMIO控制PS的灯
XGpioPs_WritePin(&Gpio, MIO9_PS_LED, 0);printf("PL_LED_CNT = %d\n\r",PL_LED_CNT);
break;
default:
break;
}
sleep(1);
}
}
return 0;
}