【Ultrascale+ MPSOC学习记录】8、PS端的MIO使用-KEY

前一篇文章描述了GPIO输出的用法,也就是点LED灯:
【Ultrascale+ MPSOC学习记录】7、PS端的MIO使用-LED
这篇文章接着前面的步骤,把输入用起来,也是就KEY;

我们先想一下我们要实现什么功能,输入IO的检测一般可以用轮训方式,或者用中断方式来检测,轮训就是不停去查1还是0,这就不去玩了,我们直接看怎么用中断方式。

原理

先看GPIO的图:
在这里插入图片描述
我们可以看到中断可以设置中断类型,也是就高低电平、上升沿下降沿等;还有清除中断、使能中断等。

我们直接基于前面文章的hello工程,然后增加IO中断检测代码:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"

XGpioPs Gpio;	  /* The driver instance for GPIO Device. */
XScuGic INTCInst;

int key_flag ;
static u32 Output_Pin = 40; /* LED */
static u32 Input_Pin = 26; /* button */

int IntrInitFuntion(XScuGic *InstancePtr, u16 DeviceId, XGpioPs *GpioInstancePtr);
void GpioHandler(void *CallbackRef);

int main()
{
	XGpioPs_Config *ConfigPtr;
	volatile int Delay;

    init_platform();

    print("Hello World\n\r");

    ConfigPtr = XGpioPs_LookupConfig(0);
    XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);

	XGpioPs_SetDirectionPin(&Gpio, Output_Pin, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, Output_Pin, 1);

	XGpioPs_SetDirectionPin(&Gpio, Input_Pin, 0);
	XGpioPs_SetIntrTypePin(&Gpio, Input_Pin, XGPIOPS_IRQ_TYPE_EDGE_RISING);
	XGpioPs_IntrEnablePin(&Gpio, Input_Pin);

	IntrInitFuntion(&INTCInst, XPAR_XGPIOPS_0_DEVICE_ID, &Gpio) ;

	for(;;){
		XGpioPs_WritePin(&Gpio, Output_Pin, 0x0);
		for (Delay = 0; Delay < 10000000; Delay++);
		XGpioPs_WritePin(&Gpio, Output_Pin, 0x1);
		for (Delay = 0; Delay < 10000000; Delay++);
		if(key_flag){
			print("Key Press\n\r");
			key_flag = 0;
		}
	}

    cleanup_platform();
    return 0;
}

int IntrInitFuntion(XScuGic *InstancePtr, u16 DeviceId, XGpioPs *GpioInstancePtr)
{
	XScuGic_Config *IntcConfig;
	int Status ;
	/*
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);

	Status = XScuGic_CfgInitialize(InstancePtr, IntcConfig, IntcConfig->CpuBaseAddress) ;
	if (Status != XST_SUCCESS)
		return XST_FAILURE ;

	/*
	 * set priority and trigger type
	 */
	XScuGic_SetPriorityTriggerType(InstancePtr, XPAR_XGPIOPS_0_INTR,
			0xA0, 0x3);
	/*
	 * Connect the device driver handler that will be called when an
	 * interrupt for the device occurs, the handler defined above performs
	 * the specific interrupt processing for the device.
	 */
	Status = XScuGic_Connect(InstancePtr, XPAR_XGPIOPS_0_INTR,
			(Xil_ExceptionHandler)GpioHandler,
			(void *)GpioInstancePtr) ;
	if (Status != XST_SUCCESS)
		return XST_FAILURE ;

	/*
	 * Enable the interrupt for the device.
	 */
	XScuGic_Enable(InstancePtr, XPAR_XGPIOPS_0_INTR) ;

	Xil_ExceptionInit();

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler)XScuGic_InterruptHandler,
			InstancePtr);
	Xil_ExceptionEnable();

	return XST_SUCCESS ;

}

void GpioHandler(void *CallbackRef)
{
	XGpioPs *GpioInstancePtr = (XGpioPs *)CallbackRef ;
	int Int_val ;

	Int_val = XGpioPs_IntrGetStatusPin(GpioInstancePtr, Input_Pin) ;
	/*
	 * Clear interrupt.
	 */
	XGpioPs_IntrClearPin(GpioInstancePtr, Input_Pin) ;
	if (Int_val)
		key_flag = 1 ;
}

然后直接上板验证,成功实现按钮一按,打印一个提示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值