admin 发表于 2022-8-29 09:54:15

【zynq课程笔记】【裸机】【第14课 】【Zynq编程原理与实验】

实验目标

使用PS侧按键0,以中断的方式

先初始化PIO基本功能,还是先初始化GIC中断?


第一步

先初始化GPIO作为输入输出的基本功能
初始化GPIO驱动

定义Gpio驱动对应的实例
static XGpioPs Gpio; /* The Instance of the GPIO Driver */

根据GPIO设备ID查找配置信息
XGpioPs_Config *ConfigPtr; /*为GPIO的设备信息创建一个指针*/
ConfigPtr = XGpioPs_LookupConfig(DeviceId);/*根据设备ID查找到GPIO的配置信息*/
(要用到GPIO的设备ID,需要包含哪个头文件?)
初始化GPIO驱动
XGpioPs_CfgInitialize(Gpio, ConfigPtr, ConfigPtr->BaseAddr);


第二步

设置本例中用到的GPIO的基本工作模式(输入(MIO47)、输出(MIO7)、初始值)
        XGpioPs_SetDirectionPin(Gpio, Output_Pin, 1);
        XGpioPs_SetOutputEnablePin(Gpio, Output_Pin, 1);
        XGpioPs_WritePin(Gpio, Output_Pin, 0x0);


第三步

初始化GIC控制器驱动
定义GIC控制器对应的实例
static XScuGic Intc; /* The Instance of the Interrupt Controller Driver */

根据GIC设备ID查找配置信息
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

初始化GIC驱动
Status = XScuGic_CfgInitialize(Intc, IntcConfig,        IntcConfig->CpuBaseAddress);


第四步

注册CPU的总异常/中断服务函数
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                Intc);


第五步

注册/绑定具体外设的中断服务函数
        Status = XScuGic_Connect(Intc, GpioIntrId,
                                (Xil_ExceptionHandler)XGpioPs_IntrHandler,
                                (void *)Gpio);[


第六步

设置具体外设的中断相关的寄存器(使能、禁止、中断检测类型)
        /* Enable falling edge interrupts for all the pins in bank 0. */
        XGpioPs_SetIntrType(Gpio, GPIO_BANK, 0x00, 0xFFFFFFFF, 0x00);

        /* Set the handler for gpio interrupts. */
        XGpioPs_SetCallbackHandler(Gpio, (void *)Gpio, IntrHandler);


        /* Enable the GPIO interrupts of Bank 0. */
        XGpioPs_IntrEnable(Gpio, GPIO_BANK, (1 << Input_Pin));


第七步

在GIC中允许该外设的中断源向Cpu发出中断



第八步

打开CPU的总中断开关,此时Cpu就可以开始接受并响应中断了。



第九步

从用户编写程序的角度,具体外设的中断服务函数要开始仔细编写了,前面的全部直接使用SDK提供的驱动库,套模板就可以,最后这一步,才是用户真正要做的。

admin 发表于 2022-8-29 10:13:45

课程附件




/*
* main.c
*
*Created on: 2022年8月25日
*      Author: Administrator
*/


#include <stdio.h>
#include <xparameters.h>
#include <xgpiops.h>
#include <xscugic.h>
#include <xil_exception.h>
#include <unistd.h>


#define Input_Pin 47        //PS_KEY
#define Output_Pin7 //PS_LED

static XGpioPs Gpio; /* The Instance of the GPIO Driver */
static XScuGic GicInstancePtr;

int flag;
//按下按键,CPU驱动PS_LED闪烁1次,周期为1S

static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
        XGpioPs *Gpio = (XGpioPs *)CallBackRef;
        u32 DataRead;

        if(Status)
        {
                DataRead = XGpioPs_ReadPin(Gpio, Input_Pin);
                if (0 == DataRead) {
                        flag ++;
                }
        }
}


int main(void)
{

        flag = 0;

        XGpioPs_Config *ConfigPtr;
        ConfigPtr = XGpioPs_LookupConfig(XPAR_AXI_GPIO_0_DEVICE_ID);
        XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);

        /* Set the direction for the specified pin to be input */
        XGpioPs_SetDirectionPin(&Gpio, Input_Pin, 0x0);

        /* Set the direction for the specified pin to be output. */
        XGpioPs_SetDirectionPin(&Gpio, Output_Pin, 1);
        XGpioPs_SetOutputEnablePin(&Gpio, Output_Pin, 1);
        XGpioPs_WritePin(&Gpio, Output_Pin, 0x0);

        XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
        IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
        XScuGic_CfgInitialize(&GicInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress);

        //注册CPU的总异常/中断服务函数
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                        (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                        &GicInstancePtr);

        //注册/绑定具体外设的中断服务函数
        XScuGic_Connect(&GicInstancePtr, XPS_GPIO_INT_ID,
                                        (Xil_ExceptionHandler)XGpioPs_IntrHandler,
                                        &Gpio);


        /* Enable falling edge interrupts for all the pins in bank 1. */
        XGpioPs_SetIntrType(&Gpio, XGPIOPS_BANK1, 0xffffffff, 0x00000000, 0x00);

        /* Set the handler for gpio interrupts. */
        XGpioPs_SetCallbackHandler(&Gpio, &Gpio, IntrHandler);


        /* Enable the GPIO interrupts of Bank 1. */
        XGpioPs_IntrEnable(&Gpio, XGPIOPS_BANK1, (1 << (Input_Pin-32)));


        //在GIC中允许该外设的中断源向Cpu发出中断
        XScuGic_Enable(&GicInstancePtr, XPS_GPIO_INT_ID);

        Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);

        while(1)
        {
                if(flag > 0)
                {
                        flag--;
                        XGpioPs_WritePin(&Gpio, Output_Pin, 0x1);
                        usleep(500000);
                        XGpioPs_WritePin(&Gpio, Output_Pin, 0x0);
                        usleep(500000);
                }
        }
}

tb一下 发表于 2022-8-29 10:15:53

抢楼备用

admin 发表于 2022-8-29 10:59:24

本楼层作者占位,主要用来统一解答大家学习本节课程过程中遇到的常见问题,后续会再次编辑完善。学习者有疑问的,请在本楼层之后开始提问和讨论。

CJC 发表于 2022-8-29 12:14:07

:handshake:handshake:handshake:handshake:handshake:handshake
页: [1]
查看完整版本: 【zynq课程笔记】【裸机】【第14课 】【Zynq编程原理与实验】