您的位置:首页 > 其它

凌乱的DSP笔记(5)-按键

2020-04-07 18:25 134 查看

1. 按键介绍

按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时,开关断开。

相距较长的脚始终导通,相距较短的脚初始不导通,在按键按下时导通。

按键抖动:

硬件消抖是通过采用外加零件来消除干扰抖动杂脉冲波,通常采用电容滤波、单稳延时电路等等。
软件消抖是通过采用软件程序的方法来达到消除干扰抖动杂脉冲波,最常见的是软件采用延时(5~10ms)再次检测的方法来消抖。

2. 矩阵键盘介绍

矩阵键盘检测方法有多种,最常用的是行列扫描和线翻转法。

行列扫描法检测时, 先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平, 若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的, 用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平, 这样即可检测完所有的按键,当有键被按下时便可判断出按下的键是哪一个键。 当然我们也可以将行线置低电平, 扫描列是否有低电平。 从而达到整个键盘的检测。

线翻转法,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有,就记录列线值;然后再翻转, 使所有列线都为低电平, 检测所有行线的值, 由于有按键按下,行线的值也会有变化, 记录行线的值。 从而就可以检测到全部按键。

3. 硬件设计

4. 软件设计

4.1 key

/*
* key.c
*
*  Created on: 2020-4-7
*      Author: Administrator
*/

#include "key.h"

void KEY_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟

//KEY端口配置
//行为输入方向
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=0;
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;

GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
GpioCtrlRegs.GPADIR.bit.GPIO13=0;
GpioCtrlRegs.GPAPUD.bit.GPIO13=0;

GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
GpioCtrlRegs.GPADIR.bit.GPIO14=0;
GpioCtrlRegs.GPAPUD.bit.GPIO14=0;

//列为输出方向
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
GpioCtrlRegs.GPBDIR.bit.GPIO48=1;
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;

GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;
GpioCtrlRegs.GPBDIR.bit.GPIO49=1;
GpioCtrlRegs.GPBPUD.bit.GPIO49=0;

GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;
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;
static char keyl2=1;
static char keyl3=1;

//第1列扫描
KEY_L1_SetL;
KEY_L2_SetH;
KEY_L3_SetH;
if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
{
DELAY_US(10000);//延时10ms,软件消抖
keyl1=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)
keyl1=1;//mode为1,可以连按,否则只能单按

//第2列扫描
KEY_L2_SetL;
KEY_L1_SetH;
KEY_L3_SetH;
if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==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;

//第3列扫描
KEY_L3_SetL;
KEY_L1_SetH;
KEY_L2_SetH;
if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==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;
}

按键采用行列扫描法,根据返回值确定被按下的按键。

/*
* key.h
*
*  Created on: 2020-4-7
*      Author: Administrator
*/

#ifndef KEY_H_
#define KEY_H_

#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

#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
ad8
(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_ */

4.2 main.c

通过1~6号按键控制LED。

/*
* main.c
*
*  Created on: 2020年4月7日
*      Author: lenovo
*/

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "leds.h"
#include "key.h"

/*******************************************************************************
* 函 数 名         : main
* 函数功能           : 主函数
* 输    入         :
ad8
无
* 输    出         : 无
*******************************************************************************/
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;
}
DELAY_US(100);
}
}

5. 效果

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: