ATmega8仿真——键盘扫描的学习
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仿真——键盘扫描的学习的更多相关文章
- ATmega8仿真——外部中断的学习
前面我们学习了ATmega8的I/O口作为通用数字输入/输出口来用时对LED数码管控制和扫描按键的应用: 但ATmega8多数的I/O口都是复用口,除了作为通用数字I/O使用,还有其第二功能,这里我们 ...
- 4x4矩阵键盘扫描
4x4矩阵键盘扫描 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架 ...
- c语言-键盘扫描码
定义: 键盘上的每一个键都有两个唯一的数值进行标志.为什么要用两个数值而不是一个数值呢?这是因为一个键可以被按下,也可以被释放.当一个键按下时,它们产生一个唯一的数值,当一个键被释放时,它也会产生一个 ...
- PS2键盘扫描码:通码与断码
键盘扫描码(实用于标准PC的101.102和104 键的键盘),按下发送通码,弹起发送断码. 说明: 第一类按键,通码为1字节,断码为 0xF0+通码 形式.如A键,其通码为 0x1C,断码为 0xF ...
- 4X4矩阵键盘扫描程序
4X4矩阵键盘扫描: 1. 4根行线的GIO均设为Output,根列线的GIO均设为Input: 2. 4根行线的GIO分别置为0111.1011.1101.1110,读逐一读取列线GIO的值,可确定 ...
- ATmega8仿真——LED 数码管的学习
1. I/O 口的结构及特点 Atmega8 有23 个I/O 引脚,分成3 个8 位的端口B.C 和D,其中C 口只有7 位 Atmega8 采用3个8位寄存器来控制I/O端口,它们分别是:方向寄存 ...
- Win10 IoT C#开发 6 - 4x4矩阵键盘扫描
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...
- <转>键盘扫描码
原文链接:http://www.cnblogs.com/wqw/archive/2009/08/30/1556618.html //以下是一个检测按键扫描码的程序 #i nclude <bios ...
- STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)
本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可. 1.键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样 ...
随机推荐
- windows:nginx配置http、https反向代理
一.下载 Windows 版本的 nginx nnginx下载:http://nginx.org/en/download.html 推荐稳定版本.下载完成后,解压得到 nginx-1.14.0 ,我把 ...
- December 04th 2016 Week 50th Sunday
Learn wisdom by the follies of others. 前车之鉴,后人之师. Maybe my personal state is that others can learn w ...
- My Heart Will Go On(我心永恒)
My Heart Will Go On(我心永恒) 歌词(英文) 歌词(中文) 简介:电影<泰坦尼克号>插曲 歌手:Celine Dion(席琳·迪翁) 词作:韦尔·杰宁斯(Wil ...
- WCF自寄宿实现Https绑定
一.WCF配置 1 Address 将服务端发布地址和客户端访问地址都配置为https开始的安全地址.参考如下. <add key="SrvUrl" value=" ...
- RabbitMQ学习以及与Spring的集成(一)
本文记录RabbitMQ服务的搭建过程. 想要使用RabbitMQ消息中间件服务.首先要安装RabbitMQ,可以在:https://www.rabbitmq.com/download.html根据安 ...
- java 解析json字符串
如果转载我的这篇文章请注明出处,谢谢! 最近工作中,需要解析json格式的字符串,恰好有个例子,感觉不错,拿来分享. 运行这个类需要加载jar包:ezmorph-1.0.6.jar.json-lib- ...
- 前端面试总结——http、html和浏览器篇
1.http和https https的SSL加密是在传输层实现的. (1)http和https的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和 ...
- 自定义input[type="checkbox"]的样式
对复选框自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :checkbox 来实现. 如果直接对复选框设置样式,那么这个伪类并不实用,因为没有多少样式能够对复选框起作用.不过,倒是可 ...
- Nginx变量.md
ngx_http_core_module ngx_http_core_module模块支持名称与Apache服务器变量匹配的嵌入式变量. 首先,这些是表示客户请求头字段的变量,例如$ http_use ...
- ngRouter和ui-router区别
在单页面应用中要把各个分散的视图给组织起来是通过路由机制来实现的.本文主要对 AngularJS 原生的 ngRoute 路由模块和第三方路由模块 ui.router 的用法进行简单介绍,并做一个对比 ...