【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提供的驱动库,套模板就可以,最后这一步,才是用户真正要做的。
课程附件
/*
* 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);
}
}
}
抢楼备用
本楼层作者占位,主要用来统一解答大家学习本节课程过程中遇到的常见问题,后续会再次编辑完善。学习者有疑问的,请在本楼层之后开始提问和讨论。 :handshake:handshake:handshake:handshake:handshake:handshake
页:
[1]