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

文章目录

  • 前言
  • 一、硬件电路设计
    • 1.开发板用户按键硬件电路
    • 2.按键检测接法
    • 3.按键检测电路考虑因素
  • 二、软件设计
    • 1.寄存器解析
      • 1.1.端口数据寄存器
      • 1.2.端口上拉电阻控制寄存器
    • 2.GPIO输入按键检测实验(单个c文件)
      • 2.1.头文件引用和路径设置
      • 2.2.编写代码
    • 3.流水灯实验(多个c文件)
      • 3.1.工程需要用到的c文件
      • 3.2.头文件引用和路径设置
      • 3.3.编写代码
  • 总结

前言

做完了GPIO点灯实验,成就感满满,不知道小白的我是不是入门了,哈哈!开始做下一个GPIO按键检测的实验。


一、硬件电路设计

1.开发板用户按键硬件电路

轻触按键又称轻触开关(下文简称按键),是电路中常用的一种开关元器件,也是一种常用的人机接口。广泛用于家电、数码产品、便携仪产品、电脑产品等电子设备中。
STC8A8K64S4A12开发板上设计了4个用户按键KEY1、KEY2、KEY3、KEY4,当使用KEY1和KEY2时,可短接J26端子的P37||KEY1、P36||KEY2。程序中通过读取这些按键对应的GPIO的状态(高电平或低电平)可判断该按键是否按下,这种电路的形式称为高低电平接法,这种检测按键的方法称为按键高低电平检测。

图1:开发板按键检测电路及实物图

☆1个用户按键占用的单片机的引脚如下表:

表1:用户按键引脚分配

KEY 引脚 功能描述 说明 备注
KEY1 P3.7 用户按键 非独立GPIO 黄色轻触按键
KEY2 P3.6 用户按键 非独立GPIO 黄色轻触按键
KEY3 P0.7 用户按键 独立GPIO 黄色轻触按键
KEY4 P0.5 用户按键 独立GPIO 黄色轻触按键

☆注:独立GPIO表示开发板没有其他的电路使用这个GPIO,非独立GPIO说明开发板有其他电路用到了该GPIO。STC8A8K64S4A12开发板上W5500模块接口用到了P3.6和P3.7口,故在将W5500模块接插到开发板时,不可再将P3.6和P3.7用于按键检测。

轻触按键,顾名思义我们只需要施加很小的力量即可改变开关连接的状态。轻触按键在所需外力作用下(按下按键)触点导通,无外力作用时(释放按键)触点断开,如下图所示:

图2:轻触按键原理

2.按键检测接法

高低电平式接法是最常见的按键检测的接法,顾名思义,该接法就是需要单片机引脚具有高低电平的检测能力,也就是常见的GPIO引脚即可。高低电平式接法又可分为两种:独立式接法和行列式接法。
行列式接法是利用单片机的 GPIO口组成行与列,在行与列的每一个交点处连接按键。 故也称为矩阵式按键,该接线方法最大的优势是可以使用较少的GPIO口实现较多按键的检测,这个在矩阵按键扫描实验中会详细介绍。
独立式接法的含义就是使用单片机的一个GPIO引脚检测一个按键的状态,有多少按键需检测就需要多少个GPIO引脚,对每个按键的检测相互独立。
独立式按键接法一般会用低电平有效的方式,即按键按下是GPIO输入为低电平,如下图所示。

图3:独立式接法

上图中的电阻R的作用是将GPIO输入端口不确定的信号通过该电阻钳位在高电平状态。我们知道数字电路有三种状态:高电平、低电平和高阻状态,有些应用场合并不希望出现高阻状态,这时加上拉电阻即可让GPIO输入端口保持确定的状态。
按键释放时,因为上拉电阻R的关系,GPIO输入检测是高电平,按键闭合时,GPIO短接到GND,输入检测是低电平。这样,单片机根据GPIO的输入状态即可确定按键是否按下。

■ 按键检测知识扩展:ADC通过电阻分压检测多个按键
按键检测除了高低电平检测的方法之外,还有一种方法是使用ADC通过电阻分压检测多个按键,这种按键检测的电路形式称为分压式接法。
分压式接法,使用的单片机引脚必须具有ADC功能,根据检测口测得的不同的电压值来识别是哪个按键被按下。如下图所示,是分压式接法的原理示意图。这种方法最大的好处是节省IO资源,它只需一个具有ADC功能的IO即可实现多个按键的检测,它适用于IO资源紧张的场合,如一些电磁炉的按键使用的就是这种方法。
相对于高低电平检测,这种方法在编程上要复杂一些,需要事先计算好分压的电压值,存储于“表”中,程序运行时,采样到电压值后查表即可获知是哪个按键按下。

图4:分压式接法原理

3.按键检测电路考虑因素

按键检测电路设计的时候,需要我们考虑两个方面:按键释放时GPIO口状态的确定和按键消抖。
1)按键释放时GPIO口状态的确定
按键检测电路中,当按键释放后要能保证GPIO口电平是确定的,即按键释放时GPIO口固定为高电平或低电平。开发板RN1排阻就是满足用户按键释放时,在单片机GPIO口上保持高电平。
2)按键消抖
对于按键硬件上的消抖,一般常用的方式是在按键上并接一个容值约0.1uF左右电容,利用电容两端的电压不能突变的特性,消除抖动时产生的毛刺电压。虽然电容可以起到消除抖动的作用,但是在考虑按键灵敏度的情况下,电容时无法完全消除抖动的,消除抖动还需要软件的配合。
开发板上按键电路没有增加硬件消抖,开发板使用的是软件消抖,这对于一般的按键检测已经完全足够。

3)GPIO口保护
开发板按键检测电路中还串有排阻RN12,该排阻阻值100欧姆,串在单片机GPIO口和按键引脚中,起到保护GPIO口的目的。
分析:如果GPIO口不小心误配置为输出模式,并且输出高电平,则分析下电路可知,此时如果没有排阻RN12,若按下用户按键,则单片机GPIO口(控制输出高电平)直接和GND相连,会损坏GPIO口。

二、软件设计

1.寄存器解析

1.1.端口数据寄存器

下图是对端口数据寄存器P0、P1、P2、P3、P4、P5、P6、P7的描述,端口数据寄存器各位代表对应端口的GPIO口,在完成对配置寄存器设置后,可直接读取端口引脚电平。

图5:端口数据寄存器

1.2.端口上拉电阻控制寄存器

下图是对端口上拉电阻控制寄存器P0PU、P1PU、P2PU、P3PU、P4PU、P5PU、P6PU、P7PU的描述,这些特殊功能寄存器不支持位寻址。端口上拉电阻控制寄存器各位代表对应端口的GPIO口是否使能其上拉电阻,在完成对该寄存器设置后,相应GPIO端口便在单片机内部有了上拉电阻。该功能使得GPIO口在硬件电路设计时具有了更多的灵活性。但务必知晓端口上拉电阻控制寄存器为扩展SFR,逻辑地址位于XDATA区域,访问前需先将P_SW2寄存器的最高位(EAXFR)置1。

图6:端口数据寄存器

☆注:如果GPIO外部加了上拉电阻,而软件又使能内部上拉电阻有效,那实际上拉电阻阻值是单片机GPIO口片内和片外上拉电阻并连后的值。

2.GPIO输入按键检测实验(单个c文件)

☆注:本节的实验源码是在“实验2-1-3:流水灯(单个c文件)”的基础上修改。本节对应的实验源码是:“实验2-2-1: GPIO输入按键检测(单个c文件)”。

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

■ 需要宏定义部分及引用的头文件
因为在“main.c”文件中使用了STC8的头文件“STC8.h”,所以需要引用下面的头文件。在头文件“STC8.h”中需要确定主时钟取值,所以宏定义主时钟值。

#define MAIN_Fosc       11059200L   //定义主时钟
#include    "STC8.H"

在程序设计中会用到定义变量的类型,为了定义变量方便,将较为复杂的“unsigned int”和“unsigned char ”进行了宏定义。

#define  uint16   unsigned int
#define  uint8    unsigned char   

这样,再定义变量时可直接使用“uint16”和“uint8”来取代“unsigned int”和“unsigned char ”即可。

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

表2:头文件包含路径

序号 路径 描述
1 …\User STC8.H头文件在该路径,所以要包含

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

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

2.2.编写代码

首先根据开发板按键及指示灯GPIO分配,定义寄存器位变量,代码如下。

/**********************
引脚别名定义
***********************/
sbit KEY=P0^7;      //用户按键KEY3用IO口P07
sbit LED_D3=P7^2;   //用户指示灯D3用IO口P72      

然后,在主函数中先对P7.2和P0.7口进行模式配置,后主循环中检测按键状态,确认按键按下控制蓝色指示灯D3亮。

int main(void)
{  P7M1 &= 0xFB; P7M0 &= 0xFB;     //设置P7.2为准双向口  P0M1 &= 0x7F;   P0M0 &= 0x7F;     //设置P0.7为准双向口
//    P0M1 |= 0x80; P0M0 &= 0x7F;     //设置P0.7为高阻输入  while(1)  {  if(KEY == 0)  //检测用户按键KEY3对应引脚P0.7是否是低电平 (按键按下,引脚为低电平) {  delay_ms(10);      //软件延时10ms,如果延时后按键KEY3的电平依然没有变化,说明按键确实被有效操作,简称按键消抖  if(KEY== 0)          //检测用户按键KEY3对应引脚P0.7是否依然是低电平  {  LED_D3=0;           //点亮用户指示灯D3  while(KEY == 0)         //等待按键KEY3释放,即如果P0.7一直为低电平,会一直执行空命令  {  ;               //条件KEY == 0成立,会执行这个空命令  }  LED_D3=1;                   //按键KEY3释放,熄灭用户指示灯D3  }  }  }
}       

3.流水灯实验(多个c文件)

☆注:本节的实验源码是在“实验2-2-1: GPIO输入按键检测(单个c文件)”的基础上修改。本节对应的实验源码是:“实验2-2-2: GPIO输入按键检测(多个c文件)”。

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

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

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

序号 文件名 后缀 功能描述
1 led .c 包含与用户led控制有关的用户自定义函数
2 key .c 包含与用户按键检测有关的用户自定义函数
3 delay .c 包含用户自定义延时函数

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

■ 需要引用的头文件
因为在“main.c”文件中使用了控制led的函数和延时函数(延时函数没有在main.c中定义),所以需要引用下面的头文件。

#include    "led.h"
#include    "delay.h"
#include    "key.h"

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

表4:头文件包含路径

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

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

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

3.3.编写代码

首先在key.h中,宏定义4个用户按键,引用延时函数的头文件,声明按键检测函数供外部调用。代码如下。

#include "delay.h"  #define KEY_ON  0
#define KEY_OFF 1  #define KEYS_OFF    0             //没有按键按下
#define KEY1_ON     1             //按键KEY1按下
#define KEY2_ON     2             //按键KEY2按下
#define KEY3_ON     3             //按键KEY3按下
#define KEY4_ON     4             //按键KEY4按下  /********************************************
引脚别名定义
*********************************************/
sbit KEY_S1=P3^7;         //用户按键KEY1用IO口P37
sbit KEY_S2=P3^6;         //用户按键KEY2用IO口P36
sbit KEY_S3=P0^7;         //用户按键KEY3用IO口P07
sbit KEY_S4=P0^5;         //用户按键KEY4用IO口P05  extern uint8 Keys_Scan(uint8 mode);

然后,在key.c文件中编写一个按键检测函数Keys_Scan,代码如下。

程序清单:延时函数

/**************************************************************************
功能描述:检测开发板上的4个用户按键(KEY1、KEY2、KEY3、KEY4)
入口参数:uint8 mode 是否支持连按
返回值:按键编号 *************************************************************************/
uint8 Keys_Scan(uint8 mode)
{  static uint8 Key_up=1;   //标志变量  if(mode==1)  //支持连按  {  Key_up=1;   //变量 Key_up会被重新赋值为1  }  //检测按键KEY1、按键KEY2、按键KEY3、按键KEY4用IO口电平是否为低电平  if(Key_up&&((KEY_S1 == KEY_ON ) || (KEY_S2 == KEY_ON ) || (KEY_S3 == KEY_ON ) || (KEY_S4 == KEY_ON )))  {  delay_ms(10);     //软件延时10ms,去抖  Key_up=0;         //变量 Key_up会被赋值为0  if(KEY_S1 == KEY_ON )    {    return KEY1_ON;  }  else if(KEY_S2 == KEY_ON )  {  return KEY2_ON;  }  else if(KEY_S3 == KEY_ON )  {  return KEY3_ON;  }  else if(KEY_S4 == KEY_ON )  {  return KEY4_ON;  }  }  else if((KEY_S1 == KEY_OFF )&&(KEY_S2 == KEY_OFF ) &&(KEY_S3 == KEY_OFF )&&(KEY_S4 == KEY_OFF )  )  {  Key_up=1;   //变量 Key_up会被赋值为1  }   return KEYS_OFF;
}

因为按键检测函数Keys_Scan中使用了控制led的函数、有关KEY的宏定义和延时函数,所以需要在key.c文件中引用下面的头文件。

#include "led.h"
#include "key.h"

最后,在主函数中先对4个用户指示灯和4个用户按键用到的GPIO口进行模式配置,后主循环中调用按键检测函数,可观察各用户按键按下后用户指示灯变化情况。

代码清单:主函数

int main(void)
{  uint8 temp;  P2M1 &= 0x3F;   P2M0 &= 0x3F;     //设置P2.6~P2.7为准双向口  P7M1 &= 0xF9;   P7M0 &= 0xF9;     //设置P7.1~P7.2为准双向口  P0M1 &= 0x5F;   P0M0 &= 0x5F;     //设置P0.5,P0.7为准双向口
//  P0M1 |= 0xA0;   P0M0 &= 0x5F;     //设置P0.5,P0.7为高阻输入  P3M1 &= 0x3F;   P3M0 &= 0x3F;     //设置P3.6~P3.7为准双向口
//  P3M1 |= 0xC0;   P3M0 &= 0x3F;   //设置P3.6~P3.7为高阻输入  //  P_SW2 |= 0x80;                  //将EAXFR位置1,以访问在XDATA区域的扩展SFR
//  P0PU |= 0xA0;                 //设置P0.5,P0.7口有上拉电阻
//  P3PU |= 0xC0;                 //设置P3.6~P3.7口有上拉电阻
//  P_SW2 &= 0x7F;                  //将EAXFR位置0,恢复访问XRAM          while(1)  {  temp=Keys_Scan(0);                 //获取开发板用户按键检测值,不支持连按  if(temp == KEY1_ON)                //如果按键KEY1被操作  {  led_toggle(LED_1);               //控制用户指示灯D1翻转  }  else if(temp == KEY2_ON)           //如果按键KEY2被操作  {  led_toggle(LED_2);               //控制用户指示灯D2翻转  }   else if(temp == KEY3_ON)           //如果按键KEY3被操作  {  led_toggle(LED_3);               //控制用户指示灯D3翻转  }   else if(temp == KEY4_ON)           //如果按键KEY4被操作  {  led_toggle(LED_4);               //控制用户指示灯D4翻转  }       }
}

总结

以上就是今天要讲的内容,其中有些内容借鉴了艾克姆科技的资料!

【STC8A8K64S4A12开发板】—小白做GPIO按键实验相关推荐

  1. 【STC8A8K64S4A12开发板】—4x4矩阵按键检测

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.硬件电路设计 1.矩阵按键检测介绍 2.矩阵按键检测原理介绍 二.软件设计 1.矩阵按键扫描实验 – 指示灯闪烁 1.1.工 ...

  2. STC8A8K64S4A12开发板介绍

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

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

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

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

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

  5. 【沁恒WCH CH32V307V-R1开发板两路ADC读取实验】

    [沁恒WCH CH32V307V-R1开发板两路ADC读取实验] 1. 前言 2. 软件配置 2.1 安装MounRiver Studio 3. ADC项目测试 3.1 打开ADC工程 3.2 编译项 ...

  6. 【STC8A8K64S4A12开发板】—开始做 定时器/计数器 实验啦

    版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.硬件设计 1.TIMER概念介绍 2.STC8A8K64S4A12系列单片机定时器/计数器介绍 3.定时器/计数器工作模式 ...

  7. AB32开发板测评:GPIO控制RGB彩灯

    文章目录 [AB32VG1]开发板测评:RGB彩灯 一.初始准备 1.硬件平台 2.软件平台 二.操作步骤 1.RTT环境生成 2.RTT程序编写 3.程序下载,观察现象 三.心得 [AB32VG1] ...

  8. 【MM32F5270开发板试用】GPIO输入+EXTI外部中断例程demo试用

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:Zeee 前言: 首先,感谢灵动微电子与极术社区给予宝贵的试用机会.借助本次对Plus-F ...

  9. 宙合Air700E开发板小白上手教程-LuatOS项目开发入门hello_world

    本文章适合刚收到开发板不知如何上手的小白,我们将从如何下载相关资料,需要哪些软件,再到连接开发板,如何新建一个helloworld项目,烧录并查看日志. 下面我们开始一起学习如何使用LuatOS开发出 ...

最新文章

  1. 科技部通知:先看病,再写论文!!!
  2. Linux中新建用户用不了sudo命令问题:rootr is not in the sudoers file.This incident will be reported解决
  3. 配置静态路由使用出站接口和下一跳IP的差别
  4. oracle乘法运算,oracle实现相乘话语
  5. 虚拟机下Ubuntu没有GUI图形界面,解决方法
  6. 应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序
  7. python读取中文txt文本-Python3 解决读取中文文件txt编码的问题
  8. Bag-of-words model
  9. Scala之部分应用函数
  10. Angular karma test.ts里一些标准api用console.log打印出的输出
  11. BUAA 更大公约数
  12. python3多进程写时拷贝_python多进程实现复制文件
  13. tomcat 无法关闭 :8005端口未启动
  14. 制作nginx的spec分享
  15. 使用PowerDesigner
  16. 记一次生产httpclient导致的tomcat假死事件
  17. redis通过key模糊搜索_jedis模糊查询key
  18. Solr学习 DIH增量、定时导入并检索数据
  19. fedora8下删除antivir
  20. TensorFlow学习笔记——深层神经网络

热门文章

  1. Windows 98 操作系统 考试大纲
  2. linux清空buff,Linux中buff
  3. KVM虚拟化- KVM虚拟化介绍
  4. 03、hadoop集群安装
  5. 配置OSPF引入缺省路由
  6. 查询江苏丹阳高考成绩2021,2021年丹阳市高考状元名单资料,今年丹阳市高考状元多少分...
  7. Unity技术手册 - 初识粒子系统及预览效果【Particle Effect】面板介绍
  8. h5案例分享--雀巢咖啡--传奇创世
  9. python歌手评分详细
  10. python运维需要哪些技术_学习运维技术要掌握哪些知识点?