按键、矩阵按键操作及protues仿真
- [1 按键介绍](#1 按键介绍)
-
- [1.1 按键种类](#1.1 按键种类)
- [1.2 按键应用场景](#1.2 按键应用场景)
- [2 按键电路](#2 按键电路)
- [3 按键软件设计](#3 按键软件设计)
-
- [3.1 按键实现](#3.1 按键实现)
- [3.2 按键滤波方法](#3.2 按键滤波方法)
- [3.3 矩阵按键软件设计](#3.3 矩阵按键软件设计)
- [3.4 按键Protues 仿真](#3.4 按键Protues 仿真)
- [4 按键操作总结](#4 按键操作总结)
提示
1 按键介绍
1.1 按键种类
按键是一种用于控制电子设备或电路连接和断开的按钮或开关。它们通常具有两个状态:打开和关闭。下面是一些常见的开关按键介绍:
- 按下开关(Push Button Switch):这是一种简单的按键,按下按钮可以连接电路,释放按钮则断开电路。它们通常用于控制设备的开关或触发特定功能。
- 切换开关(Toggle Switch):切换开关是一种具有固定位置的开关,可以手动切换其状态。它们通常有两个或更多个固定位置(例如打开和关闭),通过切换开关的位置来连接或断开电路。
- 滑动开关(Slide Switch):滑动开关是一种通过滑动按钮来改变状态的开关。它们通常具有两个位置,通过将滑块从一个位置滑动到另一个位置来连接或断开电路。
- 拨动开关(Toggle Switch):拨动开关是一种通过拨动按钮来改变状态的开关。它们通常具有一个中间位置和两个极端位置,通过将按钮从一个位置拨到另一个位置来连接或断开电路。
- 按钮开关(Button Switch):按钮开关类似于按下开关,但通常具有弹簧机制,释放按钮后会自动返回到初始位置。它们常用于需要按住按钮来保持连接状态的应用,而松开按钮则断开电路。
- 电子开关(Electronic Switch):电子开关是一种使用电子元件(如晶体管或继电器)来控制电路连接和断开的开关。它们可以通过电信号或其他触发方式来控制开关状态
1.2 按键应用场景
一些机械按键的应用场景:
- 电脑键盘:机械键盘在电脑领域广泛应用。由于机械按键提供更好的触感和键程,使得打字和游戏体验更加舒适和精准。
- 游戏设备:机械按键在游戏机、游戏手柄和游戏机械键盘中得到广泛应用。机械按键的触感反馈和快速响应时间有助于提高游戏的控制性能。
- 工业控制设备:机械按键耐用性强,适用于工业控制设备中需要频繁操作的场景,如机械控制面板、机器人控制台等。
- 通信设备:机械按键可以用于手机、电话、对讲机等通信设备中,提供更好的按键触感和可靠性。
- 音频设备:机械按键在音频设备中使用广泛,如调音台、音频控制面板、音乐键盘等。
- 医疗设备:机械按键在医疗设备中的应用很常见,如医疗仪器、手术台控制面板等,机械按键的稳定性和可靠性对医疗设备的正常运行至关重要。
- 汽车和航空设备:机械按键可以用于汽车控制面板、飞机仪表盘等需要高可靠性和耐用性的场景。
机械按键的耐用性、触感和可靠性使其成为许多领域中首选的选择。无论是为了提高工作效率,还是为了提供更好的用户体验,机械按键都在许多应用场景中得到广泛应用。
2 按键电路
开发板上的按键电路原理图如下所示,J11用于控制0/4/8/按钮处于矩阵键盘中还是独立按键中,16个按键用一组P3X端口控制。
开发板的按键实物如图所示
3 按键软件设计
3.1 按键实现
首先我们实现独立按键,将J11使用跳线帽把2.3两个短接,这样就能实现0/4/8/C按键的独立使用。
1、软件工程,我们新建两个文件,分别为c51_key.c和c51_key.h,在c51_key.c中应用includes.h,在includes.h包含c51_key.h,并将两个共文件添加到工程中如图所示。
因为要显示按键数值,我们用前面的数码管实现数据显示。
显示函数如下所示。
c
/********************************************************
函数名称:sys_keynum_ledon
函数功能:显示按键数值
入口参数:按键数值
出口参数:
修 改:
内 容:
********************************************************/
void sys_keynum_ledon(unsigned char num)
{
//根据原理图,将P0口全部输出高电平,P2选择0号数码管
P0=EL[num];//取显示数据,段码
P2=0; //取位码
}
在c51_key.c中,实现按键检测
c
bit key1=0; //定义按键位置
bit key2=0;
bit key3=0;
bit key4=0;
/********************************************************
函数名称:sys_key_single
函数功能:按键检测
入口参数:
出口参数:按键数值
修 改:
内 容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
key1=P30; //定义按键位置
key2=P31;
key3=P32;
key4=P33;
if(!key1) //按下相应的按键,数码管显示相应的码值
{
key1_history = 1;
return 1;
}
else if(!key2)
{
key1_history = 2;
return 2;
}
else if(!key3)
{
key1_history = 3;
return 3;
}
else if(!key4)
{
key1_history = 4;
return 4;
}
else
{
return key1_history;
}
}
主程序main中引用:
c
#include "includes.h"
/*------------------------------------------------
延时子程序
------------------------------------------------*/
void delay(unsigned int cnt)
{
while(--cnt);
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
//8个指示灯的操作
sys_led();
sys_led_test();
sys_led_test1();
sys_ledtube_on1();
sys_ledtube_on2();
//主循环中添加其他需要一直工作的程序
while (1)
{
sys_keynum_ledon(sys_key_single());
}
}
3.2 按键滤波方法
c
/********************************************************
函数名称:sys_key_single
函数功能:按键检测,带有消抖策略
入口参数:
出口参数:按键数值
修 改:
内 容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
key1=P30; //定义按键位置
key2=P31;
key3=P32;
key4=P33;
if(!key1) //按下相应的按键,数码管显示相应的码值
{
delay(1000);
if(!key1)
{
key1_history = 1;
return 1;
}
else
{
return key1_history;
}
}
else if(!key2)
{
delay(1000);
if(!key2)
{
key1_history = 2;
return 2;
}
else
{
return key1_history;
}
}
else if(!key3)
{
delay(1000);
if(!key3)
{
key1_history = 3;
return 3;
}
else
{
return key1_history;
}
}
else if(!key4)
{
delay(1000);
if(!key4)
{
key1_history = 4;
return 4;
}
else
{
return key1_history;
}
}
else
{
return key1_history;
}
}
3.3 矩阵按键软件设计
// 显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态
c
unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,\
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
c
unsigned char sys_key_board(void)
{
unsigned char key = 0x00;
unsigned char num = 0x00;
key=keyscan(); //调用键盘扫描
if(key == 0xFF)
{
num = key1_history;
}
else
{
switch(key)
{
case 0xee:num = 0x0;break;//0按下相应的键显示相对应的码值
case 0xde:num = 0x1;break;//1 按下相应的键显示相对应的码值
case 0xbe:num = 0x2;break;//2
case 0x7e:num = 0x3;break;//3
case 0xed:num = 0x4;break;//4
case 0xdd:num = 0x5;break;//5
case 0xbd:num = 0x6;break;//6
case 0x7d:num = 0x7;break;//7
case 0xeb:num = 0x8;break;//8
case 0xdb:num = 0x9;break;//9
case 0xbb:num = 0xA;break;//a
case 0x7b:num = 0xB;break;//b
case 0xe7:num = 0xC;break;//c
case 0xd7:num = 0xD;break;//d
case 0xb7:num = 0xE;break;//e
case 0x77:num = 0xF;break;//f
default:num = key1_history; break;
}
key1_history = num;
}
return num;
}
/*------------------------------------------------
键盘扫描程序
------------------------------------------------*/
unsigned char keyscan(void) //键盘扫描函数,使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}
return(0xff); //返回该值
}
3.4 按键Protues 仿真
独立按键显示结果,拨码开关,将按键一端接地
矩阵键盘按键仿真:
4 按键操作总结
在单片机应用中,按键检测的可靠性设计对于确保正确的输入和稳定的系统操作至关重要。以下是一些提高按键检测可靠性的设计原则:
- 消除按键抖动:按键抖动是指按键在按下或释放时产生的短暂的不稳定信号。为了消除抖动,可以采用硬件或软件的抖动消除方法。硬件方面,可以使用外部电容或RC网络来滤除抖动。软件方面,可以使用软件延时或状态机来稳定按键信号。
- 使用外部上拉/下拉电阻:通过使用外部上拉或下拉电阻连接到按键引脚,可以确保按键在未按下时保持稳定状态。这样做可以防止未按下按键时的浮动信号。
- 延时和去抖动算法:在软件中实施适当的延时和去抖动算法可以提高按键检测的可靠性。延时可以确保稳定的按键状态,并避免误触发。去抖动算法可以滤除按键抖动,确保只检测到有效的按键操作。
- 多重检测和确认:为了提高可靠性,可以使用多重按键检测和确认机制。例如,可以使用软件定时器或中断来周期性地检测按键状态,并通过多次确认来确保按键的有效触发。
- 输入缓冲区和状态机:使用输入缓冲区可以存储按键输入,然后使用状态机来处理输入。状态机可以跟踪按键状态和处理按键事件,以确保按键操作的正确性和稳定性。
- 电源和地线的干扰隔离:为了防止电源干扰和地线回流对按键信号的影响,可以采取适当的隔离措施。例如,使用独立的电源和地线平面,或者使用滤波器来减少干扰。
- 硬件和软件的容错机制:设计容错机制可以在出现错误或异常情况时保护按键输入的可靠性。例如,可以使用冗余检测、校验和检测、错误处理和恢复机制等。
总的来说,可靠的按键检测设计需要综合考虑硬件和软件方面的各种因素,并根据具体应用场景进行适当的优化和调整。通过合理的设计和实施,可以确保按键的稳定性、准确性和可靠性。