TA的每日心情 | 开心 2024-8-5 17:13 |
---|
签到天数: 333 天 连续签到: 1 天 [LV.8]以坛为家I
|
本帖最后由 xiaoshen-372360 于 2018-7-22 11:19 编辑
上次介绍的LED输出的操作,这次介绍按键输入的介绍大家都知道,在按键输入的时候都会执行消抖,那么通常的做法是什么呢?
================== 文末 分享代码 ==========================
在学校的时候通常是每次需要读取的时候就直接先读取,再延时,再读取,这样的操作,延时时间也通常为几十个毫秒左右,但是这种处理方式在实际应用中并不多用,为什么这样说呢?因为在几十个毫秒中还可以处理很多事情,那样就白白了浪费掉了你很多时间来等待按键的处理延时,而在实际应用中的按键读取时这样操作的。定时去检测IO状态,如果IO状态变化(和上一次的不一样)那么就将计数器清零,如果计数大于50ms,那就是说在50ms这个时间内并没有检测到按键的变化,说明按键是有效地,这个时候我们去更新按键状态,就可以认为这是一个稳态的按键消息。
下面来看以下1052到按键硬件连接情况。由下图的原理图对应关系可以很明确的知道-按键的对应关系//=====================================================================
Key_WK_UP :GPIO5_IO00
Key_Key_0 :GPIO1_IO05
Key_Key_1 :GPIO5_IO01
Key_Key_2 :GPIO3_IO26
//=====================================================================
//====================================
每次添加头文件都会觉得很麻烦,所以找个捷径,新建一个SystemIncludes.h文件,里面包含所有的头文件,这样就不会存在头库驱动文件
新建一个key的c文件和.h文件,用于按键的数据结构控制;
- #ifndef __DEV_KEY_H
- #define __DEV_KEY_H
- #define Key_Count 50 //--定义延时消抖时间为50ms
- //----
- #define Get_KEY0_Val() GPIO_PinRead(GPIO1,5) //KEY0按键GPIO1_05
- #define Get_KEY1_Val() GPIO_PinRead(GPIO5,1) //KEY1按键GPIO5_01
- #define Get_KEY2_Val() GPIO_PinRead(GPIO3,26) //KEY2按键GPIO3_26
- #define Get_KEY_WKUP_Val() GPIO_PinRead(GPIO5,0) //WK_UP按键GPIO5_00
- extern unsigned int TimCount;
- //--单个按键的结构体--
- typedef struct
- {
- unsigned char Key_LastStatus; //--用于存放更新的数值
- unsigned char Key_Stable_Status;//--用于存放按键的稳定键值
- unsigned int Count; //--用于按键的计数
- }One_Key;
- //--正对RT1052的按键结构体
- typedef struct
- {
- One_Key WK_UP;//--weak up 按键
- One_Key Key0; //--Key0
- One_Key Key1; //--Key1
- One_Key Key2; //--Key2
- }DEV_KEY_RT1052;
- #endif
- /*--------------------------------------- end of the files ------------------------------*/
复制代码
下面添加按键结构体初始化函数以及引脚初始化函数,这里引用原子哥的代码,稍作修改,添加按键消抖处理函数。
- /*================================================================================
- == 函数名称:Key_Struct_init(void)
- == 函数作用:初始化结构体数值
- == 输入参数:NULL
- == 返回值 :NULL
- *=================================================================================
- */
- void Key_Struct_init(void)
- {
- RT1052_Key.WK_UP.Count=0;
- RT1052_Key.WK_UP.Key_LastStatus=0;
-
- RT1052_Key.Key0.Count=0;
- RT1052_Key.Key0.Key_LastStatus=0;
- RT1052_Key.Key1.Count=0;
- RT1052_Key.Key1.Key_LastStatus=0;
- RT1052_Key.Key2.Count=0;
- RT1052_Key.Key2.Key_LastStatus=0;
- };
- //按键初始化函数
- //KEY_UP -> WAKEUP(GPIO5_IO00)
- //KEY0 -> GPIO_AD_B0_05(GPIO1_IO05)
- //KEY1 -> PMIC_ON_REQ(GPIO5_IO01)
- //KEY2 -> GPIO_EMC_40(GPIO3_IO26)
- /*================================================================================
- == 函数名称:DRV_Key_Init(void)
- == 函数作用:初始化按键的引脚
- == 输入参数:NULL
- == 返回值 :NULL
- *=================================================================================
- */
- void DRV_Key_Init(void)
- {
- gpio_pin_config_t RT1052_Key_Init;
- //IO功能设置
- IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00,0); //SNVS_WAKEUP配置为ALT5,即GPIO5_00
- IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05,0); //GPIO_AD_B0_05配置为ALT5,即GPIO1_IO05
- IOMUXC_SetPinMux(IOMUXC_SNVS_PMIC_ON_REQ_GPIO5_IO01,0); //PMIC_ON_REQ,即GPIO5_IO01
- IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_GPIO3_IO26,0); //GPIO_EMC_40配置为ALT5,即GPIO3_IO26
- //配置KEY相关IO的功能
- //低转换速度,关闭输出驱动,速度为100Mhz,关闭开路功能,使能pull/keepr
- //选择pull功能,上拉22K Ohm,关闭Hyst
- IOMUXC_SetPinConfig(IOMUXC_SNVS_WAKEUP_GPIO5_IO00,0xF080);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05,0xF080);
- IOMUXC_SetPinConfig(IOMUXC_SNVS_PMIC_ON_REQ_GPIO5_IO01,0xF080);
- IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_40_GPIO3_IO26,0xF080);
- //KEY_UP默认电平设置
- RT1052_Key_Init.direction=kGPIO_DigitalInput; //输入
- RT1052_Key_Init.interruptMode=kGPIO_NoIntmode; //不使用中断功能
- RT1052_Key_Init.outputLogic=1; //默认高电平
- GPIO_PinInit(GPIO5,0,&RT1052_Key_Init); //初始化GPIO5_00
- //KEY0默认电平设置
- RT1052_Key_Init.direction=kGPIO_DigitalInput; //输入
- RT1052_Key_Init.interruptMode=kGPIO_NoIntmode; //不使用中断功能
- RT1052_Key_Init.outputLogic=1; //默认高电平
- GPIO_PinInit(GPIO1,5,&RT1052_Key_Init); //初始化GPIO1_05
- //KEY1默认电平设置
- RT1052_Key_Init.direction=kGPIO_DigitalInput; //输入
- RT1052_Key_Init.interruptMode=kGPIO_NoIntmode; //不使用中断功能
- RT1052_Key_Init.outputLogic=1; //默认高电平
- GPIO_PinInit(GPIO5,1,&RT1052_Key_Init); //初始化GPIO5_01
- //KEY2默认电平设置
- RT1052_Key_Init.direction=kGPIO_DigitalInput; //输入
- RT1052_Key_Init.interruptMode=kGPIO_NoIntmode; //不使用中断功能
- RT1052_Key_Init.outputLogic=1; //默认高电平
- GPIO_PinInit(GPIO3,26,&RT1052_Key_Init); //初始化GPIO3_26
- }
- /*================================================================================
- == 函数名称:void Get_Key_Val(void)
- == 函数作用:更新按键数值--
- == 输入参数:NULL
- == 返回值 :NULL
- *=================================================================================
- */
- void Get_Key_Val(void)
- {
- //--该函数应当放在定时器中断里面处理的,但总是现在还没有学定时器的东西,所以只能用这种方式模拟定时器的中断处理
- //--每次进来就执行自加的动作,用这个动作模拟定时器的自加,
- RT1052_Key.Key0.Count++;
- RT1052_Key.Key1.Count++;
- RT1052_Key.Key2.Count++;
- RT1052_Key.WK_UP.Count++;
-
- //--Key_0
- //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
- if(RT1052_Key.Key0.Key_LastStatus!=Get_KEY0_Val())
- {
- RT1052_Key.Key0.Key_LastStatus=Get_KEY0_Val();
- RT1052_Key.Key0.Count=0;
- }
- if(RT1052_Key.Key0.Count>Key_Count)
- {
- RT1052_Key.Key0.Key_Stable_Status=RT1052_Key.Key0.Key_LastStatus;//--更新数据到稳定键值数据中
- }
- //--Key_1
- //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
- if(RT1052_Key.Key1.Key_LastStatus!=Get_KEY1_Val())
- {
- RT1052_Key.Key1.Key_LastStatus=Get_KEY1_Val();
- RT1052_Key.Key1.Count=0;
- }
- if(RT1052_Key.Key1.Count>Key_Count)
- {
- RT1052_Key.Key1.Key_Stable_Status=RT1052_Key.Key1.Key_LastStatus;//--更新数据到稳定键值数据中
- }
- //--Key_2
- //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
- if(RT1052_Key.Key2.Key_LastStatus!=Get_KEY2_Val())
- {
- RT1052_Key.Key2.Key_LastStatus=Get_KEY2_Val();
- RT1052_Key.Key2.Count=0;
- }
- if(RT1052_Key.Key2.Count>Key_Count)
- {
- RT1052_Key.Key2.Key_Stable_Status=RT1052_Key.Key2.Key_LastStatus;//--更新数据到稳定键值数据中
- }
- //--Key_2
- //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
- if(RT1052_Key.WK_UP.Key_LastStatus!=Get_KEY_WKUP_Val())
- {
- RT1052_Key.WK_UP.Key_LastStatus=Get_KEY_WKUP_Val();
- RT1052_Key.WK_UP.Count=0;
- }
- if(RT1052_Key.WK_UP.Count>Key_Count)
- {
- RT1052_Key.WK_UP.Key_Stable_Status=RT1052_Key.WK_UP.Key_LastStatus;//--更新数据到稳定键值数据中
- }
- }
复制代码
下面就来写主程序了,实现按下按键之后就LED灯点亮,虽然说是一个简单地按键程序,但是处理方式却是工业上常用的处理方式。
- int main(void)
- {
- LED_Init(); //--初始化LED--
- DRV_Key_Init(); //--初始化Key引脚
- Key_Struct_init();//--初始化Key结构体
- while(1)
- {
- Get_Key_Val();//--不断的刷新按键值---
- if(RT1052_Key.Key0.Key_Stable_Status==1)
- {
- LED0(1);//--开启
- }
- else
- {
- LED0(0);//--关闭
- }
-
- if(RT1052_Key.Key1.Key_Stable_Status==1)
- {
- LED1(1);//--开启
- }
- else
- {
- LED1(0);//--关闭
- }
- }
- }
复制代码
来两张实测图:
/*===========================来来来 最后的福利 --代码分享================*/
按键输入代码:
RT1052-Demo-Key_LED.rar
(909.85 KB, 下载次数: 6)
|
|