单片机交流
直播中

杨雪

7年用户 1049经验值
私信 关注
[问答]

如何去编写矩阵键盘的程序呢

矩阵键盘的原理是什么?
如何去编写矩阵键盘的程序呢?

回帖(1)

罗宗保

2021-10-26 17:29:15
  组内的小伙伴们从暑假开始的时候开始学习32也学了快20天了,昨天作为一个小检测吧,让他们焊了一个3*3的矩阵键盘然后写了键盘的驱动,虽然中间的过程有些曲折,但最后结果还是可以的,每个人都写出来了。
  我也画了键盘的原理图以及接线图,并且也写了键盘的驱动,在博客上记录一下吧。
  矩阵键盘的原理就是分行和列扫描,来获知按下按键的行数和列数,然后得到按下按键的键值
  矩阵键盘的原理图及接线图如下:
  
  因为四脚的微动按键的同一排引脚是相连的,相当于是一个同一个引脚,所以利用这个有点会大大简化我们的电路,不用做太多的飞线。
  接线效果图如下
  矩阵键盘的扫描原理为,先让三个横行或者三个竖列输出高电平,另外三个为输入模式,若扫描到高电平,则表示该行或该列有按键按下,接着切换输入输出,扫描另外三个,得到另外的坐标,由此确定按键按下的位置。
  F4的代码如下:
  key.h
  #ifndef __KEY_H
  #define __KEY_H
  #include “sys.h”
  //行操作宏定义
  #define Row1_Write PAout(0)
  #define Row2_Write PAout(2)
  #define Row3_Write PAout(3)
  #define Row1_Read PAin(0)
  #define Row2_Read PAin(2)
  #define Row3_Read PAin(3)
  //列操作宏定义
  #define Col1_Write PAout(7)
  #define Col2_Write PAout(6)
  #define Col3_Write PAout(4)
  #define Col1_Read PAin(7)
  #define Col2_Read PAin(6)
  #define Col3_Read PAin(4)
  #define PIN_OUT(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=1《《((x)*2);} //将IO口配置为输出
  #define PIN_IN(x) {GPIOA-》MODER&=~(3《《((x)*2));GPIOA-》MODER|=0《《((x)*2);} //将IO口配置为输入
  void KEY_Init(void); //IO初始化
  u8 KEY_Scan(u8); //按键扫描函数
  #endif
  key.c
  #include “key.h”
  #include “delay.h”
  #include “usart.h”
  void KEY_Init(void)
  {
  RCC-》AHB1ENR|=1《《0; //使能PORTA时钟
  GPIO_Set(GPIOA,PIN0|PIN2|PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0PA2PA3设置为输入
  GPIO_Set(GPIOA,PIN4|PIN6|PIN7,GPIO_MODE_OUT,0,0,GPIO_PUPD_PU); //推挽输出
  }
  //按键处理函数
  u8 KEY_Scan(u8 mode)
  {
  u8 res[4][4]={{0,0,0,0},{0,1,2,3},{0,4,5,6},{0,7,8,9}};
  u8 row=0,col=0;
  Col1_Write=1;
  Col2_Write=1;
  Col3_Write=1;
  //检测行
  if(Row1_Read==1||Row2_Read==1||Row3_Read==1)
  {
  delay_ms(10);//去抖动
  if(Row1_Read==1)
  row=1;
  else if(Row2_Read==1)
  row=2;
  else if(Row3_Read==1)
  row=3;
  }
  else
  return 0; //无按键按下
  //改变输入输出模式
  Col1_Write=0;
  Col2_Write=0;
  Col3_Write=0;
  PIN_OUT(0);
  PIN_OUT(2);
  PIN_OUT(3);
  PIN_IN(4);
  PIN_IN(6);
  PIN_IN(7);
  Row1_Write=1;
  Row2_Write=1;
  Row3_Write=1;
  //检测列
  if(Col1_Read==1)
  col=1;
  else if(Col2_Read==1)
  col=2;
  else if(Col3_Read==1)
  col=3;
  //还原IO口
  PIN_OUT(4);
  PIN_OUT(6);
  PIN_OUT(7);
  PIN_IN(0);
  PIN_IN(2);
  PIN_IN(3);
  if(row!=0&&col!=0)
  {
  return res[row][col];
  }
  else
  return 0;
  }
  主函数,扫描后在串口打印键值
  #include “sys.h”
  #include “delay.h”
  #include “key.h”
  #include “usart.h”
  #include “led.h”
  int main(void)
  {
  u8 key;
  Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
  uart_init(84,115200);
  delay_init(168); //延时初始化
  KEY_Init(); //初始化与按键连接的硬件接口
  LED_Init();
  LED0=0;
  while(1)
  {
  LED0=1;
  key=KEY_Scan(0); //得到键值
  if(key)
  {
  switch(key)
  {
  case 1:
  printf(“1rn”);
  break;
  case 2:
  printf(“2rn”);
  break;
  case 3:
  printf(“3rn”);
  break;
  case 4:
  printf(“4rn”);
  break;
  case 5:
  printf(“5rn”);
  break;
  case 6:
  printf(“6rn”);
  break;
  case 7:
  printf(“7rn”);
  break;
  case 8:
  printf(“8rn”);
  break;
  case 9:
  printf(“9rn”);
  break;
  }
  }
  LED0=0;
  }
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分