mpsoc嵌入式vitis开发—外部中断实验
前言
vitis版本:Vitis 2023.2
由于Vitis版本更新,很多API发生变化,学习原子哥的教程时很多代码对于不上,所以自己重新写一遍,并记录下自己踩过的坑,方便以后查看。这里直接给出代码,其他的流程参考原子哥的《2_DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南_V1.0.pdf》
代码
#include "platform.h"
#include "sleep.h"
#include "xgpiops.h"
#include "xil_printf.h"
#include "xinterrupt_wrap.h"
#include "xparameters.h"
#include "xplatform_info.h"
#include "xscugic.h"
#include "xstatus.h"
#include <stdio.h>
#include <xil_printf.h>
#define XGPIOPS_BASEADDR XPAR_XGPIOPS_0_BASEADDR
#define GPIO_BANK XGPIOPS_BANK1 /* Bank 0 of the GPIO Device */
#define MIOLED0 38
#define MIOLED1 39
#define KEY 40
static void irq_hander(void *CallBackRef, u32 Bank, u32 Status);
XGpioPs Gpio;
u32 key_press;
u32 key_val;
int main(void) {
int Status;
XGpioPs_Config *ConfigPtr;
printf("MIO Test! \r\n");
ConfigPtr = XGpioPs_LookupConfig(XGPIOPS_BASEADDR);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
printf("MIO Cfg Fail! \r\n");
return XST_FAILURE;
}
XGpioPs_SetDirectionPin(&Gpio, KEY, 0);
XGpioPs_SetDirectionPin(&Gpio, MIOLED0, 1);
XGpioPs_SetOutputEnablePin(&Gpio, MIOLED0, 1);
XGpioPs_WritePin(&Gpio, MIOLED0, 0x1);
XGpioPs_SetDirectionPin(&Gpio, MIOLED1, 1);
XGpioPs_SetOutputEnablePin(&Gpio, MIOLED1, 1);
XGpioPs_WritePin(&Gpio, MIOLED1, 0x1);
/* 变化最大的是这里,旧版API采用的是XScuGic_Connect 函数建立中断源 ID 与识别中断时要运行的关联处理程序之间的连接
* 新版API大幅度简化了中断函数实现,通过XSetupInterruptSystem 函数一键完成中断实现,十分方便。
*/
/* Enable falling edge interrupts for all the pins in GPIO bank. */
XGpioPs_SetIntrTypePin(&Gpio, KEY, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
/* Set the handler for gpio interrupts. */
XGpioPs_SetCallbackHandler(&Gpio, (void *)&Gpio, irq_hander);
XGpioPs_IntrEnablePin(&Gpio, KEY);
Status =
XSetupInterruptSystem(&Gpio, &XGpioPs_IntrHandler, ConfigPtr->IntrId,
ConfigPtr->IntrParent, XINTERRUPT_DEFAULT_PRIORITY);
if (Status != XST_SUCCESS) {
printf("MIO Cfg Fail! \r\n");
return XST_FAILURE;
}
printf("MIO IRQ Success! \r\n");
while (1) {
if (key_press) {
usleep(20000);
if (XGpioPs_ReadPin(&Gpio, KEY) == 0) {
key_val = ~key_val;
printf("key_val = %d\r\n", key_val);
}
key_press = FALSE;
XGpioPs_IntrEnablePin(&Gpio, KEY);
}
XGpioPs_WritePin(&Gpio, MIOLED0, XGpioPs_ReadPin(&Gpio, KEY));
}
return XST_SUCCESS;
};
static void irq_hander(void *CallBackRef, u32 Bank, u32 Status) {
XGpioPs *GpioPtr = (XGpioPs *)CallBackRef;
u8 BankNumber,PinNumberInBank;
XGpioPs_GetBankPin(KEY, &BankNumber, &PinNumberInBank);
if((Bank == BankNumber) && (Status & (1 << PinNumberInBank)))
{
key_press = TRUE;
XGpioPs_IntrDisablePin(GpioPtr, KEY);
}
/* 这里需要注意的是,通过XSetupInterruptSystem建立的中断,会自动清除Status,因此无法使用XGpioPs_IntrGetStatusPin */
// if (XGpioPs_IntrGetStatusPin(gpio, KEY))
// {
// key_press = TRUE;
// XGpioPs_IntrDisablePin(gpio, KEY);
// }
};