本节使用定时器实现按键的消抖,之前一直使用的是空指令实现定时函数。空指令非常浪费CPU的性能,远不如使用定时器。最终实现的效果还是按下key就打开蜂鸣器,再按一下就关闭蜂鸣器。
可以看作是前面几节内容的一个合并。
定时器实现消抖
#include "bsp_key_filter.h"
/*初始化外部中断,也就是GPIO1_IO18*/
void key_filter_init(){
/*gpio初始化*/
_gpio_pin_config_t key_config;
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18 ,0); //设置复用功能
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xf080); //设置电器属性
key_config.direction = kGPIO_INPUT; //设置输入输出
key_config.output_value = 1; //输出值
key_config.interrupt_mode = kGPIO_IntFallingEdge; //设置中断方式
gpio_init(GPIO1,18,&(key_config)); //配置GPIO
/*GIC使能*/
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
/*注册中断函数*/
system_register_irq_handler(GPIO1_Combined_16_31_IRQn, gpio1_io16_13_irqhander,NULL);
/*指定外设GPIO1_18使能*/
gpio_enable_int(GPIO1,18);
key_epit_init(66,10000); //epit初始,设置时钟时间10ms
}
/*按键key的中断处理函数*/
void gpio1_io16_13_irqhander(unsigned int gicciar, void *param){
key_epit_reatart(10000); //打开定时器
gpio_clr_int_flags(GPIO1,18); //清除key的中断标志
}
/*EPIT时钟初始化*/
void key_epit_init(unsigned int frac,int value){
if(frac > 0XFFF){
frac = 0XFFF;
}
EPIT1->CR = 0; //清零
EPIT1->CR |= (1<<24) | (frac << 4) | (1 << 3) | (1 << 2) | (1 << 1);
EPIT1->LR = value; //设置加载寄存器的值
EPIT1->CMPR = 0; //设置比较寄存器的值
GIC_EnableIRQ(EPIT1_IRQn); //初始化GIC对应的中断
/*中断处理函数的注册*/
system_register_irq_handler(EPIT1_IRQn, key_epit1_irq_handler, NULL);
}
/*EPIT1的中断处理函数*/
void key_epit1_irq_handler(unsigned int gicciar, void *param){
static unsigned char status = 0;
if (EPIT1->SR & 0x1) //判断是否产生中断
{
key_epit_stop(); //关闭定时器
if(gpio_read(GPIO1,18) == 0){
status = !status;
beep_switch(status); //反转蜂鸣器状态
}
EPIT1->SR = 0x1; //清除复位标志
}
}
//开启计数器
void key_epit_reatart(unsigned int value)
{
EPIT1->CR &= ~(1 << 0); //关闭定时器
EPIT1->LR = value; //设置加载寄存器的值
EPIT1->CR |= (1 << 0); //打开定时器
}
//关闭计数器
void key_epit_stop(void)
{
EPIT1->CR &= ~(1 << 0); //关闭定时器
}
本节只是把按键的中断和定时器中断合并到了一起。