1.按键的使用特点

  按键的应用主要是在按键闭合时改变电路的电平,但是一般情况下按键的开关都是机械弹性触点开关,即利用触点的接触和分离来实现电路的通断,所以在按键按下和释放时往往会产生抖动干扰。

消除抖动干扰的两种方式:

  (1)硬件设计:硬件消抖要在硬件设计上增加消抖电路,如用R-S触发器等,这样就会增加系统成本。

  (2)软件设计:在软件中对按键进行二次测试确认,即当第一次检测到按键被按下后,间隔10 毫秒左右再次检测该按键是否被按下,只有两次都册到按键按下时才确认该按键被按下了,从而消除抖动干扰。

2.单键盘扫描应用

用PB口接一个LED数码管,来显示按下按键的次数;

用PC0端口接一个按键电路;

  实现的功能是每一次按键,LED数码管显示的数据加1,到9回0。

 #include <iom8v.h>
#include "Delay.h"
/**
*PB口:连接一个LED数码管
*PC0:连接一个按键电路,按下呈低电平
*
*/
unsigned char CountNum; //全局变量,用来计数 //按键扫描函数
void ScanKey(void)
{
unsigned char key; key = PINC; //检测按键状态
if(0x01 == key) //未按下,退出
return;
delay_ms(); key = PINC; //再次检测,防抖动
if(0x01 == key) //未按下,退出
return;
CountNum++;
while( == key&0x01) //等到按键释放
key = PINC;
} //主函数,扫描按键显示数据
void main()
{
unsigned char num[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//初始化端口
DDRB = 0xFF; //设置B口为输出模式
PORTB = 0xFF; //置高电平
DDRC = 0x00; //设置C口为输入模式 CountNum = ; //初始化全局变量
while()
{
ScanKey(); //扫描按键
if(CountNum >= )
CountNum -= ;
PORTB = num[CountNum];
}
} //按键长按的情况
void ScanKey_Long(void)
{
unsigned char key; key = PINC; //检测按键状态
if(0x01 == key) //未按下,退出
return;
delay_ms(); key = PINC; //再次检测,防抖动
if(0x01 == key) //未按下,退出
return; while(0x00 == key) //按键长按,不断加加
{
CountNum++;
key = PINC;
}
}

按键一次LED加一

问:上面的程序没有考虑长按的情况,如果向我们使用的键盘一样,长时间按下一个按键,在屏幕上就不断的打印该字符,在这个例子里怎样实现:若长时间按下按键,CountNum就不断加加?

答:只需要更改ScanKey函数,更改结果如下

 //按键长按的情况
void ScanKey_Long(void)
{
unsigned char key; key = PINC; //检测按键状态
if(0x01 == key) //未按下,退出
return;
delay_ms(); key = PINC; //再次检测,防抖动
if(0x01 == key) //未按下,退出
return; while(0x00 == key) //按键长按,不断加加
{
CountNum++;
key = PINC;
}
}

长按按键不断加加

3.矩阵按键(键盘)扫描的应用

  按键太多的情况下,为了节省I/O资源,通常采用矩阵式的接口。矩阵键盘由行和列组成,每个键都有它的行值和列值,行值和列值的组合就是识别每个键盘的编码。

确定是哪个按键的流程:(???)

(1)在行和列的一个口中输出高电平,在另一个行列口读取一个扫描码;

(2)在后一个行列口中输出高电平,在前一行列口读取第二个扫描码;

(3)查表确定哪个按键被按下。

电路图如下:

程序实现步骤:

(1)确定有无按键按下;

(2)确定是哪个按键;

(3)返回该按键值或处理对应的任务;

(4)再加上,考虑抖动消除,等待按键的断开。

要实现每按下一个按键,就在LED数码管显示出该按键对应的值,按键断开后或默认显示“-”:

 #include <iom8v.h>
#include "Delay.h"
/**
*PB口:连接一个LED数码管
*PC0-PC5:连接9个按键电路,按下呈低电平
* PC0-PC2:按键的行
* PC3-PC5:按键的列
*
*1:确定有无按键按下,main函数两次判断实现;
*2:确定是哪个按键,ScanKey函数实现;
*3:返回该键值或处理对应的任务,main函数中处理。
*/ //按键扫描函数,确定是哪个按键,返回按键的值
unsigned char ScanKey(void)
{
unsigned char tempH,tempL,key; tempH = PINC & 0x07; //取PC0-PC2用于判断行
switch (tempH)
{
case 0x06:
DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式
delay_us();
tempL = PINC & 0x38; //取PC3-PC5用于判断列
switch (tempL)
{
case 0x30: key = 0x01; //得到键值
break;
case 0x28: key = 0x02;
break;
case 0x18: key = 0x03;
break;
default: key = ;
break;
}
DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式
break; case 0x05:
DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式
delay_us();
tempL = PINC & 0x38; //取PC3-PC5用于判断列
switch (tempL)
{
case 0x30: key = 0x04; //得到键值
break;
case 0x28: key = 0x05;
break;
case 0x18: key = 0x06;
break;
default: key = ;
break;
}
DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式
break; case 0x03:
DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式
delay_us();
tempL = PINC & 0x38; //取PC3-PC5用于判断列
switch (tempL)
{
case 0x30: key = 0x07; //得到键值
break;
case 0x28: key = 0x08;
break;
case 0x18: key = 0x09;
break;
default: key = ;
break;
}
DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式
break; default:
key = ;
break;
}
return (key); } //主函数,扫描按键显示数据
void main()
{
unsigned char temp,keynum;
unsigned char num[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//初始化端口
DDRB = 0xFF; //设置B口为输出模式
PORTB = 0xFF; //置高电平
//将PC0-PC2(行)置为输入模式
DDRC = 0x38;
PORTC = 0x07; while() //两次检测行中有没有按下
{
PORTC = 0x40; //没有按键时,LED默认显示-
//第一次检验
temp = PINC & 0x07;
if(0x07 == temp)
continue;
delay_ms();
//第二次检验
temp = PINC & 0x07;
if(0x07 == temp)
continue; //有按下,LED显示键值
keynum = ScanKey();
PORTB = num[keynum];
//等到按键被释放
while(0x07 != temp)
temp = PINC & 0x07;
}
}

矩阵键盘,LED显示其值

代码总结:

  主函数:判断是否有按键按下,并消除抖动干扰,若有则将获得的键值显示在LED数码管中;

  ScanKey函数:得到扫描码确定是哪个按键,等待按键释放,返回该按键的值。

方法扩展:

(1)除了像上面的对按键的接口不停的扫描,

(2)还可以使用定时扫描,例如用一个定时器,每隔10MS 对按键接口进行扫描,看是否有按键按下;

(3)也可以使用中断的方式去扫描,当按键按下时由硬件电路产生一个中断,MCU 响应该中断,确定哪个按键被按下,处理相应函数。

ATmega8仿真——键盘扫描的学习的更多相关文章

  1. ATmega8仿真——外部中断的学习

    前面我们学习了ATmega8的I/O口作为通用数字输入/输出口来用时对LED数码管控制和扫描按键的应用: 但ATmega8多数的I/O口都是复用口,除了作为通用数字I/O使用,还有其第二功能,这里我们 ...

  2. 4x4矩阵键盘扫描

    4x4矩阵键盘扫描 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架 ...

  3. c语言-键盘扫描码

    定义: 键盘上的每一个键都有两个唯一的数值进行标志.为什么要用两个数值而不是一个数值呢?这是因为一个键可以被按下,也可以被释放.当一个键按下时,它们产生一个唯一的数值,当一个键被释放时,它也会产生一个 ...

  4. PS2键盘扫描码:通码与断码

    键盘扫描码(实用于标准PC的101.102和104 键的键盘),按下发送通码,弹起发送断码. 说明: 第一类按键,通码为1字节,断码为 0xF0+通码 形式.如A键,其通码为 0x1C,断码为 0xF ...

  5. 4X4矩阵键盘扫描程序

    4X4矩阵键盘扫描: 1. 4根行线的GIO均设为Output,根列线的GIO均设为Input: 2. 4根行线的GIO分别置为0111.1011.1101.1110,读逐一读取列线GIO的值,可确定 ...

  6. ATmega8仿真——LED 数码管的学习

    1. I/O 口的结构及特点 Atmega8 有23 个I/O 引脚,分成3 个8 位的端口B.C 和D,其中C 口只有7 位 Atmega8 采用3个8位寄存器来控制I/O端口,它们分别是:方向寄存 ...

  7. Win10 IoT C#开发 6 - 4x4矩阵键盘扫描

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...

  8. <转>键盘扫描码

    原文链接:http://www.cnblogs.com/wqw/archive/2009/08/30/1556618.html //以下是一个检测按键扫描码的程序 #i nclude <bios ...

  9. STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)

    本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可. 1.键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样 ...

随机推荐

  1. 铁乐学python_day04-作业

    1,写代码,有如下列表,按照要求实现每一个功能 li = ['alex', 'wusir', 'eric', 'rain', 'alex'] 计算列表的长度并输出 print(len(li)) 答:结 ...

  2. TreeSet的自然排序(自定义对象 compareTo方法)

    >要实现自然排序,对象集合必须实现Comparable接口,并重写compareTo()方法 >一般需求中描述的是"主要条件",如:按姓名长度排序.  需注意次要条件 ...

  3. Hadoop HBase概念学习系列之行、行键(十一)

    行是由列簇中的列组成.行根据行键依照字典顺序排序. HBase的行使用行键标识,可以使用行键查询整行的数据. 对同一个行键的访问都会落在同样的物理节点上.如果表包含2个列簇,属于两个列簇的文件还是保存 ...

  4. 1.3 Essential Python Libraries(一些重要的Python库)

    1.3 Essential Python Libraries(一些重要的Python库) 如果不了解Python的数据生态,以及本书中即将用到的一些库,这里会做一个简单的介绍: Numpy 这里就不过 ...

  5. (动态)代理于HOOK的区别于关系

    代理模式是MITM中间人攻击模式: 是拦截对象的所有交互,然后进行处理转发: HOOK模式是定点拦截,只针对单个函数做处理转发: HOOK模式可以在动态代理模式基础上实现:因为代理模式拦截所有.

  6. HashMap,LinkedHashMap和Hashtable类的深入剖析与理解

    上一篇文章写了一些关于HashMap以及HashMap的线程安全问题,这篇文章再来说说Map系列中HashMap,LinkedHashMap和Hashtable三者之间的差异以及该注意的地方. Has ...

  7. 1303. [CQOI2009]中位数【前缀和+乱搞】

    Description 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为 ...

  8. 3942: [Usaco2015 Feb]Censoring

    3942: [Usaco2015 Feb]Censoring Time Limit: 10 Sec Memory Limit: 128 MB Submit: 964 Solved: 480 [Subm ...

  9. sql server 2000 错误229 拒绝了对象sysobjects 的select 权限

    此问题是权限问题,我的解决办法是因为添加角色的时候勾选太多导致的 !!!!!!千万不要勾选db_denydatareader.

  10. set集合HashSet

    一: 和List接口同一级的还有Set接口,Set类型的集合,元素不能重复,存储顺序和迭代顺序没有必然联系.他的元素的唯一性是由hasCode和equals决定的. 他的子类,常用的HashSet和L ...