你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F103——矩阵按键+串口打印

[复制链接]
STMCU小助手 发布时间:2022-8-22 15:26
基本介绍
最近做了一个门禁卡小玩意,用到了4X4矩阵按键,在这里也单独的记录一下。
矩阵按键图

89353c6dd6ec4f899600752e71cbafe8.png
思路:
矩阵按键读取键值写法多样,有一行一行的检测,也有是全部行检测,我这里是全部去扫。
先扫描4列是否有按下,有 再切换 扫描所有行。

第一步:先让行拉低(输出模式),去检测列(输入模式 拉高)
                        如果检测到有
第二步:让列拉低(输出模式), 去检测行(输入模式 拉高)
第三步:这样就可以获取到哪按键按下了。

代码
matrix_key.c
  1. #include "matrix_key.h"
  2. #include "usart.h"

  3. uint8_t key_flag;               



  4. /*4X4矩阵按键的表盘设置*/
  5. const uint8_t matrix_key_tab[4][4] =
  6. {
  7.         '1', '2', '3', 'A',
  8.         '4', '5', '6', 'B',
  9.         '7', '8', '9', 'C',
  10.         '*', '0', '#', 'D',
  11. };




  12. /***********************************************************************
  13. 描述: 按键 列 设置输入模式(前4个)
  14. ************************************************************************/
  15. void key_set_list_input_mode(void)
  16. {
  17.         GPIO_InitTypeDef KEY_InitStruction;
  18.         RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
  19.         
  20.         //列引脚
  21.         KEY_InitStruction.GPIO_Pin   = KEY5_PIN | KEY6_PIN | KEY7_PIN | KEY8_PIN;        //引脚
  22.         KEY_InitStruction.GPIO_Mode  = GPIO_Mode_IPU;                                                                 //上拉输入        
  23.         GPIO_Init(KEY_PORT, &KEY_InitStruction);
  24.         
  25. }


  26. /***********************************************************************
  27. 描述: 按键 列 设置输出模式
  28. ************************************************************************/
  29. void key_set_list_output_mode(void)
  30. {
  31.         GPIO_InitTypeDef KEY_InitStruction;
  32.         RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
  33.         
  34.         //列引脚
  35.         KEY_InitStruction.GPIO_Pin   = KEY5_PIN | KEY6_PIN | KEY7_PIN | KEY8_PIN;        //引脚
  36.         KEY_InitStruction.GPIO_Mode  = GPIO_Mode_Out_PP;                                                         //推挽输出        
  37.         KEY_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;                                                        //速率
  38.         
  39.         GPIO_Init(KEY_PORT, &KEY_InitStruction);
  40. }




  41. /***********************************************************************
  42. 描述: 按键 行 设置输入模式
  43. ************************************************************************/
  44. void key_set_row_input_mode(void)
  45. {
  46.         GPIO_InitTypeDef KEY_InitStruction;
  47.         RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
  48.         
  49.         //列引脚
  50.         KEY_InitStruction.GPIO_Pin   = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;        //引脚
  51.         KEY_InitStruction.GPIO_Mode  = GPIO_Mode_IPU;                                                                 //上拉输入        
  52.         GPIO_Init(KEY_PORT, &KEY_InitStruction);
  53. }


  54. /***********************************************************************
  55. 描述: 按键 行 设置输出模式
  56. ************************************************************************/
  57. void key_set_row_output_mode(void)
  58. {
  59.         GPIO_InitTypeDef KEY_InitStruction;
  60.         RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
  61.         
  62.         //列引脚
  63.         KEY_InitStruction.GPIO_Pin   = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;        //引脚
  64.         KEY_InitStruction.GPIO_Mode  = GPIO_Mode_Out_PP;                                                         //推挽输出        
  65.         KEY_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;                                                        //速率
  66.         
  67.         GPIO_Init(KEY_PORT, &KEY_InitStruction);

  68. }


  69. /***********************************************************************
  70. 描述: 按键初始化函数
  71. ************************************************************************/
  72. void matrix_key_init(void)
  73. {        
  74.         ROW_OUT_MODE;                //行设置输出模式
  75.         LIST_INT_MODE;                //列设置输入模式
  76. }


  77. /***********************************************************************
  78. 描述: 获取键值 函数
  79. 返回: 返回表盘对应键值
  80. ************************************************************************/
  81. uint8_t matrix_key_scanf(void)
  82. {
  83.         static uint8_t key_status;        
  84.         uint8_t R,L;
  85.         uint8_t key_temp;
  86.         
  87.         //检测列 所以我们让行拉低 列拉高
  88.         LIST_INT_MODE;        LIST_SET_HIGH;
  89.         ROW_OUT_MODE;        ROW_SET_LOW;
  90.         
  91.         key_temp = ~GPIO_ReadInputData(KEY_PORT) & 0XF0;
  92.         if(key_temp == 0) {key_status = 0; return 0;}
  93.         
  94.         //第一次检测到
  95.         if(key_status == 0)
  96.         {
  97.                 key_status = 1;        
  98.                 return 0;
  99.         }
  100.         //第二次检测到
  101.         else if(key_status == 1)
  102.         {
  103.                 key_status = 2;
  104.                
  105.                 //读取列
  106.                 switch(key_temp)
  107.                 {
  108.                         case 0x10:        L = 0;        break;
  109.                         case 0x20:        L = 1;        break;
  110.                         case 0x40:        L = 2;        break;
  111.                         case 0x80:        L = 3;        break;               
  112.                         default:        return 0;
  113.                 }
  114.                 //快速转换模式
  115.                 //再检测行是否有按键按下 所以先让列拉低 行拉高
  116.                 LIST_OUT_MODE;        LIST_SET_LOW;        //PA4 ~ PA7
  117.                 ROW_INT_MODE;        ROW_SET_HIGH;        //PA0 ~ PA3

  118.                 key_temp = ~GPIO_ReadInputData(KEY_PORT) & 0X0F;
  119.                 //读取行
  120.                 switch(key_temp)
  121.                 {
  122.                         
  123.                         case 0x01:        R = 0;        break;
  124.                         case 0x02:        R = 1;        break;
  125.                         case 0x04:        R = 2;        break;
  126.                         case 0x08:        R = 3;        break;
  127.                         default:        return 0;
  128.                 }

  129.                 return matrix_key_tab[R][L];;
  130.         }
  131.         //证明没松开按键
  132.         else if(key_status == 2)
  133.         {
  134.                 return 0;
  135.         }
  136.         key_status = 0;
  137.         return 0;

  138. }



  139. /***********************************************************************
  140. 描述: 矩阵键盘处理 函数
  141. ************************************************************************/
  142. void matrix_key_process(void)
  143. {
  144.         uint8_t key_val;
  145.         
  146.         if(key_flag)
  147.         {
  148.                 key_flag = 0;
  149.                 key_val = matrix_key_scanf();                        //获取键值
  150.                 if(key_val == 0) return;        
  151.                 printf("KEY:%c\r\n",key_val);
  152.         }        
  153. }

复制代码

matrix_key.h
  1. #ifndef __MATRIX_KEY_H
  2. #define __MATRIX_KEY_H
  3. #include "stm32f10x.h"

  4. #define         KEY_RCC                        RCC_APB2Periph_GPIOA                //时钟
  5. #define         KEY_PORT                GPIOA                                                //端口


  6. #define         KEY1_RCC                RCC_APB2Periph_GPIOA                //时钟
  7. #define         KEY1_PORT                GPIOA                                                //端口
  8. #define         KEY1_PIN                GPIO_Pin_0                                        //引脚

  9. #define         KEY2_RCC                RCC_APB2Periph_GPIOA                //时钟
  10. #define         KEY2_PORT                GPIOA                                                //端口
  11. #define         KEY2_PIN                GPIO_Pin_1                                        //引脚

  12. #define         KEY3_RCC                RCC_APB2Periph_GPIOA                //时钟
  13. #define         KEY3_PORT                GPIOA                                                //端口
  14. #define         KEY3_PIN                GPIO_Pin_2                                        //引脚

  15. #define         KEY4_RCC                RCC_APB2Periph_GPIOA                //时钟
  16. #define         KEY4_PORT                GPIOA                                                //端口
  17. #define         KEY4_PIN                GPIO_Pin_3                                        //引脚

  18. #define         KEY5_RCC                RCC_APB2Periph_GPIOA                //时钟
  19. #define         KEY5_PORT                GPIOA                                                //端口
  20. #define         KEY5_PIN                GPIO_Pin_4                                        //引脚

  21. #define         KEY6_RCC                RCC_APB2Periph_GPIOA                //时钟
  22. #define         KEY6_PORT                GPIOA                                                //端口
  23. #define         KEY6_PIN                GPIO_Pin_5                                        //引脚

  24. #define         KEY7_RCC                RCC_APB2Periph_GPIOA                //时钟
  25. #define         KEY7_PORT                GPIOA                                                //端口
  26. #define         KEY7_PIN                GPIO_Pin_6                                        //引脚

  27. #define         KEY8_RCC                RCC_APB2Periph_GPIOA                //时钟
  28. #define         KEY8_PORT                GPIOA                                                //端口
  29. #define         KEY8_PIN                GPIO_Pin_7                                        //引脚


  30. #define                ROW_INT_MODE        key_set_row_input_mode()
  31. #define                ROW_OUT_MODE        key_set_row_output_mode()

  32. #define                LIST_INT_MODE        key_set_list_input_mode()
  33. #define                LIST_OUT_MODE        key_set_list_output_mode()

  34. #define         LIST_SET_HIGH        {GPIO_SetBits(KEY_PORT,KEY5_PIN);GPIO_SetBits(KEY_PORT,KEY6_PIN);GPIO_SetBits(KEY_PORT,KEY7_PIN);GPIO_SetBits(KEY_PORT,KEY8_PIN);}
  35. #define         LIST_SET_LOW        {GPIO_ResetBits(KEY_PORT,KEY5_PIN);GPIO_ResetBits(KEY_PORT,KEY6_PIN);GPIO_ResetBits(KEY_PORT,KEY7_PIN);GPIO_ResetBits(KEY_PORT,KEY8_PIN);}

  36. #define         ROW_SET_HIGH        {GPIO_SetBits(KEY_PORT,KEY1_PIN);GPIO_SetBits(KEY_PORT,KEY2_PIN);GPIO_SetBits(KEY_PORT,KEY3_PIN);GPIO_SetBits(KEY_PORT,KEY4_PIN);}
  37. #define         ROW_SET_LOW                {GPIO_ResetBits(KEY_PORT,KEY1_PIN);GPIO_ResetBits(KEY_PORT,KEY2_PIN);GPIO_ResetBits(KEY_PORT,KEY3_PIN);GPIO_ResetBits(KEY_PORT,KEY4_PIN);}



  38. extern const uint8_t key_tab[4][5];
  39. extern uint8_t key_flag;



  40. void key_set_list_input_mode(void);                //按键 列 设置输入模式
  41. void key_set_list_output_mode(void);        //按键 列 设置输出模式
  42. void key_set_row_input_mode(void);                //按键 行 设置输入模式
  43. void key_set_row_output_mode(void);                //按键 行 设置输出模式

  44. void matrix_key_init(void);                //按键初始化
  45. uint8_t matrix_key_scanf(void);        //获取按键键值
  46. void matrix_key_process(void);
  47. #endif
复制代码

main.c
  1. #include "stm32f10x.h"
  2. #include "timer.h"
  3. #include "matrix_key.h"
  4. #include "usart.h"

  5. /*
  6. 接线:
  7. 4X4矩阵按键
  8. 行:        PA0 ~ PA3
  9. 列: PA4 ~ PA7
  10. */


  11. int  main()
  12. {

  13.         usart1_init(115200);        //串口1初始化   用于输出键值
  14.         matrix_key_init();                //矩阵按键初始化
  15.         timer3_init();                        //定时器3初始化 用于去检测按键

  16.         while(1)
  17.         {        
  18.                 matrix_key_process();        //矩阵按键检测和处理
  19.         }  
  20. }
复制代码

项目演示

eda0469feea1436b806c40a56b26eca6.png

如果我哪里写的有问题,或者不好,请大家多多指教

  1. #整个工程代码。
  2. printf("+meQ:844797079\n")
复制代码

————————————————
转载:皮卡丘吉尔



收藏 评论0 发布时间:2022-8-22 15:26

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版