i.MX6ULL终结者定时器按键例程程序设计

本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\10_key_filter 目录下。我们在Ubuntu系统下使用命令“mkdir 10_key_filter”建立“10_key_filter”文件夹,如图 1所示:
在这里插入图片描述

图 1

然后使用“cd 10_key_filter”命令进入到10_key_filter文件夹,如图 2所示:
在这里插入图片描述

图 2

然后使用命令“cp -r …/9_epit_timer/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“10_key_filter”里面,如图 3所示:
在这里插入图片描述

图 3

然后在drivers目录下建立keyfilter文件夹,然后在“drivers/keyfilter”目录中新建keyfilter.h和keyfilter.c两个文件,然后在keyfilter.h文件输入下面的代码:

 1 #ifndef _BSP_KEYFILTER_H
 2 #define _BSP_KEYFILTER_H
 3 
 4 
 5 /* 函数声明 */
 6 void filterkey_init(void);
 7 void filtertimer_init(unsigned int value);
 8 void filtertimer_stop(void);
 9 void filtertimer_restart(unsigned int value);
10 void filtertimer_irqhandler(void);
11 void gpio1_16_31_irqhandler(void);
12 
13 #endif

在keyfilter.h文件中声明了一些函数,然后我们打开keyfilter.c文件,在里面输入下面的代码:

  1 #include "key.h"
  2 #include "gpio.h"
  3 #include "int.h"
  4 #include "beep.h"
  5 #include "keyfilter.h"
  6 
  7 /*
  8  * @description         : 按键初始化
  9  * @param                       : 无
 10  * @return                      : 无
 11  */
 12 void filterkey_init(void)
 13 {
    
    
 14         gpio_pin_config_t key_config;
 15 
 16         /* 1、初始化IO复用 */
 17         IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0);  
 18 
 19         /* 2、、配置GPIO1_IO18的IO属性  
 20          *bit 16:0 HYS关闭
 21          *bit [15:14]: 11 默认22K上拉
 22          *bit [13]: 1 pull功能
 23          *bit [12]: 1 pull/keeper使能
 24          *bit [11]: 0 关闭开路输出
 25          *bit [7:6]: 10 速度100Mhz
 26          *bit [5:3]: 000 关闭输出
 27          *bit [0]: 0 低转换率
 28          */
 29         IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);
 30 
 31         /* 3、初始化GPIO为中断 */
 32         key_config.direction = kGPIO_DigitalInput;
 33         key_config.interruptMode = kGPIO_IntFallingEdge;
 34         key_config.outputLogic = 1;
 35         gpio_init(GPIO1, 18, &key_config);
 36 
 37         GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn); /*使能GIC中对应中断                  */
 38 
 39         /* 注册中断服务函数 */
 40         system_register_irqhandler(GPIO1_Combined_16_31_IRQn,
 41                                                            (system_irq_handler_t)gpio1_16_31_irqhandler,
 42                                                            NULL);
 43 
 44         gpio_enableint(GPIO1, 18);              /* 使能GPIO1_IO18的中断功能 */
 45 
 46         filtertimer_init(66000000/100); /* 初始化定时器,10ms */
 47 }
 48 
 49 
 50 /*
 51  * @description         : 初始化用于消抖的定时器,默认关闭定时器
 52  * @param - value       : 定时器EPIT计数值
 53  * @return                      : 无
 54  */
 55 void filtertimer_init(unsigned int value)
 56 {
    
    
 57         EPIT1->CR = 0;  //先清零
 58 
 59         /*
 60      * CR寄存器:
 61      * bit25:24 01 时钟源选择Peripheral clock=66MHz
 62      * bit15:4  0  1分频
 63      * bit3:    1  当计数器到0的话从LR重新加载数值
 64      * bit2:    1  比较中断使能
 65      * bit1:    1  初始计数值来源于LR寄存器值
 66      * bit0:    0  先关闭EPIT1
 67      */
 68         EPIT1->CR = (1<<24 | 1<<3 | 1<<2 | 1<<1);
 69 
 70         /* 计数值    */
 71         EPIT1->LR = value;
 72 
 73         /* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 */
 74         EPIT1->CMPR     = 0;
 75 
 76         GIC_EnableIRQ(EPIT1_IRQn);      /* 使能GIC中对应的中断 */
 77 
 78         /* 注册中断服务函数                 */
 79         system_register_irqhandler(EPIT1_IRQn,
 (system_irq_handler_t)filtertimer_irqhandler, NULL);
 80 }
 81 
 82 /*
 83  * @description         : 关闭定时器
 84  * @param                       : 无
 85  * @return                      : 无
 86  */
 87 void filtertimer_stop(void)
 88 {
    
    
 89         EPIT1->CR &= ~(1<<0);   /* 关闭定时器 */
 90 }
 91 
 92 /*
 93  * @description         : 重启定时器
 94  * @param - value       : 定时器EPIT计数值
 95  * @return                      : 无
 96  */
 97 void filtertimer_restart(unsigned int value)
 98 {
    
    
 99         EPIT1->CR &= ~(1<<0);   /* 先关闭定时器 */
100         EPIT1->LR = value;      /* 计数值                       */
101         EPIT1->CR |= (1<<0);    /* 打开定时器           */
102 }
103 
104 /*
105  * @description         : 定时器中断处理函数 
106  * @param                       : 无
107  * @return                      : 无
108  */
109 void filtertimer_irqhandler(void)
110 {
    
    
111         static unsigned char state = OFF;
112 
113         if(EPIT1->SR & (1<<0))     /* 判断比较事件是否发生                 */
114         {
    
    
115                 filtertimer_stop();  /* 关闭定时器                      */
116                 if(gpio_pinread(GPIO1, 18) == 0) /* KEY0                  */
117                 {
    
    
118                         state = !state;
119                         beep_switch(state);     /* 反转蜂鸣器         */
120                 }
121         }
122 
123         EPIT1->SR |= 1<<0;/* 清除中断标志位                */
124 }
125 
126 /*
127  * @description         : GPIO中断处理函数
128  * @param                       : 无
129  * @return                      : 无
130  */
131 void gpio1_16_31_irqhandler(void)
132 {
    
    
133         /* 开启定时器 */
134         filtertimer_restart(66000000/100);
135 
136         /* 清除中断标志位 */
137         gpio_clearintflags(GPIO1, 18);
138 }

keyfilter.c文件中一共有6个函数。
filterkey_init是初始化函数,初始化了按键使用的IO,设置这个IO的中断模式,然后注册中断处理函数并使能按键IO的中断,最后调用filtertimer_init函数,初始化EIPT1定时器。
filtertimer_init函数有一个参数value,他是指定时周期,我们这里传入的是66000000/100,相当于是10ms的定时周期,filtertimer_init函数的内容和上一章节的EPIT1定时器初始化一样。
filtertimer_stop函数是停止EPIT1定时器。
filtertimer_restart是重新启动EPIT1定时器。
filtertimer_irqhandler是EPIT1定时器的中断处理函数,在该函数里面如果我们读取到的按键状态是按下,那么就设置蜂鸣器的状态翻转。
gpio1_16_31_irqhandler是按键IO的中断处理函数,他的作用是检测到有按键按下就可以EPIT1定时器。

最后我们修改工程根目录下的main.c文件,输入下面的代码:

  1 #include "clk.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 #include "beep.h"
  5 #include "key.h"
  6 #include "int.h"
  7 #include "keyfilter.h"
  8 
  9 /*
 10  * @description : main函数
 11  * @param               : 无
 12  * @return              : 无
 13  */
 14 int main(void)
 15 {
    
    
 16         unsigned char state = OFF;
 17 
 18         int_init();                   /* 初始化中断(一定要最先调用!) */
 19         imx6u_clkinit();              /* 初始化系统时钟             */
 20         clk_enable();                /* 使能所有的时钟             */
 21         led_init();                  /* 初始化led                   */
 22         beep_init();                /* 初始化beep                  */
 23         filterkey_init();              /* 带有消抖功能的按键          */
 24 
 25         while(1)
 26         {
    
    
 27                 state = !state;
 28                 led_switch(LED0, state);
 29                 delay(500);
 30         }
 31 
 32         return 0;
 33 }

main.c文件中第23行调用filterkey_init 函数,filterkey_init来初始化按键IO,注册按键中断处理函数,最后调用EPIT1定时器初始化函数,最后程序进入while(1)循环里面,在循环里面每隔500ms翻转一下LED的状态。在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46635880/article/details/108973736