前言
学了一个东西,及时用起来,给自己出难题,玩点花的,把知识反复摩擦后,就不容易忘记了
实验实验目标:每按下一次按键,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;
}
上板测试