ZYNQ 嵌入式按键控制LED整理

学习记录


PL部分省略不表

主函数读取按键状态

源码

#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"

#define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID   //PS端  GPIO器件 ID

#define MIO_LED2 0   //PS_LED2 连接到 MIO0
#define EMIO_KEY 54  //PL_KEY0 连接到EMIO0

int main()
{
    printf("EMIO TEST!\n");

    XGpioPs gpiops_inst;            //PS端 GPIO 驱动实例
    XGpioPs_Config *gpiops_cfg_ptr; //PS端 GPIO 配置信息

    //根据器件ID查找配置信息
    gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
    //初始化器件驱动
    XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);
    //设置LED为输出
    XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED2, 1);
    //使能LED输出
    XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED2, 1);
    //设置KEY为输入
    XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_KEY, 0);

    //读取按键状态,用于控制LED亮灭
    while(1){
        
        XGpioPs_WritePin(&gpiops_inst, MIO_LED2, ~XGpioPs_ReadPin(&gpiops_inst, EMIO_KEY));
    }

    return 0;
}

分析

从头文件可以看出来使用了stdio的printf,省略了初始化是否成功的判断
驱动实例由全局变量改为局部变量
设置KEY为输入
读取按键状态,并对按键状态取反以后赋值给LED

按键中断

代码

#include "xparameters.h"		//器件参数信息
#include "xgpiops.h"			//包含 PS GPIO 的函数声明
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
#include <xil_printf.h>			//包含 print()函数
#include "sleep.h"				//包含 sleep()函数

/************************** Constant Definitions *****************************/
//以下常量映射到 xparameters.h 文件
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID //PS 端 GPIO 器件 ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID //通用中断控制器 ID
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR //PS 端 GPIO 中断 ID
//定义使用到的 MIO 引脚号
#define BTN0 54+0

#define LED0 54+2

/************************** Function Prototypes ******************************/
static void intr_handler(void *callback_ref);
int setup_interrupt_system(XScuGic *gic_ins_ptr, XGpioPs *gpio, u16 GpioIntrId);
/**************************Global Variable Definitions ***********************/
XGpioPs gpio; //PS 端 GPIO 驱动实例
XScuGic intc; //通用中断控制器驱动实例
u32 key_press; //KEY 按键按下的标志
u32 key_val; //用于控制 LED 的键值
/************************** Function Definitions *****************************/

int main(void)
{
	int status;
	XGpioPs_Config *ConfigPtr; //PS 端 GPIO 配置信息
	xil_printf("Gpio interrupt test \r\n");
	//根据器件 ID 查找配置信息
	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}
	//初始化 Gpio driver
	XGpioPs_CfgInitialize(&gpio, ConfigPtr, ConfigPtr->BaseAddr);
	//设置 KEY 所连接的 MIO 引脚的方向为输入
	XGpioPs_SetDirectionPin(&gpio, BTN0, 0);

	//设置 LED 所连接的 MIO 引脚的方向为输出并使能输出
	XGpioPs_SetDirectionPin(&gpio, LED0, 1);
	XGpioPs_SetOutputEnablePin(&gpio, LED0, 1);
	XGpioPs_WritePin(&gpio, LED0, 0x0);

	//建立中断,出现错误则打印信息并退出
	status = setup_interrupt_system(&intc, &gpio, GPIO_INTERRUPT_ID);
	if (status != XST_SUCCESS) {
		xil_printf("Setup interrupt system failed\r\n");
		return XST_FAILURE;
	}

	//中断触发时, key_press 为 TURE,延时一段时间后判断按键是否按下,是则反转 LED
	while (1) {
		if (key_press) {
			usleep(20000);
			if (XGpioPs_ReadPin(&gpio, BTN0) == 0) {
				key_val = ~key_val;
				XGpioPs_WritePin(&gpio, LED0, key_val);
			}
			key_press = FALSE;
			XGpioPs_IntrClearPin(&gpio, BTN0); //清除按键 KEY 中断
			XGpioPs_IntrEnablePin(&gpio, BTN0); //使能按键 KEY 中断
		}
	}
	return XST_SUCCESS;
}

//中断处理函数
// @param CallBackRef 是指向上层回调引用的指针
static void intr_handler(void *callback_ref)
{
	XGpioPs *gpio = (XGpioPs *) callback_ref;
	//读取 KEY 按键引脚的中断状态,判断是否发生中断
	if (XGpioPs_IntrGetStatusPin(gpio, BTN0)){
		key_press = TRUE;
		XGpioPs_IntrDisablePin(gpio, BTN0); //屏蔽按键 KEY 中断
	}
}

//建立中断系统,使能 KEY 按键的下降沿中断
// @param GicInstancePtr 是一个指向 XScuGic 驱动实例的指针
// @param gpio 是一个指向连接到中断的 GPIO 组件实例的指针
// @param GpioIntrId 是 Gpio 中断 ID
// @return 如果成功返回 XST_SUCCESS, 否则返回 XST_FAILURE
int setup_interrupt_system(XScuGic *gic_ins_ptr, XGpioPs *gpio, u16 GpioIntrId)
{
	int status;
	XScuGic_Config *IntcConfig; //中断控制器配置信息
	//查找中断控制器配置信息并初始化中断控制器驱动
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}
	status = XScuGic_CfgInitialize(gic_ins_ptr, IntcConfig,
		IntcConfig->CpuBaseAddress);
	if (status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	
	//设置并使能中断异常
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler) XScuGic_InterruptHandler, gic_ins_ptr);
	Xil_ExceptionEnable();
	
	//为中断设置中断处理函数
	//建立中断源 ID 与识别中断时要运行的关联处理程序之间的连接
	//intr_handler为中断处理函数
	status = XScuGic_Connect(gic_ins_ptr, GpioIntrId,
		(Xil_ExceptionHandler) intr_handler, (void *) gpio);
	if (status != XST_SUCCESS) {
		return status;
	}
	
	//使能来自于 Gpio 器件的中断
	XScuGic_Enable(gic_ins_ptr, GpioIntrId);
	
	//设置 KEY 按键的中断类型为下降沿中断
	//共有五种中断类型,分别是上升沿、下降沿、双边沿、高电平和低电平
	XGpioPs_SetIntrTypePin(gpio, BTN0, XGPIOPS_IRQ_TYPE_EDGE_FALLING);

	//使能按键 KEY 中断
	XGpioPs_IntrEnablePin(gpio, BTN0);

	return XST_SUCCESS;
}

分析

  1. 多出了几个头文件,干啥的不太清楚
#include "xscugic.h"
#include "xil_exception.h"
#include "xplatform_info.h"
  1. 宏定义多了
    通用中断控制器 ID,PS端GPIO 中断 ID
  2. 定义变量
    主要是通用中断控制器驱动实例
  3. 主函数
    建立中断,出现错误则打印信息并退出
    while循环当发现自定义的按键按下标志位为真时,延时消抖并检测是否按下,如果按下则取反按键值并赋值给LED灯。
    最后将按键按下标志位复位,并清除按键中断标志位,使能按键中断
  4. 中断处理函数
    读取 KEY 按键引脚的中断状态,判断是否发生中断
    如果发生中断,置位按键按下标志位,屏蔽按键中断
  5. 中断建立函数
    查找中断控制器配置信息并初始化中断控制器驱动(类似GPIO)
    设置并使能中断异常
    为中断设置中断处理函数
    使能来自于 Gpio 器件的中断
    设置 KEY 按键的中断类型为下降沿中断
    使能按键 KEY 中断

参考文献

参考正点原子《领航者 ZYNQ 之嵌入式开发指南》


都看到这了,给文章点个赞再走吧
   ||
   V

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值