按键消抖实验

1. 步骤

1、配置按键 IO 中断
配置按键所使用的 IO,因为要使用到中断驱动按键,所以要配置 IO 的中断模式。
2、初始化消抖用的定时器
上面已经讲的很清楚了,消抖要用定时器来完成,所以需要初始化一个定时器,这里使用
上一章讲解的 EPIT1 定时器,也算是对 EPIT1 定时器的一次巩固。定时器的定时周期为 10ms,也可根据实际情况调整定时周期。
3、编写中断处理函数
需要编写两个中断处理函数:按键对应的 GPIO 中断处理函数和 EPIT1 定时器的中断处理
函数。在按键的中断处理函数中主要用于开启 EPIT1 定时器,EPIT1 的中断处理函数才是重点,按键要做的具体任务都是在定时器 EPIT1 的中断处理函数中完成的,比如控制蜂鸣器打开或关闭。

2. 代码

keyfilter.h
#ifndef __BSP_KEYFILTER
#define __BSP_KEYFILTER
#include "imx6ul.h"

/* 函数声明 */
void filterkey_init(void);
void filtertimer_init(unsigned int value);
void filtertimer_stop(void);
void filtertimer_restart(unsigned int value);
void filtertimer_irqhandler(void);
void gpio1_16_31_irqhandler(void);

#endif // !__BSP_KEYFILTER

keyfilter.c

#include "bsp_keyfilter.h"
#include "bsp_key.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_beep.h"
#include "bsp_keyfilter.h"

/*
* @description : 按键初始化
* @param : 无
* @return : 无
*/
void filterkey_init(void)
{ 
    gpio_pin_config_t key_config;

    /* 1、初始化 IO */
    IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
    IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);

    /* 2、初始化 GPIO 为中断 */
    key_config.direction = kGPIO_DigitalInput;
    key_config.interruptMode = kGPIO_IntFallingEdge;
    key_config.outputLogic = 1;
    gpio_init(GPIO1, 18, &key_config);

    /* 3、 使能 GPIO 中断,并且注册中断处理函数 */
    GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
    system_register_irqhandler(GPIO1_Combined_16_31_IRQn, 
                              (system_irq_handler_t)gpio1_16_31_irqhandler,
                              NULL);

    gpio_enableint(GPIO1, 18); /* 使能 GPIO1_IO18 的中断功能 */
    filtertimer_init(66000000/100); /* 初始化定时器,10ms */
}

/*
* @description : 初始化用于消抖的定时器,默认关闭定时器
* @param - value : 定时器 EPIT 计数值
* @return : 无
*/
void filtertimer_init(unsigned int value)
{
    EPIT1->CR = 0; /* 先清零 */
    EPIT1->CR = (1<<24 | 1<<3 | 1<<2 | 1<<1);
    EPIT1->LR = value; /* 计数值 */
    EPIT1->CMPR = 0; /* 比较寄存器为 0 */

    /* 使能 EPIT1 中断并注册中断处理函数*/
    GIC_EnableIRQ(EPIT1_IRQn); 
    system_register_irqhandler(EPIT1_IRQn,
    (system_irq_handler_t)filtertimer_irqhandler,
    NULL);
}

/*
* @description : 关闭定时器
* @param : 无
* @return : 无
*/
void filtertimer_stop(void)
{
    EPIT1->CR &= ~(1<<0); /* 关闭定时器 */
}

/*
* @description : 重启定时器
* @param – value : 定时器 EPIT 计数值
* @return : 无
*/
void filtertimer_restart(unsigned int value)
{
    EPIT1->CR &= ~(1<<0); /* 先关闭定时器 */
    EPIT1->LR = value; /* 计数值 */
    EPIT1->CR |= (1<<0); /* 打开定时器 */
}
/*
* @description : 定时器中断处理函数
* @param : 无
* @return : 无
*/
void filtertimer_irqhandler(void)
{
    static unsigned char state = OFF;

    if(EPIT1->SR & (1<<0)) /* 判断比较事件是否发生 */
    {
        filtertimer_stop(); /* 关闭定时器 */
        if(gpio_pinread(GPIO1, 18) == 0) /* KEY0 按下 */
        {
            state = !state;
            beep_switch(state); /* 反转蜂鸣器 */
        }
    }
    EPIT1->SR |= 1<<0; /* 清除中断标志位 */
}

/*
* @description : GPIO 中断处理函数
* @param : 无3.0
* @return : 无
*/
void gpio1_16_31_irqhandler(void)
{
    filtertimer_restart(66000000/100); /* 开启定时器 */
    gpio_clearIntFlags(GPIO1, 18); /* 清除中断标志位 */
}

main.c

#include "imx6ul.h"
#include "bsp_led.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_exit.h"
#include "bsp_epittimer.h"
#include "bsp_keyfilter.h"
/*
 * @description	: mian函数
 * @param 		: 无
 * @return 		: 无
 */

int main(void)
{
	uint8_t state = OFF;
	/* 对于中断的初始化,一定要放在代码的最前面 */
	int_init();
	clk_init();			/* 系统时钟初始化 */
	clk_enable();		/* 使能所有的时钟 			*/
	led_init();			/* 初始化led 			*/
	beep_init();		/* 初始化beep */
	filterkey_init();	/* 带有消抖功能的按键 */

	while(1)			/* 死循环 				*/
	{	
		state = !state;
		led_switch(LED0, state);
		delay(500);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值