搜索
bottom↓
回复: 5

求STM32矩阵按键状态机程序

[复制链接]

出0入4汤圆

发表于 2019-7-9 09:41:37 | 显示全部楼层 |阅读模式
现有个产品需要矩阵按键状态机程序,写了几天,还是有问题,哪位大神给分享一个历程

出0入0汤圆

发表于 2019-7-9 10:29:49 | 显示全部楼层
本帖最后由 xld826 于 2019-7-9 13:41 编辑

目前支持抬起识别。可以修改支持短按按下识别,短按抬起识别,长按按下识别,长按抬起识别。
  1. void MatrixKeyScan(unsigned char ucKeyValue[4][4])
  2. {
  3.         static unsigned char ucKeyState[4][4] = {KEY_STATE_0, KEY_STATE_0, KEY_STATE_0, KEY_STATE_0};
  4.         static unsigned char ucKeyTime[4][4] = {0, 0, 0, 0};
  5.         unsigned char ucKeyPress[4], i = 0, j = 0;
  6.        
  7.           for(j = 0; j < 4; j++)
  8.           {
  9.                 LineOutCtrl(j, SET);
  10.                   for(i = 0; i < 4; i++)
  11.                   {
  12.                         ColumnScan(i, ucKeyPress);
  13.                         //printf("\r\n %d %d %d", j, i, ucKeyPress[i]);
  14.                        
  15.                         switch (ucKeyState[j][i])
  16.                         {
  17.                                 case KEY_STATE_0:
  18.                                 if (!ucKeyPress[i])
  19.                                 {
  20.                                         ucKeyState[j][i] = KEY_STATE_1;
  21.                                 }
  22.                                 break;

  23.                                 case KEY_STATE_1:
  24.                                 if (!ucKeyPress[i])
  25.                                 {
  26.                                         ucKeyTime[j][i] = 0;
  27.                                         ucKeyState[j][i] = KEY_STATE_2;
  28.                                 }
  29.                                 else
  30.                                 {
  31.                                         ucKeyState[j][i] = KEY_STATE_0;
  32.                                 }
  33.                                 break;

  34.                                 case KEY_STATE_2:
  35.                                 if(ucKeyPress[i])
  36.                                 {
  37.                                         ucKeyState[j][i] = KEY_STATE_0;
  38.                                 }
  39.                                 else
  40.                                 {
  41.                                         ucKeyTime[j][i]++;
  42.                                         if(ucKeyTime[j][i] == 1)
  43.                                         {
  44.                                                 ucKeyState[j][i] = KEY_STATE_3;
  45.                                         }
  46.                                 }
  47.                                 break;
  48.                                 case KEY_STATE_3:
  49.                                 if (ucKeyPress[i])
  50.                                 {
  51.                                         ucKeyValue[j][i] = (i + j * 4 + 1);
  52.                                         ucKeyState[j][i] = KEY_STATE_0;
  53.                                 }
  54.                                 else
  55.                                 {
  56.                                 }
  57.                                 break;
  58.                                 default:
  59.                                 break;
  60.                         }
  61.                   }
  62.                 LineOutCtrl(j, RESET);
  63.           }
  64. }


  65. void ColumnScan(U8 Index, U8 *KeyPress)
  66. {
  67.         switch(Index)
  68.         {
  69.                 case 0:
  70.                         if(GPIO_ReadInputDataBit(KEYIN1_PORT, KEYIN1_PIN) == RESET)
  71.                         KeyPress[Index] = 0;//按下
  72.                         else
  73.                         KeyPress[Index] = 1;//抬起
  74.                 break;
  75.                 case 1:
  76.                         if(GPIO_ReadInputDataBit(KEYIN2_PORT, KEYIN2_PIN) == RESET)
  77.                         KeyPress[Index] = 0;
  78.                         else
  79.                         KeyPress[Index] = 1;
  80.                 break;
  81.                 case 2:
  82.                         if(GPIO_ReadInputDataBit(KEYIN3_PORT, KEYIN3_PIN) == RESET)
  83.                         KeyPress[Index] = 0;
  84.                         else
  85.                         KeyPress[Index] = 1;
  86.                 break;
  87.                 case 3:
  88.                         if(GPIO_ReadInputDataBit(KEYIN4_PORT, KEYIN4_PIN) == RESET)
  89.                         KeyPress[Index] = 0;
  90.                         else
  91.                         KeyPress[Index] = 1;
  92.                 break;
  93.                 default:
  94.                 break;
  95.         }
  96.         //printf("\r\n %d %d", Index, KeyPress[Index]);
  97. }

  98. void LineOutCtrl(U8 Index, U8 en)
  99. {
  100.         switch(Index)
  101.         {
  102.                 case 0:
  103.                         if(!en)
  104.                         GPIO_SetBits(KEYOUT1_PORT, KEYOUT1_PIN);
  105.                         else
  106.                         GPIO_ResetBits(KEYOUT1_PORT, KEYOUT1_PIN);
  107.                 break;
  108.                 case 1:
  109.                         if(!en)
  110.                         GPIO_SetBits(KEYOUT2_PORT, KEYOUT2_PIN);
  111.                         else
  112.                         GPIO_ResetBits(KEYOUT2_PORT, KEYOUT2_PIN);
  113.                 break;
  114.                 case 2:
  115.                         if(!en)
  116.                         GPIO_SetBits(KEYOUT3_PORT, KEYOUT3_PIN);
  117.                         else
  118.                         GPIO_ResetBits(KEYOUT3_PORT, KEYOUT3_PIN);
  119.                 break;
  120.                 case 3:
  121.                         if(!en)
  122.                         GPIO_SetBits(KEYOUT4_PORT, KEYOUT4_PIN);
  123.                         else
  124.                         GPIO_ResetBits(KEYOUT4_PORT, KEYOUT4_PIN);
  125.                 break;
  126.                
  127.                 default:
  128.                 break;
  129.         }
  130.        
  131. }

  132. #define KEYOUT1_PORT                        GPIOA
  133. #define KEYOUT1_PIN                                GPIO_Pin_0
  134. #define KEYOUT2_PORT                        GPIOA
  135. #define KEYOUT2_PIN                                GPIO_Pin_1
  136. #define KEYOUT3_PORT                        GPIOA
  137. #define KEYOUT3_PIN                                GPIO_Pin_2
  138. #define KEYOUT4_PORT                        GPIOA
  139. #define KEYOUT4_PIN                                GPIO_Pin_3

  140. #define KEYIN1_PORT                                GPIOA
  141. #define KEYIN1_PIN                                GPIO_Pin_4
  142. #define KEYIN2_PORT                                GPIOA
  143. #define KEYIN2_PIN                                GPIO_Pin_5
  144. #define KEYIN3_PORT                                GPIOA
  145. #define KEYIN3_PIN                                GPIO_Pin_6
  146. #define KEYIN4_PORT                                GPIOA
  147. #define KEYIN4_PIN                                GPIO_Pin_7

  148. #define KEY_STATE_0 0
  149. #define KEY_STATE_1 1
  150. #define KEY_STATE_2 2
  151. #define KEY_STATE_3 3
  152. #define KEY_STATE_4 4

  153. #define N_KEY       0xFE

  154. void Task_10ms(void)
  155. {
  156.         static U8 ucCount = 0;
  157.         U8 ucKeyValue[4][4] = {
  158.         {N_KEY, N_KEY, N_KEY, N_KEY},
  159.         {N_KEY, N_KEY, N_KEY, N_KEY},
  160.         {N_KEY, N_KEY, N_KEY, N_KEY},
  161.         {N_KEY, N_KEY, N_KEY, N_KEY}
  162.         }, i = 0, j = 0;

  163.         MatrixKeyScan(ucKeyValue);
  164.         for(j = 0; j < 4; j++)
  165.         {
  166.                 for(i = 0; i < 4; i++)
  167.                 {
  168.                         if(ucKeyValue[j][i] != N_KEY)
  169.                         {
  170.                                 printf("\r\n ucKeyValue 测试计数:%d %d",ucCount++, ucKeyValue[j][i]);
  171.                         }
  172.                 }
  173.         }
  174. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2019-7-9 10:42:12 | 显示全部楼层
坛子里很多类似的状态机,自己搜一下,取长补短

出0入4汤圆

发表于 2019-7-9 12:54:22 | 显示全部楼层
xld826 发表于 2019-7-9 10:29
目前支持抬起识别。可以修改支持短按按下识别,短按抬起识别,长按按下识别,长按抬起识别。

有乱码                     

出110入8汤圆

发表于 2019-7-12 18:05:35 | 显示全部楼层
按照安福莱的单个按键驱动改一下按键的的扫描函数就好,支持短按,长按,连发,弹起。

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-20 04:40

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

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