查看: 3873|回复: 1

[原创] 【正点原子-号令者】【I.MX-RT-1052】【04-按键输入】

[复制链接]
  • TA的每日心情
    开心
    2024-8-5 17:13
  • 签到天数: 333 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2018-7-22 08:33:22 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 xiaoshen-372360 于 2018-7-22 11:19 编辑

    上次介绍的LED输出的操作,这次介绍按键输入的介绍大家都知道,在按键输入的时候都会执行消抖,那么通常的做法是什么呢?
    ==================  文末 分享代码 ==========================
    在学校的时候通常是每次需要读取的时候就直接先读取,再延时,再读取,这样的操作,延时时间也通常为几十个毫秒左右,但是这种处理方式在实际应用中并不多用,为什么这样说呢?因为在几十个毫秒中还可以处理很多事情,那样就白白了浪费掉了你很多时间来等待按键的处理延时,而在实际应用中的按键读取时这样操作的。定时去检测IO状态,如果IO状态变化(和上一次的不一样)那么就将计数器清零,如果计数大于50ms,那就是说在50ms这个时间内并没有检测到按键的变化,说明按键是有效地,这个时候我们去更新按键状态,就可以认为这是一个稳态的按键消息。
    01-按键消抖.png

    下面来看以下1052到按键硬件连接情况。由下图的原理图对应关系可以很明确的知道-按键的对应关系
    //=====================================================================

    Key_WK_UP :GPIO5_IO00

    Key_Key_0   :GPIO1_IO05

    Key_Key_1   :GPIO5_IO01

    Key_Key_2   :GPIO3_IO26

    //=====================================================================

    02-按键原理图.png


    03-按键位置图.jpg

    4-Key.png


    //====================================
    每次添加头文件都会觉得很麻烦,所以找个捷径,新建一个SystemIncludes.h文件,里面包含所有的头文件,这样就不会存在头库驱动文件
    05-includes.png


    新建一个key的c文件和.h文件,用于按键的数据结构控制;
    06-按键结构体、.png

    下面是key的.h文件的代码。
    1. #ifndef __DEV_KEY_H
    2. #define __DEV_KEY_H



    3. #define Key_Count  50  //--定义延时消抖时间为50ms
    4. //----
    5. #define Get_KEY0_Val()            GPIO_PinRead(GPIO1,5)  //KEY0按键GPIO1_05
    6. #define Get_KEY1_Val()            GPIO_PinRead(GPIO5,1)  //KEY1按键GPIO5_01
    7. #define Get_KEY2_Val()            GPIO_PinRead(GPIO3,26) //KEY2按键GPIO3_26
    8. #define Get_KEY_WKUP_Val()         GPIO_PinRead(GPIO5,0)  //WK_UP按键GPIO5_00
    9. extern unsigned int TimCount;


    10. //--单个按键的结构体--
    11. typedef struct
    12. {
    13.         unsigned char Key_LastStatus;   //--用于存放更新的数值
    14.         unsigned char Key_Stable_Status;//--用于存放按键的稳定键值
    15.         unsigned int Count;    //--用于按键的计数
    16. }One_Key;

    17. //--正对RT1052的按键结构体
    18. typedef struct
    19. {
    20.   One_Key WK_UP;//--weak up 按键
    21.         One_Key Key0; //--Key0
    22.         One_Key Key1; //--Key1
    23.         One_Key Key2; //--Key2
    24. }DEV_KEY_RT1052;
    25. #endif



    26. /*---------------------------------------   end of the  files  ------------------------------*/





    复制代码


    下面添加按键结构体初始化函数以及引脚初始化函数,这里引用原子哥的代码,稍作修改,添加按键消抖处理函数。

    1. /*================================================================================
    2. == 函数名称:Key_Struct_init(void)
    3. == 函数作用:初始化结构体数值
    4. == 输入参数:NULL
    5. == 返回值  :NULL
    6. *=================================================================================
    7. */
    8. void Key_Struct_init(void)
    9. {
    10.                 RT1052_Key.WK_UP.Count=0;
    11.                 RT1052_Key.WK_UP.Key_LastStatus=0;
    12.                         
    13.                 RT1052_Key.Key0.Count=0;
    14.                 RT1052_Key.Key0.Key_LastStatus=0;

    15.                 RT1052_Key.Key1.Count=0;
    16.                 RT1052_Key.Key1.Key_LastStatus=0;

    17.                 RT1052_Key.Key2.Count=0;
    18.                 RT1052_Key.Key2.Key_LastStatus=0;
    19. };





    20. //按键初始化函数
    21. //KEY_UP    ->  WAKEUP(GPIO5_IO00)
    22. //KEY0      ->  GPIO_AD_B0_05(GPIO1_IO05)
    23. //KEY1      ->  PMIC_ON_REQ(GPIO5_IO01)
    24. //KEY2      ->  GPIO_EMC_40(GPIO3_IO26)
    25. /*================================================================================
    26. == 函数名称:DRV_Key_Init(void)
    27. == 函数作用:初始化按键的引脚
    28. == 输入参数:NULL
    29. == 返回值  :NULL
    30. *=================================================================================
    31. */
    32. void DRV_Key_Init(void)
    33. {
    34.                 gpio_pin_config_t RT1052_Key_Init;
    35.                 //IO功能设置
    36.                 IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00,0);                //SNVS_WAKEUP配置为ALT5,即GPIO5_00
    37.                 IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05,0);            //GPIO_AD_B0_05配置为ALT5,即GPIO1_IO05
    38.                 IOMUXC_SetPinMux(IOMUXC_SNVS_PMIC_ON_REQ_GPIO5_IO01,0);     //PMIC_ON_REQ,即GPIO5_IO01
    39.                 IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_GPIO3_IO26,0);                //GPIO_EMC_40配置为ALT5,即GPIO3_IO26

    40.                 //配置KEY相关IO的功能
    41.                 //低转换速度,关闭输出驱动,速度为100Mhz,关闭开路功能,使能pull/keepr
    42.                 //选择pull功能,上拉22K Ohm,关闭Hyst
    43.                 IOMUXC_SetPinConfig(IOMUXC_SNVS_WAKEUP_GPIO5_IO00,0xF080);      
    44.                 IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05,0xF080);   
    45.                 IOMUXC_SetPinConfig(IOMUXC_SNVS_PMIC_ON_REQ_GPIO5_IO01,0xF080);
    46.                 IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_40_GPIO3_IO26,0xF080);

    47.                 //KEY_UP默认电平设置
    48.                 RT1052_Key_Init.direction=kGPIO_DigitalInput;        //输入
    49.                 RT1052_Key_Init.interruptMode=kGPIO_NoIntmode;        //不使用中断功能
    50.                 RT1052_Key_Init.outputLogic=1;                                        //默认高电平
    51.                 GPIO_PinInit(GPIO5,0,&RT1052_Key_Init);                         //初始化GPIO5_00

    52.                 //KEY0默认电平设置
    53.                 RT1052_Key_Init.direction=kGPIO_DigitalInput;        //输入
    54.                 RT1052_Key_Init.interruptMode=kGPIO_NoIntmode;        //不使用中断功能
    55.                 RT1052_Key_Init.outputLogic=1;                                        //默认高电平
    56.                 GPIO_PinInit(GPIO1,5,&RT1052_Key_Init);                         //初始化GPIO1_05

    57.                 //KEY1默认电平设置
    58.                 RT1052_Key_Init.direction=kGPIO_DigitalInput;        //输入
    59.                 RT1052_Key_Init.interruptMode=kGPIO_NoIntmode;        //不使用中断功能
    60.                 RT1052_Key_Init.outputLogic=1;                                        //默认高电平
    61.                 GPIO_PinInit(GPIO5,1,&RT1052_Key_Init);                         //初始化GPIO5_01

    62.                 //KEY2默认电平设置
    63.                 RT1052_Key_Init.direction=kGPIO_DigitalInput;        //输入
    64.                 RT1052_Key_Init.interruptMode=kGPIO_NoIntmode;        //不使用中断功能
    65.                 RT1052_Key_Init.outputLogic=1;                                        //默认高电平
    66.                 GPIO_PinInit(GPIO3,26,&RT1052_Key_Init);             //初始化GPIO3_26
    67. }


    68. /*================================================================================
    69. == 函数名称:void Get_Key_Val(void)
    70. == 函数作用:更新按键数值--
    71. == 输入参数:NULL
    72. == 返回值  :NULL
    73. *=================================================================================
    74. */

    75. void Get_Key_Val(void)
    76. {
    77.         //--该函数应当放在定时器中断里面处理的,但总是现在还没有学定时器的东西,所以只能用这种方式模拟定时器的中断处理
    78.         //--每次进来就执行自加的动作,用这个动作模拟定时器的自加,
    79.         RT1052_Key.Key0.Count++;
    80.         RT1052_Key.Key1.Count++;
    81.         RT1052_Key.Key2.Count++;
    82.         RT1052_Key.WK_UP.Count++;
    83.         
    84.         //--Key_0
    85.         //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
    86.         if(RT1052_Key.Key0.Key_LastStatus!=Get_KEY0_Val())
    87.         {
    88.                 RT1052_Key.Key0.Key_LastStatus=Get_KEY0_Val();
    89.     RT1052_Key.Key0.Count=0;
    90.         }
    91.   if(RT1052_Key.Key0.Count>Key_Count)
    92.         {
    93.           RT1052_Key.Key0.Key_Stable_Status=RT1052_Key.Key0.Key_LastStatus;//--更新数据到稳定键值数据中
    94.         }
    95.         //--Key_1
    96.         //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
    97.         if(RT1052_Key.Key1.Key_LastStatus!=Get_KEY1_Val())
    98.         {
    99.                 RT1052_Key.Key1.Key_LastStatus=Get_KEY1_Val();
    100.     RT1052_Key.Key1.Count=0;
    101.         }
    102.   if(RT1052_Key.Key1.Count>Key_Count)
    103.         {
    104.           RT1052_Key.Key1.Key_Stable_Status=RT1052_Key.Key1.Key_LastStatus;//--更新数据到稳定键值数据中
    105.         }
    106.         //--Key_2
    107.         //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
    108.         if(RT1052_Key.Key2.Key_LastStatus!=Get_KEY2_Val())
    109.         {
    110.                 RT1052_Key.Key2.Key_LastStatus=Get_KEY2_Val();
    111.     RT1052_Key.Key2.Count=0;
    112.         }
    113.   if(RT1052_Key.Key2.Count>Key_Count)
    114.         {
    115.           RT1052_Key.Key2.Key_Stable_Status=RT1052_Key.Key2.Key_LastStatus;//--更新数据到稳定键值数据中
    116.         }
    117.         //--Key_2
    118.         //--每次进来之后就将Count计数器清0 这样才能保证数值大于50ms的消抖延时是起作用的
    119.         if(RT1052_Key.WK_UP.Key_LastStatus!=Get_KEY_WKUP_Val())
    120.         {
    121.                 RT1052_Key.WK_UP.Key_LastStatus=Get_KEY_WKUP_Val();
    122.     RT1052_Key.WK_UP.Count=0;
    123.         }
    124.   if(RT1052_Key.WK_UP.Count>Key_Count)
    125.         {
    126.           RT1052_Key.WK_UP.Key_Stable_Status=RT1052_Key.WK_UP.Key_LastStatus;//--更新数据到稳定键值数据中
    127.         }
    128. }


    复制代码




    下面就来写主程序了,实现按下按键之后就LED灯点亮,虽然说是一个简单地按键程序,但是处理方式却是工业上常用的处理方式。

    1. int main(void)
    2. {
    3.           LED_Init();  //--初始化LED--
    4.           DRV_Key_Init();  //--初始化Key引脚
    5.           Key_Struct_init();//--初始化Key结构体
    6.     while(1)
    7.     {
    8.                         Get_Key_Val();//--不断的刷新按键值---
    9.                         if(RT1052_Key.Key0.Key_Stable_Status==1)
    10.                         {
    11.          LED0(1);//--开启
    12.                         }
    13.                         else
    14.                         {
    15.                          LED0(0);//--关闭
    16.                         }
    17.                         
    18.                         if(RT1052_Key.Key1.Key_Stable_Status==1)
    19.                         {
    20.          LED1(1);//--开启
    21.                         }
    22.                         else
    23.                         {
    24.                          LED1(0);//--关闭
    25.                         }
    26.     }
    27. }

    复制代码


    来两张实测图:



    1.jpg 2.jpg 3.jpg



    /*===========================来来来 最后的福利 --代码分享================*/
    按键输入代码: RT1052-Demo-Key_LED.rar (909.85 KB, 下载次数: 6)
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-8-5 17:13
  • 签到天数: 333 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2018-7-24 16:39:50 | 显示全部楼层
    自己过来顶一下
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-12 20:44 , Processed in 0.126221 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.