您当前的位置: 首页 > 

刘颜儿

暂无认证

  • 4浏览

    0关注

    99博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

FPGA入门例程:PL按键中断

刘颜儿 发布时间:2022-06-11 16:40:47 ,浏览量:4

前言

学了一个东西,及时用起来,给自己出难题,玩点花的,把知识反复摩擦后,就不容易忘记了

实验

实验目标:每按下一次按键,LED反转一次。即:用PL端的4个按键分别控制PL端的4个LED,按键作为外部中断信息,将中断信号传输给PS,然后PS控制GPIO实现LED反转。

中断:用通俗易懂的话来说,就是本来在吃饭,听到敲门,去开了门后,回来接着刚刚的饭继续吃,停下一件事,去做另一件,做完后回来继续做最开始的那件事

下面是使用的zynq7000-AX7350开发板的led与按键的分布 在这里插入图片描述 本实验中,按键按下,中断发送,因此中断来自PL端

硬件部分

引入ZYNQ的IP核,双击配置处理器的中断 在这里插入图片描述 右键ZYNQ,引出4个端口,连接4个按键 在这里插入图片描述 由于需要使用按键,因此要进行按键消抖 于是我将之前写过的按键消抖代码生成一个IP核 IP核生成的步骤参照:自定义IP核 但是IP核的输入输出都是一位的,而此处有4个按键输入,因此需要用到:拼接IP核、拆分IP核 这两个IP核长这个样子 在这里插入图片描述 使用IP核将按键输入先拆分,然后合并,最后将PL按键信息输入到PS 在这里插入图片描述 当PS得到按键信息后,PS内部通过中断控制ID号,找到对应的中断函数,将点灯信息通过AXI总线传给GPIO,然后上面的GPIO实现点灯操作(GPIO部分的教程在【2】第十章用PS点亮PL端的LED) 下面就是软件,通过vitis网PS中写代码

软件部分

在vitis中修改原有的模板为:

#include 
#include "platform.h"
#include "xil_printf.h"

#include "xil_io.h"
#include "xparameters.h"
#include "xscugic.h"

#define INTC_DEVICE_ID	XPAR_SCUGIC_SINGLE_DEVICE_ID
#define XIL_EXCEPTION_ID_INT	XIL_EXCEPTION_ID_IRQ_INT
#define INTC_HANDLER	XScuGic_InterruptHandler
XScuGic Intc;

void Key1Handler(void *CallbackRef)
{

	u32 io = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR);
	if(io&0x01){
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io&(~0x01));
	}
	else{
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io|0x01);
	}
}
void Key2Handler(void *CallbackRef)
{
	u32 io = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR);
	if(io&0x02){
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io&(~0x02));
	}
	else{
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io|0x02);
	}
}
void Key3Handler(void *CallbackRef)
{
	u32 io = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR);
	if(io&0x04){
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io&(~0x04));
	}
	else{
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io|0x04);
	}
}
void Key4Handler(void *CallbackRef)
{
	u32 io = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR);
	if(io&0x08){
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io&(~0x08));
	}
	else{
		Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR,io|0x08);
	}
}
int main()
{
    init_platform();
    int i;
    int Result;
    XScuGic_Config *IntcConfig;

	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}
	Result = XScuGic_CfgInitialize(&Intc, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Result != XST_SUCCESS) {
		return XST_FAILURE;
	}
	XScuGic_SetPriorityTriggerType(&Intc, 61,
					0xA0, 0x3);
	XScuGic_SetPriorityTriggerType(&Intc, 62,
					0xA0, 0x3);
	XScuGic_SetPriorityTriggerType(&Intc, 63,
					0xA0, 0x3);
	XScuGic_SetPriorityTriggerType(&Intc, 64,
					0xA0, 0x3);
	Result = XScuGic_Connect(&Intc, 61,
				 (Xil_ExceptionHandler)Key1Handler, 0);
	Result = XScuGic_Connect(&Intc, 62,
				 (Xil_ExceptionHandler)Key2Handler, 0);
	Result = XScuGic_Connect(&Intc, 63,
				 (Xil_ExceptionHandler)Key3Handler, 0);
	Result = XScuGic_Connect(&Intc, 64,
				 (Xil_ExceptionHandler)Key4Handler, 0);
	if (Result != XST_SUCCESS) {
		return Result;
	}

	XScuGic_Enable(&Intc, 61);
	XScuGic_Enable(&Intc, 62);
	XScuGic_Enable(&Intc, 63);
	XScuGic_Enable(&Intc, 64);

	Xil_ExceptionInit();

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			 (Xil_ExceptionHandler)INTC_HANDLER, &Intc);

	Xil_ExceptionEnable();

    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+0x04,0x00);

    while(1){
    }
    print("Hello World\n\r");
    print("Successfully ran Hello World application");
    cleanup_platform();
    return 0;
}
上板测试

请添加图片描述

关注
打赏
1659364566
查看更多评论
立即登录/注册

微信扫码登录

0.0394s