GPIO驱动
MIO和EMIO都是一样的模式。
#include "xparameters.h"
#include "xgpiops.h"
#include <xil_printf.h>
#include "sleep.h"
XGpioPs Gpio; /* The driver instance for GPIO Device. */
int main(void)
{
XGpioPs_Config *ConfigPtr;
int Status;
u32 InputData;
/* Initialize the GPIO driver. */
ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
ConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//MIO7 输出
XGpioPs_SetDirectionPin(&Gpio, 7, 1);
XGpioPs_SetOutputEnablePin(&Gpio, 7, 1);
XGpioPs_WritePin(&Gpio, 7, 0);
//MIO50输入
XGpioPs_SetDirectionPin(&Gpio, 50, 0);
InputData = XGpioPs_ReadPin(&Gpio, 50);
xil_printf("GPIO initial completed!\n\r");
while(1){
InputData = XGpioPs_ReadPin(&Gpio, 50);
if(InputData)
XGpioPs_WritePin(&Gpio, 7, 1);
else
XGpioPs_WritePin(&Gpio, 7, 0);
sleep(1);
}
return XST_SUCCESS;
}
GPIO中断
外设IO也是可以中断的。
中断ID号文件在 "xparameters_ps.h"中。
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include <xil_printf.h>
#include "sleep.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR
#define GPIO_BANK XGPIOPS_BANK1 /* Bank 0 of the GPIO Device */
static int GpioInitial(XGpioPs *Gpio, u16 DeviceId);
void IntrHandler();
static int SetupInterruptSystem(XScuGic *Intc, XGpioPs *Gpio, u16 GpioIntrId);
static XGpioPs Gpio; /* The Instance of the GPIO Driver */
static XScuGic Intc; /* The Instance of the Interrupt Controller Driver */
static u32 Input_Pin = 50; /* Switch button */
static u32 Output_Pin = 7; /* LED button */
int key_press;
int main(void)
{
int Status;
int led_value;
xil_printf("GPIO Interrupt Example Test \r\n");
Status = GpioInitial(&Gpio, GPIO_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("GPIO Initial Failed\r\n");
return XST_FAILURE;
}
else
xil_printf("GPIO Initial completed!\r\n");
Status = SetupInterruptSystem(&Intc, &Gpio, GPIO_INTERRUPT_ID);
if (Status != XST_SUCCESS) {
xil_printf("GPIO Initial Failed\r\n");
return XST_FAILURE;
}
else
xil_printf("Interrupt Initial completed!\r\n");
while(1){
if(key_press) {
led_value = ~led_value;
key_press = 0;
// 清除之前的中断状态 (写1时清除)
XGpioPs_IntrClearPin(&Gpio, Input_Pin);
// 将led_value的值写入LED
XGpioPs_WritePin(&Gpio, Output_Pin, led_value);
// 延时消抖
usleep(200000);
XGpioPs_IntrEnablePin(&Gpio, Input_Pin);
}
}
return XST_SUCCESS;
}
int GpioInitial(XGpioPs *Gpio, u16 DeviceId)
{
XGpioPs_Config *ConfigPtr;
int Status;
/* Initialize the Gpio driver. */
ConfigPtr = XGpioPs_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
XGpioPs_CfgInitialize(Gpio, ConfigPtr, ConfigPtr->BaseAddr);
/* Run a self-test on the GPIO device. */
Status = XGpioPs_SelfTest(Gpio);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Set the direction for the specified pin to be input */
XGpioPs_SetDirectionPin(Gpio, Input_Pin, 0x0);
/* Set the direction for the specified pin to be output. */
XGpioPs_SetDirectionPin(Gpio, Output_Pin, 1);
XGpioPs_SetOutputEnablePin(Gpio, Output_Pin, 1);
XGpioPs_WritePin(Gpio, Output_Pin, 0x0);
return XST_SUCCESS;
}
static int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
u16 GpioIntrId)
{
int Status;
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
// 初始化ARM处理器异常句柄
Xil_ExceptionInit();
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
Status = XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
// 来给 IRQ 异常注册处理程序
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)Gpio);
// 关联中断处理函数
XScuGic_Connect(GicInstancePtr, GpioIntrId,
(Xil_ExceptionHandler)IntrHandler,
(void *)Gpio);
// 设置MIO引脚中断触发类型:下降沿 修改为上升沿
//XGpioPs_SetIntrType(Gpio, GPIO_BANK, 0x00, 0xFFFFFFFF, 0x00);
XGpioPs_SetIntrTypePin(Gpio, Input_Pin, XGPIOPS_IRQ_TYPE_EDGE_RISING);
XGpioPs_SetCallbackHandler(Gpio, (void *)Gpio, IntrHandler);
//XGpioPs_IntrEnable(Gpio, GPIO_BANK, (1 << Input_Pin));
XGpioPs_IntrEnablePin(Gpio, Input_Pin);// 打开MIO引脚中断使能信号
XScuGic_Enable(GicInstancePtr, GpioIntrId);// 为GPIO器件使能中断
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);// 使能处理器的中断
return XST_SUCCESS;
}
/****************************************************************************/
/**
* This function is the user layer callback function for the bank 1 interrupts of
* the GPIO device. It checks if all the switches have been pressed to stop the
* interrupt processing and exit from the example.
*
* @param CallBackRef is a pointer to the upper layer callback reference.
* @param Status is the Interrupt status of the GPIO bank.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void IntrHandler()
{
xil_printf("interrupt detected!\n\r");
key_press = 1;
XGpioPs_IntrDisablePin(&Gpio, Input_Pin);
}
AXI GPIO
#include "xparameters.h"
#include "xgpio.h"
#include <xil_printf.h>
// channel1
#define BTN_CHANNEL 1
// channel2
#define LED_CHANNEL 2
XGpio Gpio;
int main(void)
{
int Status;
u32 Btn_val;
/* 初始化 GPIO 驱动 */
Status = XGpio_Initialize(&Gpio, XPAR_AXI_GPIO_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("Gpio Initialization Failed\r\n");
return XST_FAILURE;
}
else xil_printf("Gpio Initialization completed!\r\n");
/* 设置gpio的信号方向,设置0为输出, 设置1为输入.*/
XGpio_SetDataDirection(&Gpio, BTN_CHANNEL, 1);
XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
while(1)
{
Btn_val=XGpio_DiscreteRead(&Gpio, BTN_CHANNEL);
switch (Btn_val){
case 0x00: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0xff);break;
case 0x01: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x01);break;
case 0x02: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x02);break;
case 0x04: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x04);break;
case 0x08: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x08);break;
case 0x10: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x10);break;
default: XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0xff);
}
}
}