28335学习笔记4

您所在的位置:网站首页 87键键盘三个灯的按键开关分别是什么 28335学习笔记4

28335学习笔记4

2024-05-30 01:47| 来源: 网络整理| 查看: 265

1.按键消抖

通常的按键所用开关为机械弹性开关,当机械触点断开、 闭合时, 电压信号如下图所示 在这里插入图片描述 由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开。在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的, 一般为 5ms 到 10ms。 按键稳定闭合时间的长短则由操作人员的按键动作决定的, 一般为零点几秒至数秒。 按键抖动会引起按键被误读多次。 为了确保 CPU 对按键的一次闭合仅作一次处理, 必须进行消抖。 按键消抖有两种方式, 一种是硬件消抖(在按键管脚上串联RC电路,通过延时相当于把抖动的波滤除掉), 另一种是软件消抖。 为了使电路更加简单, 通常采用软件消抖。一个简单的按键消抖就是先读取按键的状态, 如果得到按键按下之后, 延时 10ms, 再次读取按键的状态, 如果按键还是按下状态, 那么说明按键已经按下。其中延时10ms 就是软件消抖处理。

2.矩阵键盘工作原理及检测

3X3 矩阵键盘将 9 个按键排成 3行 3 列, 第一行将每个按键的一端连接在一起构成行线, 第一列将每个按键的另一端连接在一起构成列线, 这样便一共有 3 行 3 列共 6 根线, 我们将这 6 根线连接到6 个 I/O 口上, 通过程序扫描键盘就可检测 9 个键。 用这种方法我们也可实现 4 行 4 列 16 个键、 5 行 5 列 25 个键、 6 行 6 列36 个键甚至更多。 矩阵键盘两端都与 I/O 口相连, 因此在检测时需编程通过一侧的 I/O 口送出低电平。 检测方法有多种,最常用的是行列扫描和线翻转法。 行列扫描法检测时, 先送一列为低电平, 其余几列全为高电平(此时我们确定了列数), 然后立即轮流检测一次各行是否有低电平, 若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的, 用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键, 当有键被按下时便可判断出按下的键是哪一个键。当然我们也可以将行线置低电平, 扫描列是否有低电平。 从而达到整个键盘的检测。 线翻转法, 就是使所有行线为低电平时, 检测所有列线是否有低电平, 如果有, 就记录列线值; 然后再翻转, 使所有列线都为低电平, 检测所有行线的值,由于有按键按下, 行线的值也会有变化, 记录行线的值。 从而就可以检测到全部按键。

3.程序

按键驱动程序源文件

#include "key.h" //按键初始化函数 void KEY_Init(void) { EALLOW; SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK=1;//开启GPIO时钟 //KEY端口配置 GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;//设置为普通IO口 GpioCtrlRegs.GPADIR.bit.GPIO12=0;//设置为输入 GpioCtrlRegs.GPAPUD.bit.GPIO12=0;//默认上拉 GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;//设置为普通IO口 GpioCtrlRegs.GPADIR.bit.GPIO13=0;//设置为输入 GpioCtrlRegs.GPAPUD.bit.GPIO13=0;//默认上拉 GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;//设置为普通IO口 GpioCtrlRegs.GPADIR.bit.GPIO14=0;//设置为输入 GpioCtrlRegs.GPAPUD.bit.GPIO14=0;//默认上拉 GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;//设置为普通IO口 GpioCtrlRegs.GPBDIR.bit.GPIO48=1;//设置为输出 GpioCtrlRegs.GPBPUD.bit.GPIO48=0;//默认上拉 GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;//设置为普通IO口 GpioCtrlRegs.GPBDIR.bit.GPIO49=1;//设置为输出 GpioCtrlRegs.GPBPUD.bit.GPIO49=0;//默认上拉 GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;//设置为普通IO口 GpioCtrlRegs.GPBDIR.bit.GPIO50=1;//设置为输出 GpioCtrlRegs.GPBPUD.bit.GPIO50=0;//默认上拉 EDIS; GpioDataRegs.GPBSET.bit.GPIO48=1;//设置输出高电平 GpioDataRegs.GPBSET.bit.GPIO49=1;//设置输出高电平 GpioDataRegs.GPBSET.bit.GPIO50=1;//设置输出高电平 //即使按键按下也不影响判断 } //按键检测函数 char KEY_Scan(char mode) { static char keyl1=1;//三个静态变量(如不是静态变量,在执行过程中,每次进入该函数变量值为1. static char keyl2=1; static char keyl3=1; //第一列扫描 KEY_L1_SetL;//第一列为低电平,其他为高电平 KEY_L2_SetH;// KEY_L3_SetH;// if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为0即按键按下 { DELAY_US(10000);//软件消抖 keyl1=0;//如该列有按键按下,则变为0。方便下一次再判断(按键松开后,可能还有抖动,有了这个松开按键后不会再执行。其实是松开按键的消抖 if(KEY_H1==0) { return KEY1_PRESS; } else if(KEY_H2==0) { return KEY4_PRESS; } else if(KEY_H3==0) { return KEY7_PRESS; } } else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1) { keyl1=1;//松开后按键要为1,为下次判断做准备 } if(mode)//mode为0相当于按键按一下执行一下不能连续按。但当mode为1(连续扫描)时则可以连续按,像音量加减那样 keyl1=1;//始终 //第2列扫描 KEY_L1_SetH;//第2列为低电平,其他为高电平 KEY_L2_SetL;// KEY_L3_SetH;// if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为0即按键按下 { DELAY_US(10000);//软件消抖 keyl2=0; if(KEY_H1==0) { return KEY2_PRESS; } else if(KEY_H2==0) { return KEY5_PRESS; } else if(KEY_H3==0) { return KEY8_PRESS; } } else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1) { keyl2=1; } if(mode) keyl2=1; //第三列扫描 KEY_L1_SetH;//第3列为低电平,其他为高电平 KEY_L2_SetH;// KEY_L3_SetL;// if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为0即按键按下 { DELAY_US(10000);//软件消抖 keyl3=0; if(KEY_H1==0) { return KEY3_PRESS; } else if(KEY_H2==0) { return KEY6_PRESS; } else if(KEY_H3==0) { return KEY9_PRESS; } } else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1) { keyl3=1; } if(mode) keyl3=1; return KEY_UNPRESS; }

按键驱动程序头文件

#ifndef KEY_H_ #define KEY_H_ #include "DSP2833x_Device.h"//包含所有的头文件,常用的宏定义 、F2833x 内核、 外设驱动的源文件对应的头文件 #include "DSP2833x_Examples.h"// 包含F2833x 通用文件的头文件。 比如中断、全局变量及函数声明、 IQmath 库等 #define KEY_L1_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO48=1) #define KEY_L2_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO49=1) #define KEY_L3_SetL (GpioDataRegs.GPBCLEAR.bit.GPIO50=1) #define KEY_L1_SetH (GpioDataRegs.GPBSET.bit.GPIO48=1) #define KEY_L2_SetH (GpioDataRegs.GPBSET.bit.GPIO49=1) #define KEY_L3_SetH (GpioDataRegs.GPBSET.bit.GPIO50=1) #define KEY_H1 (GpioDataRegs.GPADAT.bit.GPIO12) #define KEY_H2 (GpioDataRegs.GPADAT.bit.GPIO13) #define KEY_H3 (GpioDataRegs.GPADAT.bit.GPIO14) #define KEY1_PRESS 1 #define KEY2_PRESS 2 #define KEY3_PRESS 3 #define KEY4_PRESS 4 #define KEY5_PRESS 5 #define KEY6_PRESS 6 #define KEY7_PRESS 7 #define KEY8_PRESS 8 #define KEY9_PRESS 9 #define KEY_UNPRESS 0 void KEY_Init(void); char KEY_Scan(char mode); #endif /* KEY_H_ */

主程序

#include "DSP2833x_Device.h"//包含所有的头文件,常用的宏定义 、F2833x 内核、 外设驱动的源文件对应的头文件 #include "DSP2833x_Examples.h"// 包含F2833x 通用文件的头文件。 比如中断、全局变量及函数声明、 IQmath 库等 #include "leds.h" #include "key.h" void main() { int i=0; char key=0; InitSysCtrl();//系统时钟初始化 LED_Init(); KEY_Init(); while(1)//不断的检测按键扫描 { key=KEY_Scan(0); switch(key) { case KEY1_PRESS: LED2_TOGGLE;break; case KEY2_PRESS: LED3_TOGGLE;break; case KEY3_PRESS: LED4_TOGGLE;break; case KEY4_PRESS: LED5_TOGGLE;break; case KEY5_PRESS: LED6_TOGGLE;break; case KEY6_PRESS: LED7_TOGGLE;break; } i++; if(i%2000==0) { LED1_TOGGLE;//设置GPIO输出翻转信号 i=0; } DELAY_US(100); } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3