ZYNQ7000-GPIO EMIO中断实验 程序烧写后自动进一次中断的怪现象

试验硬件:正点原子领航者ZYNQ开发板(芯片xc7z020clg400-2)

试验软件:Vivado 2020.2与Vitis 2020.2

Vivado中的Block Design:

image-20210331205448865

打开UART0,打开MIO与EMIO,EMIO位宽为1,正确设置DDR型号,设置FCLK为50MHz,VIO输出与EMIO输入对接,此时无需指定EMIO引脚,VIO输出默认为0。

Vitis中的代码:

#include "xil_printf.h"
#include "xgpiops.h"
#include "sleep.h"
#include "xparameters.h"
#include "xscugic.h"

#define EMIO0 54U

XGpioPs psGpio;

XScuGic scuGic;

void psGpio_Handler(void *CallBackRef);

int main(void)
{
	xil_printf("begin!\r\n");

	// 初始化psGpio
	XGpioPs_Config *psGpio_configPtr;
	psGpio_configPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
	XGpioPs_CfgInitialize(&psGpio, psGpio_configPtr, psGpio_configPtr->BaseAddr);

	// 打开系统的中断处理功能
	Xil_ExceptionInit(); // 初始化异常句柄,只在很早版本的bsp中需要,此处为了兼容性保留
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler,
			                     &scuGic); // 为IRQ注册中断处理程序
	Xil_ExceptionEnable(); // 使能系统中断功能

	// 初始化中断控制器
	XScuGic_Config *scuGic_config;
	scuGic_config = XScuGic_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID); // 根据器件ID查找配置
    XScuGic_CfgInitialize(&scuGic, scuGic_config, scuGic_config->CpuBaseAddress);

    // 关联中断处理函数
	XScuGic_Connect(&scuGic, XPAR_XGPIOPS_0_INTR, (Xil_ExceptionHandler)psGpio_Handler, (void *)&psGpio);
	// 启用对应中断ID的中断源
	XScuGic_Enable(&scuGic, XPAR_XGPIOPS_0_INTR);

	// 注意psGPIO中断不需要设置中断优先级

	// 设置psGPIO中断类型
	XGpioPs_SetIntrTypePin(&psGpio, EMIO0, XGPIOPS_IRQ_TYPE_EDGE_RISING);
	// 使能psGPIO中断
	XGpioPs_IntrEnablePin(&psGpio, EMIO0);

	while(1)
	{

	}

	return 0;
}


void psGpio_Handler(void *CallBackRef)
{
	XGpioPs *psGpioPtr = (XGpioPs *)CallBackRef;

	if (XGpioPs_IntrGetStatusPin(psGpioPtr, EMIO0) == TRUE)
	{
		xil_printf("This is EMIO0 Interrupt!\r\n");
		XGpioPs_IntrClearPin(psGpioPtr, EMIO0);
	}
}

试验现象:

EMIO烧写时有时自动进一次中断)

此时ZYNQ的启动方式为QSPI,也就是从FLASH启动。

可以看到第一次烧写打印了"This is EMIO Interrupt",这表示烧写后自动进了一次中断,而第二次烧写则未打印,表明烧写未进入此中断。不进中断才是对的。

当设置启动方式为JTAG,从JTAG启动后,看一下这种情况会不会消失。

JTAG模式下EMIO烧写时不会自动进一次中断

从上图可见,设置为JTAG启动后,烧写后不会自动触发一次EMIO中断了。

还有一种更通用的办法是在GPIO PIN中断使能之前,先清除一次中断状态,也可以防止烧写自动进一次EMIO中断,即加入一行代码:

XGpioPs_IntrClearPin(&psGpio, EMIO0);

如下:

	// 设置psGPIO中断类型
	XGpioPs_SetIntrTypePin(&psGpio, EMIO0, XGPIOPS_IRQ_TYPE_EDGE_RISING);
	// 使能之前先清除中断状态!
	XGpioPs_IntrClearPin(&psGpio, EMIO0);
	// 使能psGPIO中断
	XGpioPs_IntrEnablePin(&psGpio, EMIO0);

推测造成这种现象的原因是烧写前EMIO被FLASH中的程序控制着,可能中断状态就是1,而烧写也没有清除中断状态寄存器,所以烧写后自动进了一次中断,所以QSPI模式出现此问题,而JTAG模式不出现。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值