ATmega8仿真——键盘扫描的学习
1.按键的使用特点
按键的应用主要是在按键闭合时改变电路的电平,但是一般情况下按键的开关都是机械弹性触点开关,即利用触点的接触和分离来实现电路的通断,所以在按键按下和释放时往往会产生抖动干扰。
消除抖动干扰的两种方式:
(1)硬件设计:硬件消抖要在硬件设计上增加消抖电路,如用R-S触发器等,这样就会增加系统成本。
(2)软件设计:在软件中对按键进行二次测试确认,即当第一次检测到按键被按下后,间隔10 毫秒左右再次检测该按键是否被按下,只有两次都册到按键按下时才确认该按键被按下了,从而消除抖动干扰。
2.单键盘扫描应用
用PB口接一个LED数码管,来显示按下按键的次数;
用PC0端口接一个按键电路;
实现的功能是每一次按键,LED数码管显示的数据加1,到9回0。
1 #include <iom8v.h> 2 #include "Delay.h" 3 /** 4 *PB口:连接一个LED数码管 5 *PC0:连接一个按键电路,按下呈低电平 6 * 7 */ 8 unsigned char CountNum; //全局变量,用来计数 9 10 //按键扫描函数 11 void ScanKey(void) 12 { 13 unsigned char key; 14 15 key = PINC; //检测按键状态 16 if(0x01 == key) //未按下,退出 17 return; 18 delay_ms(10); 19 20 key = PINC; //再次检测,防抖动 21 if(0x01 == key) //未按下,退出 22 return; 23 CountNum++; 24 while(0 == key&0x01) //等到按键释放 25 key = PINC; 26 } 27 28 //主函数,扫描按键显示数据 29 void main() 30 { 31 unsigned char num[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 32 //初始化端口 33 DDRB = 0xFF; //设置B口为输出模式 34 PORTB = 0xFF; //置高电平 35 DDRC = 0x00; //设置C口为输入模式 36 37 CountNum = 0; //初始化全局变量 38 while(1) 39 { 40 ScanKey(); //扫描按键 41 if(CountNum >= 10) 42 CountNum -= 10; 43 PORTB = num[CountNum]; 44 } 45 } 46 47 //按键长按的情况 48 void ScanKey_Long(void) 49 { 50 unsigned char key; 51 52 key = PINC; //检测按键状态 53 if(0x01 == key) //未按下,退出 54 return; 55 delay_ms(10); 56 57 key = PINC; //再次检测,防抖动 58 if(0x01 == key) //未按下,退出 59 return; 60 61 while(0x00 == key) //按键长按,不断加加 62 { 63 CountNum++; 64 key = PINC; 65 } 66 }
按键一次LED加一
问:上面的程序没有考虑长按的情况,如果向我们使用的键盘一样,长时间按下一个按键,在屏幕上就不断的打印该字符,在这个例子里怎样实现:若长时间按下按键,CountNum就不断加加?
答:只需要更改ScanKey函数,更改结果如下
1 //按键长按的情况 2 void ScanKey_Long(void) 3 { 4 unsigned char key; 5 6 key = PINC; //检测按键状态 7 if(0x01 == key) //未按下,退出 8 return; 9 delay_ms(10); 10 11 key = PINC; //再次检测,防抖动 12 if(0x01 == key) //未按下,退出 13 return; 14 15 while(0x00 == key) //按键长按,不断加加 16 { 17 CountNum++; 18 key = PINC; 19 } 20 }
长按按键不断加加
3.矩阵按键(键盘)扫描的应用
按键太多的情况下,为了节省I/O资源,通常采用矩阵式的接口。矩阵键盘由行和列组成,每个键都有它的行值和列值,行值和列值的组合就是识别每个键盘的编码。
确定是哪个按键的流程:(???)
(1)在行和列的一个口中输出高电平,在另一个行列口读取一个扫描码;
(2)在后一个行列口中输出高电平,在前一行列口读取第二个扫描码;
(3)查表确定哪个按键被按下。
电路图如下:
程序实现步骤:
(1)确定有无按键按下;
(2)确定是哪个按键;
(3)返回该按键值或处理对应的任务;
(4)再加上,考虑抖动消除,等待按键的断开。
要实现每按下一个按键,就在LED数码管显示出该按键对应的值,按键断开后或默认显示“-”:
1 #include <iom8v.h> 2 #include "Delay.h" 3 /** 4 *PB口:连接一个LED数码管 5 *PC0-PC5:连接9个按键电路,按下呈低电平 6 * PC0-PC2:按键的行 7 * PC3-PC5:按键的列 8 * 9 *1:确定有无按键按下,main函数两次判断实现; 10 *2:确定是哪个按键,ScanKey函数实现; 11 *3:返回该键值或处理对应的任务,main函数中处理。 12 */ 13 14 15 //按键扫描函数,确定是哪个按键,返回按键的值 16 unsigned char ScanKey(void) 17 { 18 unsigned char tempH,tempL,key; 19 20 tempH = PINC & 0x07; //取PC0-PC2用于判断行 21 switch (tempH) 22 { 23 case 0x06: 24 DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式 25 delay_us(1); 26 tempL = PINC & 0x38; //取PC3-PC5用于判断列 27 switch (tempL) 28 { 29 case 0x30: key = 0x01; //得到键值 30 break; 31 case 0x28: key = 0x02; 32 break; 33 case 0x18: key = 0x03; 34 break; 35 default: key = 0; 36 break; 37 } 38 DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式 39 break; 40 41 case 0x05: 42 DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式 43 delay_us(1); 44 tempL = PINC & 0x38; //取PC3-PC5用于判断列 45 switch (tempL) 46 { 47 case 0x30: key = 0x04; //得到键值 48 break; 49 case 0x28: key = 0x05; 50 break; 51 case 0x18: key = 0x06; 52 break; 53 default: key = 0; 54 break; 55 } 56 DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式 57 break; 58 59 case 0x03: 60 DDRC = 0x07; PORTC = 0x38;//将PC3-PC5(列)置为输入模式 61 delay_us(1); 62 tempL = PINC & 0x38; //取PC3-PC5用于判断列 63 switch (tempL) 64 { 65 case 0x30: key = 0x07; //得到键值 66 break; 67 case 0x28: key = 0x08; 68 break; 69 case 0x18: key = 0x09; 70 break; 71 default: key = 0; 72 break; 73 } 74 DDRC = 0x38; PORTC = 0x07;//输入完毕恢复默认输出模式 75 break; 76 77 default: 78 key = 0; 79 break; 80 } 81 return (key); 82 83 } 84 85 //主函数,扫描按键显示数据 86 void main() 87 { 88 unsigned char temp,keynum; 89 unsigned char num[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 90 //初始化端口 91 DDRB = 0xFF; //设置B口为输出模式 92 PORTB = 0xFF; //置高电平 93 //将PC0-PC2(行)置为输入模式 94 DDRC = 0x38; 95 PORTC = 0x07; 96 97 while(1) //两次检测行中有没有按下 98 { 99 PORTC = 0x40; //没有按键时,LED默认显示- 100 //第一次检验 101 temp = PINC & 0x07; 102 if(0x07 == temp) 103 continue; 104 delay_ms(10); 105 //第二次检验 106 temp = PINC & 0x07; 107 if(0x07 == temp) 108 continue; 109 110 //有按下,LED显示键值 111 keynum = ScanKey(); 112 PORTB = num[keynum]; 113 //等到按键被释放 114 while(0x07 != temp) 115 temp = PINC & 0x07; 116 } 117 }
矩阵键盘,LED显示其值
代码总结:
主函数:判断是否有按键按下,并消除抖动干扰,若有则将获得的键值显示在LED数码管中;
ScanKey函数:得到扫描码确定是哪个按键,等待按键释放,返回该按键的值。
方法扩展:
(1)除了像上面的对按键的接口不停的扫描,
(2)还可以使用定时扫描,例如用一个定时器,每隔10MS 对按键接口进行扫描,看是否有按键按下;
(3)也可以使用中断的方式去扫描,当按键按下时由硬件电路产生一个中断,MCU 响应该中断,确定哪个按键被按下,处理相应函数。
转载于:https://www.cnblogs.com/Christal-R/p/6912229.html
ATmega8仿真——键盘扫描的学习相关推荐
- PS2键盘第二套键盘扫描码学习发现
PS2键盘中第二套键盘扫描码使用最广泛.但是每个按键的键值,大多数是一个字节. 有少量的两个字节: 小键盘ENTER 键 E0 5A 右CTRL E0 14 右GUI ...
- 山东大学单片机原理与应用实验 3.4 矩阵键盘扫描实验
目录 一.实验题目 二.实验要求 三.实验过程及结果记录 1. 在Proteus 环境下建立图1所示原理图,并将其保存为keyscan_self.DSN 文件. 2. 编写控制源程序,将其保存为key ...
- c语言矩阵键盘实验心得,DSP-矩阵键盘扫描实验.doc
DSP-矩阵键盘扫描实验 班 级 学号 姓 名 同组人 实验日期 室温 大气压 成 绩 实验五 矩阵键盘扫描实验 一.实验目的 1.掌握键盘信号的输入,DSP I/O的使用: 2.掌握键盘信号之间的时 ...
- VHDL矩阵键盘扫描数码管显示
VHDL矩阵键盘扫描数码管显示 一.新建一个工程 二.矩阵键盘 三.代码部分 四.仿真结果 一.新建一个工程 1.打开Quarteus,直接点击New Project izard. 2.选择存放路径和 ...
- 嵌入式设计与开发项目-ADC键盘扫描程序设计
嵌入式设计与开发项目-ADC键盘扫描程序设计 一.实现的功能 二.根据功能实现代码 1.主文件main.c 2.ADC按键程序的头文件"adc.h" 3.ADC按键程序的源文件&q ...
- 基于FPGA的键盘扫描程序的设计
在现代电子「业的控制电路中,键盘扫描和显示电路时系统的调试和设置有着重要 的作用.随着EDA技术的发展,基于FPGA的扫描键盘因其结构简单,能有效防止机 械键盘按键抖动带来的数据错误等优点在许多电子设 ...
- 实验九、 键盘扫描及数码管显示实验
实验九. 键盘扫描及数码管显示实验 1.实验目的 学习了解键盘扫描的基本原理. 掌握通过并行接口芯片对键盘进行扫描并在多位数码管显示数字的方法. 2.实验内容 编写程序,实现如下功能:初始时数码管无显 ...
- 51单片机4x4矩阵键盘扫描+数码管显示
51单片机4x4矩阵键盘扫描+数码管显示 个位闪烁感在这篇文章已经修复<51单片机4x4矩阵键盘扫描+数码管显示(二)(修bug篇)> 材料:AT89C52.2位数码管.74HC595. ...
- 8255数码管显示0到9_汇编语言--键盘扫描及显示实验(含代码解释)
实验题目 将8255单元与键盘及数码管显示单元连接,编写实验程序,扫描键盘输入,并将扫描结果送数码管显示.键盘采用4X4键盘,每个数码管显示值可为0-F共16个数. 实验具体内容如下:将键盘进行编号, ...
- elementui table某一列是否显示_汇编语言--键盘扫描及显示实验(含代码解释)
实验题目 将8255单元与键盘及数码管显示单元连接,编写实验程序,扫描键盘输入,并将扫描结果送数码管显示.键盘采用4X4键盘,每个数码管显示值可为0-F共16个数. 实验具体内容如下:将键盘进行编号, ...
最新文章
- centos7 install 安装mysql
- JSP第二次作业_8小题
- 处理南通一客户:Fortigate 310B Firmware丢失
- java 更新对象_java通过key-list和对应value更新当前对象
- 和我一起学WCF(6):宿主(Hosting)
- 前端学习(1712):前端系列javascript之创建uni-app创建下
- 局域网即时通讯的可管理性
- 史上最详细JVM笔记
- 【转存】游戏中常用术语
- String 类的常用方法
- 4399小游戏怎样下载到本地玩
- 整型变量和整型常量呀
- 从0开始学大数据(十四)
- C. Dima and Salad
- GitHub之多人开发一个项目
- 官方正式发布 Java 16
- [rust-003] rust by example学习过程点点滴滴杂记
- win10系统无法访问ftp服务器地址,win10如何访问ftp服务器地址
- 线性差分方程及其通解的一般求法
- 计算机无法连接富士网络打印机,网络打印机无法连接的解决方法是什么
热门文章
- java dns 缓存_一次排查多线程引发Java DNS缓存的Bug
- python字典练习_python字典练习
- 均值定理四个公式_中考数学几何题,就考这140多条公式定理!
- 【2020牛客寒假基础算法训练营】第三场总结
- STM32——库函数版——超声波测距模块
- 小程序marker 气泡怎么用_小程序直播怎么用,看这里!
- 为资产分类定义折旧范围_SAP FICO零基础学习_0006_资产-概述和基本配置
- 二分从查找(2)按条件查找
- 容器技术Docker K8s 37 Serverless Kubernetes(ASK)详解-Serverless容器进化
- 1949-2017闰年 c语言,C语言编写方案-万年历选编.doc