1回答

1收藏

玩GD32F450那些事之4x4薄片矩阵按键

GD32 GD32 7471 人阅读 | 1 人回复 | 2017-06-06

玩GD32F450那些事之4x4薄片矩阵按键
一、前言
          好久没有出来写贴子了,这上一个月还真忙,每天不是焊板子就是在调代码,还好上个月四套作品成功的完成了。。。一看时间擦擦擦!爱板也要交作品了,工作人员都催了几通了,但不要急哦!东西都构思好了,淘宝买了一个模块,正在坐等快递啦!不过今天先抽点时间来发一个基础点的--4x4矩阵键盘。

二、薄片4x4薄片矩阵键盘
       薄膜4×4矩阵键盘,我想很多朋友玩C51时定然玩过,可能到了STM32时也有部分人玩过,昨天看GD32F450中没人写这个,我就补个漏,大家别嫌弃哦。下面图1是实物图,图2为内部电路图

图1 实物图


     图2 内部电路图
       正如图中所示,该矩阵键盘和其它的矩阵键盘没啥两样,8根线来控制,其中 1,2,3,4定义为低4位,5,6,7,8位定义为高4位。该矩阵键盘和板子的链接正如图2所示。
                                  1-->PE15,          2-->PE13,       3-->PE12,              4-->PE11,
                                  5-->PE10,          6-->PE9,         7-->PE8,                8-->PE7
三、代码
        1、引脚初始化
  1. <font size="4">void BT4x4_gpio_config(void)
  2. {
  3. /* enable the BT clock */
  4. rcu_periph_clock_enable(RCU_GPIOE);
  5. /* configure BT GPIO port PE0 PE1*/
  6. gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15);
  7. gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
  8. gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
  9. }</font>
复制代码
         2、键值检测
        本套代码的设计是将高4位循环的给低电平,其它位给高电平,这时去读低四位的状态,比如说当我们的第8位给高,这时高四位就为 1110,这时读到低四位是0111,很明显是第4个按键按下了,对应的矩阵键盘是“D”。具体实现见下面代码:
  1. <font size="4">uint16_t Read4x4Hinght(void)
  2. {
  3. uint16_t Data=0;
  4. uint16_t keynumble=20;
  5. gpio_bit_set(GPIOE,GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_8);
  6. gpio_bit_reset(GPIOE,GPIO_PIN_7);
  7. delay_1ms(1);
  8. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  9. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  10. if(Data!=0x0f)
  11. {
  12. delay_1ms(1);
  13. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  14. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  15. if(Data!=0x0f)
  16. {
  17. switch(Data)
  18. {
  19. case 0x07: keynumble = 13;//D
  20. break;
  21. case 0x0b: keynumble = 12;//C
  22. break;
  23. case 0x0d: keynumble = 11;//B
  24. break;
  25. case 0x0e: keynumble = 10;//A
  26. break;
  27. default:
  28. break;
  29. }
  30. while(Data!=0x0f)
  31. {
  32. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  33. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  34. }
  35. return keynumble;
  36. }
  37. }

  38. gpio_bit_set(GPIOE,GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_7);
  39. gpio_bit_reset(GPIOE,GPIO_PIN_8);
  40. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  41. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);

  42. if(Data!=0x0f)
  43. {
  44. delay_1ms(1);
  45. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  46. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  47. if(Data!=0x0f)
  48. {
  49. switch(Data)
  50. {
  51. case 0x07: keynumble = 14;//#
  52. break;
  53. case 0x0b: keynumble = 9;
  54. break;
  55. case 0x0d: keynumble = 6;//11
  56. break;
  57. case 0x0e: keynumble = 3;//14
  58. break;
  59. default:
  60. break;
  61. }
  62. while(Data!=0x0f)
  63. {
  64. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  65. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  66. }
  67. return keynumble;
  68. }
  69. }

  70. gpio_bit_set(GPIOE,GPIO_PIN_10|GPIO_PIN_8|GPIO_PIN_7);
  71. gpio_bit_reset(GPIOE,GPIO_PIN_9);
  72. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  73. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);

  74. if(Data!=0x0f)
  75. {
  76. delay_1ms(1);
  77. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  78. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  79. if(Data!=0x0f)
  80. {
  81. switch(Data)
  82. {
  83. case 0x07: keynumble = 0;//2
  84. break;
  85. case 0x0b: keynumble = 8;//7
  86. break;
  87. case 0x0d: keynumble = 5;//5
  88. break;
  89. case 0x0e: keynumble = 2;//15
  90. break;
  91. default:
  92. break;
  93. }
  94. while(Data!=0x0f)
  95. {
  96. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  97. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  98. }
  99. return keynumble;
  100. }
  101. }

  102. gpio_bit_set(GPIOE,GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7);
  103. gpio_bit_reset(GPIOE,GPIO_PIN_10);
  104. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  105. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);

  106. if(Data!=0x0f)
  107. {
  108. delay_1ms(2);
  109. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  110. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  111. if(Data!=0x0f)
  112. {
  113. switch(Data)
  114. {
  115. case 0x07: keynumble = 15;//*
  116. break;
  117. case 0x0b: keynumble = 7;//8
  118. break;
  119. case 0x0d: keynumble = 4;//9
  120. break;
  121. case 0x0e: keynumble = 1;//16
  122. break;
  123. default:
  124. break;
  125. }
  126. while(Data!=0x0f)
  127. {
  128. Data = (gpio_input_bit_get(GPIOE, GPIO_PIN_11)<<3)|(gpio_input_bit_get(GPIOE, GPIO_PIN_12)<<2)|\
  129. (gpio_input_bit_get(GPIOE, GPIO_PIN_13)<<1)|(gpio_input_bit_get(GPIOE, GPIO_PIN_15)<<0);
  130. }
  131. return keynumble;
  132. }
  133. }
  134. return keynumble;
  135. }</font>
复制代码
        3、键值串口打印
        通过高4位一位一位的轮流给低电平,然后读取对应状态下的低四位的结果来获取键值,不过这薄片键盘上存在“#”,“*”等符号,我们需要进一步处理后,再做串口显示,其代码如下:
  1. <font size="4">if(keychar!=20)
  2. {
  3. if(keychar<10)
  4. {
  5. printf("keynumble=%d\t\n",keychar);
  6. }
  7. else
  8. {
  9. switch (keychar)
  10. {
  11. case 10:printf("keynumble=A\t\n");
  12. break;
  13. case 11:printf("keynumble=B\t\n");
  14. break;
  15. case 12:printf("keynumble=C\t\n");
  16. break;
  17. case 13:printf("keynumble=D\t\n");
  18. break;
  19. case 14:printf("keynumble=#\t\n");
  20. break;
  21. case 15:printf("keynumble=*\t\n");
  22. break;
  23. default:
  24. break;
  25. }

  26. }</font>
复制代码
        到此矩阵键盘就实现了哦!!!其中串口部分配置大家看论坛分享或者直接下载我的代码。

四、实战演练
         轮流按下矩阵键盘上的16个键,串口一一显示对应的键值。

五、附件
     
代码奉上,由于写地匆忙,有很多地方完全可以精简和浓缩,就请大家自行优化下;对于其中的按键消抖和等待按下松开,大家按照自己实际硬件按键来调,因为硬件不同可能延迟时间上会有些差异。
Key4x4.rar (1019.39 KB, 下载次数: 24, 售价: 2 与非币)

关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

wolfgang2015

发表于 2017-6-7 11:50:53 | 只看该作者

经典的键盘扫描方式,不过提一个问题仅表思考方向:
按键的触发可以用中断,在单片机不使用ROTS的情况下,如何进行扫描循环呢?如果还有其他应用在使用,扫描键盘会不会被其他应用的循环拖累导致响应太慢?
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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