ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭

前面我们介绍了按键中断,其实我们稍作修改就可以用按键控制LED了。做个小实验,两个按键分别控制两个led亮灭。

板子:zc702。


硬件部分

添加zynq核:

勾选串口用于打印信息,勾选EMIO,我们控制两个led,所以需要2bit

ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭_第1张图片

PL 到PS的中断勾选上:
ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭_第2张图片

PL时钟什么的都用不到,我们用的按键不需要时钟,EMIO属于PS。

再添加一个concat IP用于合并两路按键信号:

ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭_第3张图片

最后连接完的系统:

ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭_第4张图片

In0,In1和GPIO_0需要自己右键make external。

生成顶层文件。

添加约束文件:

在顶层模块找到相应的信号名称,将SW0,SW1连接到SW5,SW7;将GPIO[1:0]连接到两个led:

#GPIO PMOD1  
set_property PACKAGE_PIN E15 [get_ports {gpio_0_tri_io[0]}]  
set_property IOSTANDARD LVCMOS25 [get_ports {gpio_0_tri_io[0]}]  
set_property PACKAGE_PIN D15 [get_ports {gpio_0_tri_io[1]}]  
set_property IOSTANDARD LVCMOS25 [get_ports {gpio_0_tri_io[1]}]

#SW5 SW7
set_property PACKAGE_PIN G19 [get_ports {SW0[0]}]  
set_property IOSTANDARD LVCMOS25 [get_ports {SW0[0]}]  
set_property PACKAGE_PIN F19 [get_ports {SW1[0]}]  
set_property IOSTANDARD LVCMOS25 [get_ports {SW1[0]}]  
生成bit文件。打开SDK。


软件部分

原理就是产生中断后在中断处理程序里完成控制led的操作。

#include 
#include "xscugic.h"
#include "xil_exception.h"
#include "xgpiops.h"
#include "sleep.h"

#define SW1_INT_ID 61
#define SW2_INT_ID 62
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID


static XScuGic INTCInst;
static void SW_intr_Handler(void *param);
static int IntcInitFunction(u16 DeviceId);
static int cnt1=0,cnt2=0;

static void SW_intr_Handler(void *param){
    int sw_id = (int)param;

    XGpioPs psGpioInstancePtr;
	XGpioPs_Config* GpioConfigPtr;
	int xStatus;
	//-- EMIO的初始化
	GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,
	GpioConfigPtr->BaseAddr);

    if(sw_id==1){
    	cnt1++;
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);
    	if(cnt1%2){
    		XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);//EMIO的第0位输出1
    	}else{
    		XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);
    	}
    	XGpioPs_IntrClearPin(&psGpioInstancePtr, 54);
    }
    if(sw_id==2){
    	cnt2++;
    	XGpioPs_SetDirectionPin(&psGpioInstancePtr, 55,1);
    	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 55,1);
    	if(cnt2%2){
    		XGpioPs_WritePin(&psGpioInstancePtr, 55, 1);//EMIO的第1位输出0
    	}
    	else{
    		XGpioPs_WritePin(&psGpioInstancePtr, 55, 0);
    	}
    	XGpioPs_IntrClearPin(&psGpioInstancePtr, 55);
    }
    printf("led %d on\n\r",sw_id);
}

int IntcInitFunction(u16 DeviceId){

    XScuGic_Config *IntcConfig;
    int status;
    // Interrupt controller initialisation
    IntcConfig = XScuGic_LookupConfig(DeviceId);
    status = XScuGic_CfgInitialize(&INTCInst, IntcConfig,
    IntcConfig->CpuBaseAddress);
    if(status != XST_SUCCESS) return XST_FAILURE;
    // Call to interrupt setup
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    (Xil_ExceptionHandler)XScuGic_InterruptHandler,
    &INTCInst);
    Xil_ExceptionEnable();
    // Connect SW1~SW3 interrupt to handler
    status = XScuGic_Connect(&INTCInst,
    SW1_INT_ID,
    (Xil_ExceptionHandler)SW_intr_Handler,
    (void *)1);
    if(status != XST_SUCCESS) return XST_FAILURE;
    status = XScuGic_Connect(&INTCInst,
    SW2_INT_ID,
    (Xil_ExceptionHandler)SW_intr_Handler,
    (void *)2);
    if(status != XST_SUCCESS) return XST_FAILURE;

    // Enable SW1~SW3 interrupts in the controller
    XScuGic_Enable(&INTCInst, SW1_INT_ID);
    XScuGic_Enable(&INTCInst, SW2_INT_ID);
    return XST_SUCCESS;
}
int main(void){

    printf("key interrupt control leds\n\r");
    IntcInitFunction(INTC_DEVICE_ID);
    while(1);
    return 0;
}

定义使用GIC需要的两个结构体:XScuGic  XScuGic_Config
初始化GIC:XScuGic_LookupConfig  XScuGic_CfgInitialize

Xil_ExceptionRegisterHandler  //在ARM里注册中断异常

Xil_ExceptionEnable  //异常使能

XScuGic_Connect  //连接到自定义中断处理函数

XScuGic_Enable  //GIC使能


自定义异常处理函数SW_intr_Handler()里:

传进来的参数表明当前是哪个按键按下;

定义使用GPIO需要的两个结构体:XGpioPs  XGpioPs_Config

EMIO初始化:XGpioPs_LookupConfig  XGpioPs_CfgInitialize

XGpioPs_SetDirectionPin  //设置GPIO是输入还是输出,1表示输出

XGpioPs_SetOutputEnablePin  //GPIO输出使能

XGpioPs_WritePin  //向pin脚写数据

XGpioPs_IntrClearPin  //废弃这个pin

你可能感兴趣的:(ZYNQ)