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); 
  // }
  
};
posted @ 2024-02-21 10:25  USTHzhanglu  阅读(108)  评论(0编辑  收藏  举报