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 内部拉高,这样 ...
随机推荐
- Linux系统更改/关闭防火墙
更改/关闭防火墙 查看当前防火墙状态 /etc/init.d/iptables status ==>service iptables status 打开防火墙 service iptables ...
- 解决标题过长的CSS
不知道为什么大家用截取字符串的人很多呢.. <html> <head> <style type="text/css"> .divout { di ...
- 数据结构&堆&heap&priority_queue&实现
目录 什么是堆? 大根堆 小根堆 堆的操作 STL queue 什么是堆? 堆是一种数据结构,可以用来实现优先队列 大根堆 大根堆,顾名思义就是根节点最大.我们先用小根堆的建堆过程学习堆的思想. 小根 ...
- Hello World ! 第一篇随笔
Hello World ! 第一篇随笔 /* * Language: C++ * Code Name: Hello World ! * @author Metak */ #include <io ...
- 关于markdown格式的测试..
标题 标题一 这是? 标题二 标题三 标题四 区块 1.这是一个列表项目 还是吗? 嵌套了? 空格了? 区块加列表 标题加二级列表 嘿嘿 无序列表 RED GREEN BLUE 有序列表 dog ca ...
- springmvc IDEA
回顾Java平台上Web开发历程来看,从Servlet出现开始,到JSP繁盛一时,然后是Servlet+JSP时代,最后演化为现在Web开发框架盛行的时代.一般接触到一个新的Web框架,都会想问这个框 ...
- standard cell timing model
standard cell timing model 主要包括两方面的信息: Cell Delay calculation Output Transition calculation 首先,cel ...
- P1569 [USACO11FEB]属牛的抗议
题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row and numbered 1..N. The cow ...
- cloudstack 添加新网卡使其能上网
由于虚拟机使用了默认的网络套餐,是不能上网的.现在的需求是使其能上网. 操作步骤: 1.添加一个在能上网的网络里的网卡,使其成为默认网卡 2.复制网卡配置文件,修改网卡名称等,重启network(可能 ...
- .Net操作Excel公式实现
//传入Excel公式,获取公式计算结果private string GetValue(string formula) { string result = ""; try { Ob ...