• sjk.
    了解作者
  • C/C++
    开发工具
  • 102KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 4
    下载次数
  • 2019-07-11 11:15
    上传日期
分享一个按键程序; 状态机按键程序,支持短按、长按、双击等操作.
132415k3yzcg3555rh3ny2.rar
  • key
  • proj
  • out
  • key.obj
    17KB
  • key.plg
    389B
  • key.lnp
    93B
  • key
    18.7KB
  • key.hex
    4.4KB
  • main.obj
    3.8KB
  • list
  • key.m51
    16.4KB
  • key.lst
    13.4KB
  • main.lst
    1007B
  • key.uvopt
    73.5KB
  • key.plg
    389B
  • key_uvopt.bak
    73.5KB
  • key_uvproj.bak
    13.1KB
  • key.uvproj
    13.1KB
  • si
  • key.IAB
    4KB
  • key.PO
    776B
  • key.SearchResults
    745B
  • key.PRI
    6.4KB
  • key.PFI
    12B
  • key.PS
    11.8KB
  • key.PR
    1.4KB
  • key.IMD
    368B
  • key.WK3
    18.9KB
  • key.IAD
    368B
  • key.IMB
    4KB
  • src
  • key.c
    7.6KB
  • main.c
    85B
  • key.h
    2KB
  • key.rar
    51.4KB
内容介绍
#include <reg52.h> #include "key.h" //修改按键个数,最大不得超过12个 #define GPIO_KEY_NUM 3 ///< 定义按键成员总数 keyTypedef_t singleKey[GPIO_KEY_NUM]; ///< 定义单个按键成员数组指针 keysTypedef_t keys; ///< 定义总的按键模块结构体指针 gpio_addr_t gpio_addr; gpio_t gpio; /***********************建议不要修改*************************************/ unsigned char keyCountTime; static unsigned char keyTotolNum = 0; unsigned char _PX_Value(gpio_addr_t px) { unsigned char value=0; switch(px) { case p0_:value=P0;break; case p1_:value=P1;break; case p2_:value=P2;break; case p3_:value=P3;break; // case p4_:value=P4;break; // case p5_:value=P5;break; } return value; } /** * @brief Read the GPIO state * @param [in] keys 按键功能全局结构体指针 * @return unsigned int型的GPIO状态值 */ unsigned int getKey(keysTypedef_t *keyS) { unsigned char i = 0,px=0; unsigned int readKey = 0; //必要,初始化 unsigned char PX_Value=0; //GPIO Cyclic scan for(i = 0; i < keys.keyTotolNum; i++)//根据按键数,循环扫描 { px |=keyS->singleKey[i].keyx; PX_Value=_PX_Value(keyS->singleKey[i].keyPx); if(PRESS_DOWN_STATUS==(PX_Value & px )) { G_SET_BIT(readKey, keyS->singleKey[i].keyNum);//哪一个按键按下,就将readKey的哪个位置一 } px=0; } return readKey; } /** * @brief Read the KEY value * @param [in] keys 按键功能全局结构体指针 * @return unsigned int型的按键状态值 */ unsigned int readKeyValue(keysTypedef_t *keyS) { static unsigned char keyCheck = 0; static unsigned char keyState = 0; static unsigned int keyLongCheck = 0; static unsigned int keyPrev = 0; //上一次按键 unsigned int keyPress = 0; unsigned int keyReturn = 0; keyCountTime +=KEY_TIMER_MS;//每个定时器中断进入一次 2ms if(keyCountTime >= KEY_DELAY_MS) // 按键消抖时长 { keyCountTime = 0; keyCheck = 1; } if(1 == keyCheck)//进入一次 { keyCheck = 0; keyPress = getKey(keyS); switch (keyState) { case 0://按键未按下 if(keyPress != 0) { keyPrev = keyPress; keyState = 1; } break; case 1://按键按下,判断是不是抖动 if(keyPress == keyPrev)//不是抖动 { keyState = 2; keyReturn= keyPrev | KEY_DOWN;//按键未松开,哪个按键按下就将哪个位置一 } else //按键抬起,是抖动,不响应按键 { keyState = 0; } break; case 2: if(keyPress != keyPrev)//按键已松开,不是长按键 { keyState = 0; keyLongCheck = 0;// keyReturn = keyPrev | KEY_UP;//按键已松开,哪个按键按下就将哪个位置一 return keyReturn; } if(keyPress == keyPrev)//判断是不是长按键 { keyLongCheck++; if(keyLongCheck >= PRESS_LONG_TIME_S) //长按3S有效 { keyLongCheck = 0; keyState = 3; keyReturn= keyPress | KEY_LONG;//按键未松开,是长按键 return keyReturn; } } break; case 3: if(keyPress != keyPrev)//一次按键扫描已完成,等待按键松开,按键不松开就一直调到case 3执行 { keyState = 0; } break; } } return NO_KEY; } /** * @brief 按键回调函数 * 在该函数内完成按键状态监测后调用对应的回调函数 * @param [in] keys 按键功能全局结构体指针 * @return none */ void keyHandle(keysTypedef_t *keyS) { unsigned char i = 0; unsigned int key_value = 0; key_value = readKeyValue(keyS); if(!key_value) return; //Check short press button if(key_value & KEY_UP) { //Valid key is detected for(i = 0; i < keyS->keyTotolNum; i++)//循环扫描,查找出是哪个按键按下 { //判断key_value置1的位数与哪一个keyTypedef_t结构体元素keyNum相等 if(G_IS_BIT_SET(key_value, keyS->singleKey[i].keyNum)) // { //key callback function of short press if(keyS->singleKey[i].shortPress) //如果初始化有回调函数 { keyS->singleKey[i].shortPress(); //执行回调函数 } } } } //Check short long button if(key_value & KEY_LONG) { //Valid key is detected for(i = 0; i < keyS->keyTotolNum; i++) { if(G_IS_BIT_SET(key_value, keyS->singleKey[i].keyNum)) { //key callback function of long press if(keyS->singleKey[i].longPress) { keyS->singleKey[i].longPress(); } } } } } /** * @brief 单按键初始化 * 在该函数内完成单个按键的初始化,这里需要结合STM32 GPIO寄存器配置设置参数 * @param [in] keyPx GPIO_pins_define * @param [in] short_press 短按状态的回调函数地址 * @param [in] long_press 长按状态的回调函数地址 * @return 单按键结构体指针 */ keyTypedef_t keyInitOne(gpio_addr_t keyPx,gpio_t keyx, gokitKeyFunction shortPress, gokitKeyFunction longPress) { static char key_total = -1; keyTypedef_t singleKey; //Platform-defined GPIO singleKey.keyPx = keyPx; singleKey.keyx = keyx; singleKey.keyNum = ++key_total; //Button trigger callback type singleKey.longPress = longPress; singleKey.shortPress = shortPress; keyTotolNum++; return singleKey; } /*********************以上部分不要修改,以下为用户添加函数,可自行修改************************************ @因为按键回调函数都是在中断中执行的,建议不要在回调函数中 执行过多的代码。可设立按键标志位,在主函数中执行按键操作函数。 用杜邦线连接按键时,有时会松动,导致长按变短按,故此时推荐使用短按事件即可。 ***************************************************************************/ void Timer0Init(void) //2毫秒@22.1184MHz { // AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x33; //设置定时初值 TH0 = 0x53; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; } void t0_interrupt() interrupt 1 { keyHandle((keysTypedef_t *)&keys); } /********** @按键的回调函数。 当有按键按下时会在定时器中断中执行,函数的执行时间不应超过定时器的中断时间。 或者可声明一个标志位,在main.c while{}大循环中扫描该标志位 **********/ char flag,flag2,flag3,flag4,flag5; void key1_Shrot(void) { flag = !flag; } void key1_Long(void) { flag2 = !flag2; } void key2_Shrot(void) { flag3 = !flag3; } void key3_Long(void) { flag4 = !flag4; } /*在主函数中调用此函数*/ void key_Init(void) { singleKey[0]=keyInitOne(p1_,px_0,key1_Shrot,key1_Long); singleKey[1]=keyInitOne(p2_,px_2,key2_Shrot,(void*)0); singleKey[2]=keyInitOne(p2_,px_3,(void*)0,key3_Long); keys.singleKey=(keyTypedef_t*)&singleKey; if( keyTotolNum >12) keyTotolNum=12; keys.keyTotolNum = keyTotolNum;//按键数量 Timer0Init(); }
评论
    相关推荐
    • ourdev_429803.zip
      基于STM8的状态机按键程序,长短按功能,双击功能
    • Single-key-program.rar
      该程序为单个按键实现短击、长击和双击,基于状态机编程思想。
    • Btn_State_Machine_Module-V1.10.zip
      按键模块程序,支持按键长按双击,可以配置多个按键
    • 16-状态机按键查询.zip
      基于STM8S的按键状态机程序,使用C语言、IAR开发环境,可以使用Visual Studio code 跨平台打开,已有代码可实现单击、双击、长按,可进行相应修改适应各单片机平台
    • MultiButton-master.rar
      适合st平台和其他平台的按键函数,包含短按、长按、双击
    • 多普达S1闹钟手机软件
      多普达S1的手机闹钟软件,我使用的时候是windows mobile 6.0,不确定高一点的能用不
    • S201室外枪机防水摄录一体
      产品在通电工作中,如果要取卡读取里面的内容,请先按按键保存当前录像内容,按按键后红/蓝灯同时常亮,处于待机状态。视频文件已经保存可以取出TF卡,取卡后红灯快闪。再次插入TF卡时,红蓝灯又同时常亮,按下按键...
    • AxisCam(SketchUp定轨相机插件)V1.0.4最新免费汉化版
      Axis Cam(SketchUp定轨相机插件)是一款非常实用的SketchUp定轨相机插件,通过这款定轨相机插件...按键说明 点击命令打开相机面板,选择目标对象后,保持面板处于激活状态后,通过方向键和ASDW及Shift键来控制相机。
    • dhdvr大华录象手册
      http://ys-e.ys168.com/2.0/81664201/jTtUhJk5S2K562V3J4Mxfu/二代通用硬盘录像使用手册(通用)200612.rar
    • Proteus7.12.rar
      Proteus7.12完美破解版.rar电路仿真软件很好用可以仿真单片数字模拟电路