版权声明:本文为博主原创文章,转载请附上原文出处链接。

文章目录

  • 前言
  • 一、硬件电路设计
    • 1.矩阵按键检测介绍
    • 2.矩阵按键检测原理介绍
  • 二、软件设计
    • 1.矩阵按键扫描实验 – 指示灯闪烁
      • 1.1.工程需要用到的c文件
      • 1.2.头文件引用和路径设置
      • 1.3.编写代码
      • 1.4.硬件连接
    • 2.矩阵按键扫描实验 – 串口调试助手
      • 2.1.工程需要用到的c文件
      • 2.2.编写代码
      • 2.3.硬件连接
  • 总结

前言

今天介绍下STC8A8K64S4A12系列单片机4x4矩阵按键检测电路的工作原理、4x4矩阵按键检测的程序设计。


一、硬件电路设计

1.矩阵按键检测介绍

在讲解输入按键检测时,总结了按键检测常见的有GPIO高低电平检测和ADC电阻分压检测。分压式接法,使用的单片机引脚须具有ADC功能,根据检测口测得不同的电压值来识别是哪个按键被按下。如下图。

图1:分压式接法原理

ADC电阻分压检测按键的方法适合单片机IO口资源非常紧张的场合,如一些电磁炉的按键使用的就是这种方法。高低电平式接法检测按键需要用到的单片机IO口较多,而高低电平式接法又可分为两种:独立式接法和行列式接法。

行列式接法是利用单片机的 GPIO口组成行与列,在行与列的每一个交点处连接按键。 故也称为矩阵式按键,该接线方法最大的优势是可以使用较少的GPIO口实现较多按键的检测。根据行和列的不同可以有很多种矩阵按键组合,比如2x3矩阵按键、2x4矩阵按键、3x3矩阵按键、4x4矩阵按键等等。

图2:矩阵按键原理图

☆注:行的英文是Row,列的英文是Line。

上述矩阵按键原理图中没有加任何保护电阻,市场上很多矩阵按键检测模块,都是参考上图来的。这样的设计可以实现矩阵检测,但是并不是最规范的。

图3:4x4矩阵模块

STC8A8K64S4A12开发板上设计了4x4矩阵按键检测电路,该检测电路在行检测和列检测连接单片机IO上串联了220Ω电阻,并且把行检测用IO口加了10K上拉电阻,如图。

图4:开发板4x4矩阵按键检测部分

★ 上图开发板板载矩阵按键电路的RN3和RN4都是串在单片机GPIO口引脚的220Ω电阻,作用为:

  1. 保护单片机GPIO口。若本该作为输入用的GPIO口不小心被配置成了输出(输出了高电平或低电平),按下按键外部会直接给GPIO口一个高电平或低电平。如果没有串接电阻,则若单片机GPIO口输出的电平和按键按下给的电平不一致,会损坏GPIO口。
  2. 便于检测。串接220Ω电阻可有效降低按键按下时产生的抖动峰值电压。

★ 上图开发板板载矩阵按键电路的RN2作用:保证行检测用单片机GPIO口在按键没有按下时为有效高电平。

★ 4x4矩阵按键检测电路占用的单片机的引脚如下表:

表1:4x4矩阵按键检测电路引脚分配

☆注:
1)独立GPIO表示开发板没有其他的电路使用这个GPIO,非独立GPIO说明开发板有其他电路用到了该GPIO。
2)在使用开发板4x4矩阵按键功能时,不仅J30和J31端子需使用8个短路帽短接,还要去掉J29的2个短路帽,以将P2.6和P2.7与用户指示灯断开连接。
3)开发板外部晶振电路没有焊接,也就意味着P1.6和P1.7可以使用。而如果外部晶振焊接了,则一定注意使用杜邦线连接其他没有占用的GPIO到 J31端子的L3和L4上。

2.矩阵按键检测原理介绍

矩阵按键检测的工作原理:按键设置在行、列线交点上,行、列线分别连接到按键开关的两端。行线通过上拉电阻接到VCC电源上。无按键按下时,行线处于高电平的状态,而当有按键按下时,行线电平由与此行线相连的列线电平决定。

矩阵按键检测方法有多种,这里介绍下比较常用的行列扫描法。原理解析如下:

  1. 将行线(R1Rm)配置为输出口并控制输出为高电平,将列线(L1Ln)配置为输出口并控制输出为低电平。再配置行线(R1Rm)为输入口、列线(L1Ln)仍是输出口,检测行线(R1Rm)的GPIO口电平变化。如果有按键按下,按键按下的对应行线被拉低,否则所有的行线(R1Rm)都为高电平。
  2. 将列线(L1Ln)配置为输出口并控制输出为高电平,将行线(R1Rm)配置为输出口并控制输出为低电平。再配置列线(L1Ln)为输入口、行线(R1Rm)仍是输出口,检测列线(L1Ln)的GPIO口电平变化。如果有按键按下,按键按下的对应列线被拉低,否则所有的列线(L1Ln)都为高电平。
  3. 在第一步和第二步判断有键按下后,延时10ms消除机械抖动,再次读取相应的行值或列值。
  4. 开始扫描按键位置,采用行扫描,得到行值;采用列扫描,得到列值,再分别把行值和列值保存起来。
  5. 将保存的行值和列值合并,得到按键对应的编码值,通过对编码值的操作可得到对应的按键信息,完成对矩阵按键的检测。

☆注:m代表矩阵按键检测电路的行数,n代表矩阵按键检测电路的列数。

二、软件设计

1.矩阵按键扫描实验 – 指示灯闪烁

1.1.工程需要用到的c文件

本例需要用到的c文件如下表所示,工程需要添加下表中的c文件。

表2:实验需要用到的c文件

序号 文件名 后缀 功能描述
1 led .c 用户LED有关的用户自定义函数。
2 key_4x4 .c 4x4矩阵按键有关的用户自定义函数。
3 delay .c 包含用户自定义延时函数。

1.2.头文件引用和路径设置

■ 需要引用的头文件

#include " led.h"
#include " delay.h"
#include " key_4x4.h"

■ 需要包含的头文件路径

本例需要包含的头文件路径如下表:

表3:头文件包含路径

序号 路径 描述
1 …\ Source led.h,key_4x4.h和delay.h头文件在该路径,所以要包含。
2 …\User STC8.h头文件在该路径,所以要包含。

MDK中点击魔术棒,打开工程配置窗口,按照下图所示添加头文件包含路径。

图5:添加头文件包含路径

1.3.编写代码

首先,在key_4x4.c文件中对4x4矩阵按键进行扫描,并返回键值。该KeyScan函数代码如下。

程序清单:4x4矩阵扫描函数

/***************************************************************************** * 描  述 : 4x4矩阵扫描函数 * 入  参 : 无 * 返回值 : 哪个按键按下的对应值 *****************************************************************************/
uint8 KeyScan(void)
{  uint8 X_temp,Y_temp,temp;  X_temp=0xF0;        //列值赋初值  Y_temp=0x0F;        //行值赋初值  P1M1 &= 0x3F;  P1M0 |= 0xC0;     //设置P1.6~P1.7为强推挽输出  P2M1 &= 0x3F;  P2M0 |= 0xC0;     //设置P2.6~P2.7为强推挽输出  P0M1 &= 0xF0;  P0M0 |= 0x0F;     //设置P0.0~P0.3为强推挽输出  ROW1=1;ROW2=1;ROW3=1;ROW4=1;  //行置高  COL1=0;COL2=0;COL3=0;COL4=0;  //列置低  //所用到行IO口配置为输入,进行检测  delay_ms(15);  P2M1 &= 0x3F; P2M0 &= 0x3F;     //设置P2.6~P2.7为准双向口  P0M1 &= 0xF6; P0M0 &= 0xF6;     //设置P0.0,P0.3为准双向口  delay_ms(15);  if(ROW1 == 0)         //检测行1电平是否为低电平  {  delay_ms(DELAY_TIME);  if(ROW1 == 0)  Y_temp &= 0x0E;   }  if(ROW2 == 0)         //检测行2电平是否为低电平  {  delay_ms(DELAY_TIME);  if(ROW2 == 0)  Y_temp &= 0x0D;   }  if(ROW3 == 0)         //检测行3电平是否为低电平  {  delay_ms(DELAY_TIME);  if(ROW3 == 0)  Y_temp &= 0x0B;   }  if(ROW4 == 0)         //检测行4电平是否为低电平  {  delay_ms(DELAY_TIME);  if(ROW4 == 0)  Y_temp &= 0x07;   }  P1M1 &= 0x3F;  P1M0 |= 0xC0;     //设置P1.6~P1.7为强推挽输出  P2M1 &= 0x3F;  P2M0 |= 0xC0;     //设置P2.6~P2.7为强推挽输出  P0M1 &= 0xF0;  P0M0 |= 0x0F;     //设置P0.0~P0.3为强推挽输出  ROW1=0;ROW2=0;ROW3=0;ROW4=0;  //行置低  COL1=1;COL2=1;COL3=1;COL4=1;  //列置高  //所用到列IO口配置为输入,进行检测  delay_ms(15);  P1M1 &= 0x3F; P1M0 &= 0x3F;     //设置P1.6~P1.7为准双向口  P0M1 &= 0xF9; P0M0 &= 0xF9;     //设置P0.1,P0.2为准双向口  delay_ms(15);  if(COL1 == 0)         //检测列1电平是否为低电平  {  delay_ms(DELAY_TIME);  if(COL1 == 0)  X_temp &= 0xE0;   }  if(COL2 == 0)         //检测列2电平是否为低电平  {  delay_ms(DELAY_TIME);  if(COL2 == 0)  X_temp &= 0xD0;   }  if(COL3 == 0)         //检测列3电平是否为低电平  {  delay_ms(DELAY_TIME);  if(COL3 == 0)  X_temp &= 0xB0;   }  if(COL4 == 0)         //检测列4电平是否为低电平  {  delay_ms(DELAY_TIME);  if(COL4 == 0)  X_temp &= 0x70;   }  //将行值和列值合并,得到按键对应的编码值,该值与16个按键一一对应  temp = X_temp|Y_temp;  temp = ~temp;  //将按键检测的原始编码值解析对应按键值信息  switch (temp)  {     case 0x11:return 1;   //1  case 0x21:return 2;   //2   case 0x41:return 3;   //3  case 0x81:return 4;   //4  case 0x12:return 5;   //5  case 0x22:return 6;   //6  case 0x42:return 7;   //7  case 0x82:return 8;   //8  case 0x14:return 9;   //9  case 0x24:return 10;  //0  case 0x44:return 11;  //a  case 0x84:return 12;  //b  case 0x18:return 13;  //c  case 0x28:return 14;  //d  case 0x48:return 15;  //e  case 0x88:return 16;  //f   default:  return 0;   }
}

然后,主函数中通过检测按键扫描的键值来控制用户指示灯闪烁不同的次数。具体代码如下。

代码清单:主函数

int main(void)
{  uint8 temp;  while(1)  {  temp=KeyScan();     //得到键值  if(temp)  {                            switch(temp)  {                  case 1: //按下按键S3  LED_FLI_D3(1);   //用户指示灯D3闪烁1次  break;  case 2: //按下按键S4  LED_FLI_D3(2);   //用户指示灯D3闪烁2次  break;  case 3: //按下按键S5   LED_FLI_D3(3);   //用户指示灯D3闪烁3次  break;  case 4: //按下按键S6  LED_FLI_D3(4);   //用户指示灯D3闪烁4次  break;  case 5: //按下按键S7  LED_FLI_D3(5);   //用户指示灯D3闪烁5次  break;  case 6: //按下按键S8  LED_FLI_D3(6);   //用户指示灯D3闪烁6次  break;  case 7: //按下按键S9   LED_FLI_D3(7);   //用户指示灯D3闪烁7次  break;  case 8: //按下按键S10  LED_FLI_D3(8);   //用户指示灯D3闪烁8次  break;  case 9: //按下按键S11  LED_FLI_D4(1);   //用户指示灯D4闪烁1次  break;  case 10:    //按下按键S12  LED_FLI_D4(2);   //用户指示灯D4闪烁2次  break;  case 11:    //按下按键S13  LED_FLI_D4(3);   //用户指示灯D4闪烁3次  break;  case 12:    //按下按键S14  LED_FLI_D4(4);   //用户指示灯D4闪烁4次  break;  case 13:    //按下按键S15  LED_FLI_D4(5);   //用户指示灯D4闪烁5次  break;  case 14:    //按下按键S16  LED_FLI_D4(6);   //用户指示灯D4闪烁6次  break;  case 15:    //按下按键S17      LED_FLI_D4(7);   //用户指示灯D4闪烁7次  break;  case 16:    //按下按键S18  LED_FLI_D4(8);   //用户指示灯D4闪烁8次  break;  }  }  }
}

1.4.硬件连接

本矩阵按键实验需要用到P26和P27,所以J29的短路帽需去掉。矩阵按键检测用到8个GPIO,所以J30和J31端子均需短路帽短接,实验连接图如下。

图6:4x4矩阵按键检测实验连接图

2.矩阵按键扫描实验 – 串口调试助手

2.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-18-1:4x4矩阵按键扫描实验 - 指示灯闪烁”部分。

2.2.编写代码

首先,在key_4x4.c文件中对4x4矩阵按键进行扫描,并返回键值。该KeyScan函数代码请参考“实验2-18-1:4x4矩阵按键扫描实验 - 指示灯闪烁”部分。

然后,在主函数中对串口1进行初始化,并通过串口1发送按键扫描的键值。具体代码如下:

代码清单:主函数

int main(void)
{  uint16 temp;  P3M1 &= 0xFE;   P3M0 &= 0xFE;                     //设置P3.0为准双向口  P3M1 &= 0xFD;   P3M0 |= 0x02;                     //设置P3.1为推挽输出  Uart1_Init();                                 //串口1初始化    EA = 1;                                       //使能总中断  delay_ms(10);                                 //初始化后延时  while(1)  {  temp=(uint16)KeyScan();                               //得到键值  if(temp)  {             printf("\r\n 4x4矩阵按键键值: %d\r\n",temp);    //串口打印上传的采集的原始值  temp = 0;                                        //清零        }  }
}

2.3.硬件连接

本矩阵按键实验需要用到P26和P27,所以J29的短路帽需去掉。矩阵按键检测用到8个GPIO,所以J30和J31端子均需短路帽短接。另外,需使用USB线连接开发板USB口至电脑,以串口调试助手接收数据。

图7:4x4矩阵按键检测实验连接图

总结

以上就是今天要讲的内容,希望对你有帮助!

【STC8A8K64S4A12开发板】—4x4矩阵按键检测相关推荐

  1. 【STC8A8K64S4A12开发板】—小白做GPIO按键实验

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.硬件电路设计 1.开发板用户按键硬件电路 2.按键检测接法 3.按键检测电路考虑因素 二.软件设计 1.寄存器解析 1.1. ...

  2. STC8A8K64S4A12开发板介绍

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.STC8A8K64S4A12系列单片机介绍 二.STC8A8K64S4A12开发板概述 三.STC8A8K64S4A12开发 ...

  3. 【STC8A8K64S4A12开发板】—RS485总线通信

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.硬件设计 1.开发板串口硬件电路 2.RS485电气性能 3.RS485通信协议 4.RS485电路设计 二.软件设计 1. ...

  4. 【Proteus仿真】4X4矩阵按键显示0-F

    [Proteus仿真]4X4矩阵按键显示0-F 本实验基于Proteus VSM Studio仿真 VSM Studio程序代码 /* Main.c file generated by New Pro ...

  5. 基于STM32F103+AS608指纹模块+4X4矩阵按键+SIM900A发短信——智能门禁卡系统

    STM32F103-智能门禁卡系统 1.基本介绍 1.用到硬件 2.功能介绍 2.代码 指纹模块 SIM900A模块 矩阵按键 主程序 项目展示 验证密码开锁演示 指纹验证开锁演示 添加指纹演示 删除 ...

  6. 开发板visionpro视觉通用检测框架源码,c#+vp, vp9.0,一个测量的程序可作为通用的检测框架使用

    开发板visionpro视觉通用检测框架源码,c#+vp, vp9.0,一个测量的程序可作为通用的检测框架使用.功能模块完整,像什么视觉处理,数据处理,文件操作,IO卡应用等都有,学习与项目参考比较好 ...

  7. 【STC8A8K64S4A12开发板】—片外存储器FLASH讲解

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.硬件设计 1.FRAM铁电存储器介绍 2.W25Q128JV存储芯片介绍 2.1.芯片引脚定义 2.2.芯片介绍及使用注意事 ...

  8. linux开发板led怎么亮,TQ2440开发板上实现按键点亮LED(转载)

    //声明:该文章是在网上搜到的,对作者表示感谢. 文章记录了作者在TQ2440开发板上实现按键点亮LED驱动开发的详细过程,还记录了一些容易出现的错误,以及怎么解决这些错误. 一.驱动开发流程 二.驱 ...

  9. STM32F411核心板固件库开发(三) 按键检测

    对于自己手上的这款核心板,考虑到还有一个外部外设没有使用,为了比较充分地用好板上的资源,在这里使用一个按键检测. (一)按键外设 1.核心板 2.核心板原理图 按键上端和PA0引脚相连,按键下端接地. ...

最新文章

  1. H5画布不显示图片的问题解决
  2. BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览
  3. 龙格-库塔(Runge-Kutta)方法数学原理及实现
  4. scala与python混合调用实验
  5. sprytabbedpanels.js库之在页面中插入Tabbed Panels
  6. 【Java基础】递归输出目录下所有文件路径
  7. python 写入json数据到数据库
  8. springMVC下载FTP上的文件
  9. 设计模式速查手册-创建型
  10. Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析
  11. 怎么在安卓布局里设置滚动字体_手机里堪称神器的 App
  12. Swift Basic 3
  13. 【数字设计】诺瓦科技_笔试面试题目分享
  14. 为什么我用腾讯会议录屏没声音?教你一招搞定!
  15. NAS 层架构_01
  16. va_buffersharing example
  17. Jackson官网与官方文档
  18. AJAX 后端处理程序
  19. 股权和更高的薪资应该选那个呢?
  20. [软件人生]抢钱的电影与现在的软件开发

热门文章

  1. 一句话木马绕过检测的常见思路
  2. 分式的二阶导数怎么求_二阶导数怎么求?
  3. UR机械臂学习(5-2):使用Universal_Robots_ROS_Driver驱动真实机械臂
  4. 西电软工计算机通信与网络期末复习要点总结
  5. Ant Design Tabs切换控制
  6. php的多种sort的区别
  7. [UE5蓝图基础二]8.[UI]血蓝条的制作
  8. Kibana:使用 Maps 来显示分布式的团队
  9. 平面3连杆机器人正逆解
  10. Auto CAD 2013的故障解决方法