搜索
bottom↓
回复: 8

[分享]用坛子里各位大侠的按键程序,改成了一个自己想要的,放上来给各位参考和拍砖

[复制链接]

出0入55汤圆

发表于 2020-4-28 10:58:14 | 显示全部楼层 |阅读模式
大体是源于这位大侠的思想
【MultiButton】并发状态事件驱动按键驱动模块,量产产品实践
https://www.amobbs.com/thread-5658940-1-1.html
(出处: amobbs.com 阿莫电子论坛)

不过,改得有点面目全非了
1、不用再定义按键,想要直接注册一个就行(就一个注册函数SL_Regist),但也失去了同一个按键注册多个回调的可能,目前只能注册一个按键注册一个
    本来想再改成一个按键可以注册成多个回调的,但要同时定义一个事件,不合算,如果要malloc,这货有问题,有时候明明有空间,就是返回一个负数。。不敢用。遂算了,凑合着用
2、可以同时支持查询方式(SL_GetEvent),支持长按,支持组合(100ms扫一次,两个按键同时按还是比较容易按得到,实测,当然,扫描时间越快就越难)
3、。。好吧,其实原装也可以有这些,我只是想用的时候就仅仅调用一个函数就可以,不要一堆。。

程序小白,欢迎拍砖。。。

底层驱动
  1. #ifndef __BSP_SLOW_KEY_H
  2. #define __BSP_SLOW_KEY_H

  3. #ifdef __cplusplus  
  4. extern "C" {  
  5. #endif  

  6. #include "main.h"
  7.        
  8. //According to your need to modify the constants.
  9. //#define _SL_CYCLE                            5        //ms   °´¼üɨÃèʱ¼ä
  10. #define SL_LONG_TICKS                (2000 /_SL_CYCLE)

  11. typedef enum {
  12.         idSL_UP = 0,
  13.         idSL_LEFT,
  14.         idSL_RIGHT,
  15.         idSL_DOWN,
  16.         idSL_ENTER,
  17.         idSL_ESC,
  18.         idSL_number_of_id,
  19. }idSL_n;

  20. //typedef enum {
  21. //        SL_PRESS_DOWN = 0,
  22. //        SL_LONG_PRESS_HOLD,
  23. //        SL_PRESS_UP,
  24. //        SL_number_of_event,
  25. //        SL_NONE_PRESS
  26. //}SL_Event_n;
  27. #define SL_PRESS_DOWN                   0x01
  28. #define SL_LONG_PRESS_HOLD           0x02
  29. #define SL_PRESS_UP                           0x04
  30. #define SL_number_of_event           3
  31. #define SL_NONE_PRESS                   0x00

  32. typedef void (*SL_Callback)(void*);

  33. typedef struct _SL {
  34.         uint8_t  id;
  35.         uint8_t  event;
  36.         uint16_t contCnt;
  37.         uint8_t  trg;
  38.         uint8_t  cont;
  39.         SL_Callback  cb[SL_number_of_event];
  40.         struct _SL* next;
  41. }SL_t;

  42. void SL_Init(void);
  43. void SL_Scan(void);

  44. int SL_Regist(uint8_t id,uint8_t event,SL_Callback cb);
  45. uint8_t SL_GetEvent(uint8_t id);

  46. #ifdef __cplusplus
  47. }
  48. #endif

  49. #endif //__BSP_FAST_KEY_H
复制代码

  1. #include "main.h"

  2. static const uint8_t tabPORT[]         = {0,0,0,0,0,0,}; //按顺序排列要打开的内部电阻Px口(P0 P1 P2 P3 P4 P5 P6 P7)
  3. static const uint8_t tabPIN[]         = {0,1,2,3,4,5,}; //按顺序排列输入引脚号(Px0 Px1 Px2 Px3 Px4 Px5 Px6 Px7)
  4.        
  5. static SL_t mSL[idSL_number_of_id];
  6.        
  7. void SL_Init(void)
  8. {
  9.         uint8_t i;
  10.         memset(mSL, 0, sizeof(mSL));
  11.         for(i=0;i<idSL_number_of_id;i++){
  12.                 mSL[i].id = i;
  13.         }
  14. }

  15.        
  16. int SL_Regist(uint8_t id,uint8_t event,SL_Callback cb) //链表注册
  17. {
  18.         if(id>=idSL_number_of_id) return -1; //超出范围
  19.         if(event&SL_PRESS_DOWN)                 mSL[id].cb[0] = cb;
  20.         if(event&SL_LONG_PRESS_HOLD)         mSL[id].cb[1] = cb;
  21.         if(event&SL_PRESS_UP)                         mSL[id].cb[2] = cb;
  22.         return 0;
  23. }

  24. uint8_t SL_GetEvent(uint8_t id)
  25. {
  26.         static uint8_t eve[idSL_number_of_id];
  27.         if(eve[id]!=mSL[id].event || mSL[id].event==SL_LONG_PRESS_HOLD){ eve[id] = mSL[id].event;
  28.                 return eve[id];
  29.         }
  30.         return SL_NONE_PRESS;
  31. }

  32. #define EVENT_CB(ev)   if(mSL[id].cb[ev])mSL[id].cb[ev]((SL_t*)(&mSL[id]))  //回调函数
  33. void SL_Handler(int id)
  34. {
  35.         uint8_t keyReadBit = 0xff;
  36.         if(id>=sizeof(tabPIN)) return;
  37.        
  38.         switch(tabPORT[id]){
  39.                 case 0:{//P0
  40.                         keyReadBit = (P0&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  41.                         break;}
  42.                 case 1:{//P1
  43.                         keyReadBit = (P1&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  44.                         break;}
  45.                 case 2:{//P2
  46.                         keyReadBit = (P2&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  47.                         break;}
  48.                 case 3:{//P3
  49.                         keyReadBit = (P3&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  50.                         break;}
  51.                 case 4:{//P4
  52.                         keyReadBit = (P4&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  53.                         break;}
  54.                 case 5:{//P5
  55.                         keyReadBit = (P5&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  56.                         break;}
  57.                 case 6:{//P6
  58.                         keyReadBit = (P6&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  59.                         break;}
  60.                 case 7:{//P7
  61.                         keyReadBit = (P7&(0x01<<tabPIN[id])) ^ (0x01<<tabPIN[id]);
  62.                         break;}
  63.                 default:break;
  64.         }
  65.         mSL[id].trg = keyReadBit & (keyReadBit ^ mSL[id].cont);
  66.         mSL[id].cont = keyReadBit;
  67.         if(mSL[id].trg>0){ //printf("mSL[%d].trg=1\n",id);
  68.                 mSL[id].event = (uint8_t)SL_PRESS_DOWN;
  69.                 EVENT_CB(0);
  70.         }
  71.         if(mSL[id].cont>0){
  72.                 if(mSL[id].contCnt==SL_LONG_TICKS){        //printf("mSL[%d].cont\n",id);
  73.                         mSL[id].contCnt++;        //只触发一次,如果屏蔽此条就一直触发,做连续动作用,比如连加连减等操作.
  74.                         mSL[id].event = (uint8_t)SL_LONG_PRESS_HOLD;
  75.                         EVENT_CB(1);
  76.                 }
  77.                 else{
  78.                         mSL[id].contCnt++;
  79.                 }
  80.         }
  81.         else{
  82.                 if(mSL[id].contCnt>0) mSL[id].contCnt = 0;
  83.         }
  84.         if((mSL[id].trg==0)&&(mSL[id].cont==0)&&(mSL[id].event!=SL_PRESS_UP)){ //printf("mSL[%d].trg=0\n",id);
  85.                 mSL[id].event = SL_PRESS_UP;
  86.                 EVENT_CB(2);
  87.         }
  88. }

  89. void SL_Scan(void)
  90. {
  91.         int i;
  92.         static uint32_t tick_SL = 0;
  93.         if(Sys_GetTick()-tick_SL>=_SL_CYCLE){ tick_SL = Sys_GetTick();
  94.                 for(i=0; i<idSL_number_of_id; i++) {
  95.                         SL_Handler(i);
  96.                 }
  97.         }
  98. }

复制代码



回调使用
  1. SL_Regist(idSL_UP,SL_PRESS_DOWN,cbFn_idSL_UP);
  2. SL_Regist(idSL_LEFT,SL_PRESS_DOWN|SL_PRESS_UP,cbFn_idSL_LEFT);
  3. SL_Regist(idSL_RIGHT,SL_PRESS_DOWN|SL_PRESS_UP,cbFn_idSL_RIGHT);
  4. SL_Regist(idSL_DOWN,SL_PRESS_DOWN|SL_PRESS_UP,cbFn_idSL_DOWN);
  5. SL_Regist(idSL_ENTER,SL_PRESS_DOWN|SL_PRESS_UP,cbFn_idSL_ENTER);
复制代码


查询方式
  1.         static uint32_t tick = 0;
  2.         if(SL_PRESS_DOWN==SL_GetEvent(idSL_UP)){
  3.                         num++;
  4.         }else if(SL_PRESS_DOWN==SL_GetEvent(idSL_DOWN)){
  5.                         num--;
  6.         }else if(SL_PRESS_DOWN==SL_GetEvent(idSL_ENTER)){
  7.                         return 1;
  8.         }else if(SL_PRESS_DOWN==SL_GetEvent(idSL_ESC)){
  9.                         return 1;
  10.         }else if(SL_LONG_PRESS_HOLD==SL_GetEvent(idSL_UP)){
  11.                 if(Sys_GetTick()-tick>=100){ tick = Sys_GetTick();
  12.                         num++;
  13.                 }
  14.         }else if(SL_LONG_PRESS_HOLD==SL_GetEvent(idSL_DOWN)){
  15.                 if(Sys_GetTick()-tick>=100){ tick = Sys_GetTick();
  16.                         num--;
  17.                 }
  18.         }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2020-4-28 14:36:01 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2020-4-28 15:25:51 | 显示全部楼层
感谢!都是大师!  

出0入0汤圆

发表于 2020-4-28 15:57:01 | 显示全部楼层
按键程序,学习一下

出0入0汤圆

发表于 2020-5-21 14:25:58 | 显示全部楼层
顶一下,学习学习!

出140入115汤圆

发表于 2020-5-21 22:59:15 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2020-5-22 03:10:37 来自手机 | 显示全部楼层
感谢分享

出95入100汤圆

发表于 2020-5-22 20:53:19 | 显示全部楼层
嗯,可以鼓励

出0入0汤圆

发表于 2020-5-24 16:51:57 | 显示全部楼层
按键程序...
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 19:47

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表