第六讲 独立按键和矩阵键盘 第七讲 数码管要点
- 格式:doc
- 大小:1.12 MB
- 文档页数:23
电气工程学院《单片机原理及其应用》第x次课外设计报告组号:No. xxx组长:xxxxxxxxxxxxxxxxxx组员:xxxxxxxxxxxxxxxxxx组员:xxxxxxxxxxxxxxxxxx设计时间:xxxxxxxxxxxxxxxxxx评定成绩:评定教师:设计内容:利用单片机、1个按钮、4*4矩阵键盘和1位共阳数码管,实现显示闪烁控制功能。
要求:按下数字键,将按下键对应位置值(0~F)显示在数码管上;按下按钮,显示以0.5秒间隔闪烁;再次按下按钮,显示闪烁停止。
摘要:单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。
概括的讲:一块芯片就成了一台计算机。
它的体积小、质量轻、价格便与结构的最佳选择。
单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。
从二十世纪九十年代开始,单片机技术就已经发展起来,随着时代的进步与科技的发展,目前该技术的实践应用日渐成熟,单片机被广泛应用于各个领域。
现如今,人们越来越重视单片机在智能电子技术方面的开发和应用,单片机的发展进入到新的时期,无论是自动测量还是智能仪表的实践,都能看到单片机技术的身影。
电子信息技术与单片机技术相融合,有效提高了单片机应用效果。
作为计算机技术中的一个分支,为智能化电子设备的开发和应用提供了新的出路,实现了智能化电子设备的创新与发展。
单片机也被称为单片微控器,属于一种集成式电路芯片。
在单片机中主要包含CPU、只读存储器ROM和随机存储器RAM等,多样化数据采集与控制系统能够让单片机完成各项复杂的运算,无论是对运算符号进行控制,还是对系统下达运算指令都能通过单片机完成。
由此可见,单片机凭借着强大的数据处理技术和计算功能可以在智能电子设备中充分应用。
简单地说,单片机就是一块芯片,这块芯片组成了一个系统,通过集成电路技术的应用,将数据运算与处理能力集成到芯片中,实现对数据的高速化处理。
第六讲独立按键和矩阵键盘按键是什么东西,我想这个就不必由我向各位阐述了。
嗯,如你所见,按键种类繁多,功能有简有繁,极大的充斥着我们的生活。
但是无论如何,所有的按键其实都有一个原型,来源于同一种原理,所有的按键无论多复杂,多华丽,都是从这样一个原型发展而成的。
好比你就算长的再帅,你也是只猩猩变来的,呵呵。
我们平日所见到的绝大部分的按键,其实都可以归类为一种,叫“接触式按键”。
下图为一个典型的接触式按键(又称轻触开关)。
需要特别说明的是,这里说的“接触”,是指机械层面上的接触,而不是感光或者某些特殊涂层(比如触摸屏)一类的接触。
所以,按键的工作特性其实是一种机械特性,下文会详细说明。
,如上图,请对照图一想象,1、2、3、4 分别对应按键的四个引脚,其中蓝色的线表示按键未被按下之时的状态,我成为初始状态,它是不导通的;而绿色的线是却永久导通的。
各位明白了么,其实是两个相同的结构连在一起了。
我们只要将需要按键开关作用的线路分别接在1、3 和2、4 的任意取一组合,概括起来就是(1,2)、(1,4)、(3,2)、(3,4)四种组合,都可以起到我们预期的开关作用。
相信以上说明使大家对按键的工作原理有了个比较清晰的认识了,现在来说说一个小知识。
先看下图(图4):首先说明的是,上图的连法是不允许的,因为当按键按下之后,电源和地短接,会将导线直接烧毁。
但是此处用作特例,假设导线不会烧毁。
现在来提出一个问题,当按键按下以后,请问如果这时用万用表测量导线上任何一处的电压,得到的结果是VCC 还是GND 的电压?答案是:GND,即表示测出的电压为0V。
为什么呢,因为导线上,对于两端的电平是一种类似于程序语言逻辑运算里面的“与”,即对于导线两端:有零即为零,只有全为一是才为一。
理解了这点,按键的工作前提就有了。
键盘分为编码键盘和非编码键盘。
键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。
单片机独立按键和矩阵键盘概念及原理一、基本知识 1.按键分类与输入原理 按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。
前者造价低,后者寿命长。
目前,微机系统中最常见的是触点式开关按键。
在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。
当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入时与软件结构密切相关的过程。
对于一组键或一个键盘,总有一个接口电路与CPU相连。
CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。
2.按键结构与特点 微机键盘通常使用机械触点式按键开关,其主要功能式把机械上的通断转换为电气上的逻辑关系。
也就是说,它能提供标准的TTL逻辑电平,以便于通用数字系统的逻辑电平相容。
机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定的时间触点机械抖动,然后其触点才稳定下来。
其抖动过程如下图1所示,抖动时间的长短与开关的机械特性有关,一般为5-10ms。
在触点抖动期间检测按键的通与断,可能导致判断出错,即按键一次按下或释放错误的被认为是多次操作,这种情况是不允许出现的。
为了克服你、按键触点机械抖动所致的检测误判,必须采取消抖措施。
按键较少时,可采用硬件消抖;按键较多式,采用软件消抖。
图1 按键触点机械抖动 (1)按键编码 一组按键或键盘都要通过I/O口线查询按键的开关状态。
根据键盘结构的不同,采用不同的编码。
无论有无编码,以及采用什幺编码,最后都要转换成为与累加器中数值相对应的键值,以实现按键功能程序的跳转。
(2)键盘程序 一个完整的键盘控制程序应具备以下功能: a.检测有无按键按下,并采取硬件或软件措施消抖。
HC6800-EM3-V2.2 单片机开发板学习指南普中科技目录第一讲开发板资源介绍 (4)第二讲:软件安装 (6)第三讲程序下载 (21)第四讲KEIL软件使用及入门led灯 (27)第五讲蜂鸣器 (44)第六讲独立按键和矩阵键盘 (47)第七讲数码管 (60)第八讲继电器 (74)第九讲led点阵 (82)第十讲IO口输入扩展74HC165芯片 (96)第十一讲电机 (103)第十二讲串口通信 (114)第十三讲1602液晶显示 (124)第十四讲温度传感器18B20 (135)第十五讲EEPROM操作24C02 (145)第十六讲时钟芯片DS1302 (153)第十七讲中断 (161)第十八讲红外遥控显示 (169)第十九讲AD/DA 模数/数模转换 (173)第二十讲光敏电阻与热敏电阻 (180)第二十一讲液晶屏显示 (183)附录A 单片机C语言介绍 (193)附录B 电路板绘制软件PROTEL介绍 (241)第一讲开发板资源介绍本开发板相对以往开发板的特点是综合性比较高、把短路冒去掉了省去接线的麻烦更加方便了初学者、是一款性价比极高的产品,提供USB2.0和串口两种通信方式,USB实现供电、编程、仿真、通信多种功能,另外还提供了Atmel单片机的ISP接口。
此板兼容STC、SST、Atmel、Philips等51家族的所有单片机。
如果使用ISP编程建议使用开发板自带的单片机,因为每个厂烧录程序的方式不一样。
HC6800S开发板有着丰富的外部资源,通过对该开发实验仪的学习,学员不仅可以轻松快速地掌握单片机软件系统的开发(C语言、汇编语言),而且还能快速掌握硬件电路的设计及嵌入系统开发流程。
本套件配有丰富的实例源码、原理图等,特别适合单片机初学者,大中专院校师生,单片机开发工程师选用,也是毕业设计和电子竞赛不可多得的参考板➢单片机采用STC90c516 1280 SRAM 64K Flash➢ 2.2寸彩色液晶屏➢SD接口➢8*8 双色点阵(红色、绿色)➢1602液晶屏接口➢12864液晶屏接口➢温度传感器DS18B20➢EEPROM 24C02 存储器➢8为动态数码管➢1位静态显示数码管➢AD/DA转换 PCF8951➢DS1302实时时钟,配电池座➢IO口扩展输出芯片74HC165,实现并行输入➢4*4矩阵键盘➢2*4个独立键盘➢8路led灯➢可更换晶振座➢PS2 键盘接口➢USB 接口,实现下载,供电,串行通信。
矩阵键盘使用说明矩阵键盘是一种特殊设计的键盘,其按键布局呈矩阵状,与传统的直排键盘有所不同。
矩阵键盘的按键分布更加紧凑,使得用户的手指在按键时的移动距离更小,可以提高打字的速度和准确性。
在本篇文章中,将介绍矩阵键盘的基本使用说明。
1.连接键盘:2.打字基本操作:和传统键盘相比,矩阵键盘的按键布局有所不同。
在开始打字之前,需要了解矩阵键盘的按键分布。
通常情况下,矩阵键盘的按键分布为4行,每行有10个按键,共40个按键。
每个按键上标有一个字母、数字或符号,用户通过按下相应的按键来输入字符。
由于按键的布局更加紧凑,用户在使用矩阵键盘时需要稍微调整手指的位置。
一般来说,用户应该将手指放置在键盘上,使得拇指位于空格键上,食指、中指和无名指分别位于第一行、第二行和第三行按键上,小指位于第四行按键上。
这样可以更加灵活地操作按键,并提高打字的速度和准确性。
当需要输入字符时,用户可以按下相应的按键,即可将字符输入到计算机中。
和传统键盘类似,用户可以通过长按Shift键来输入大写字母,并通过按下Caps Lock键来锁定大写输入模式。
此外,矩阵键盘通常还具备一些特殊功能按键,例如功能键、控制键等。
用户可以通过按下这些特殊按键来完成一些特定的操作,例如切换输入法、调节音量等。
3.高级功能:除了基本的打字功能外,矩阵键盘通常还具备一些高级功能。
例如,一些矩阵键盘支持多键触发功能,即用户可以同时按下多个按键,以实现一些复杂的操作。
例如,在游戏中,用户可以同时按下多个按键来触发组合技能。
此外,一些矩阵键盘还支持自定义按键功能。
用户可以通过软件设置,将一些按键映射为其他功能键或字符,以满足个性化的需求。
一些高端的矩阵键盘还具备背光功能。
用户可以通过调节键盘的背光亮度和颜色,以适应不同的环境需求。
4.清洁和维护:和其他键盘一样,矩阵键盘也需要定期进行清洁和维护。
由于矩阵键盘的按键间隙较小,容易积累灰尘和污垢。
用户可以使用软刷或气泡喷射器清洁键盘表面和按键间隙。
矩阵键盘嵌入式移动设备的应用越来越广,以其体积小、重量轻、便于携带等特点而备受青睐。
键盘是一种最为普遍使用的输入工具,但嵌入式移动设备因其体积小的特点决定了它的键盘不大可能采用普通PC机上的标准键盘,因而大多数采用键数相对较少的矩阵键盘。
利用矩阵键盘用户可以很方便的实现对嵌入式移动设备进行相应的操作,是极方便的人机交互设备。
随着微软的嵌入式操作系统Windows CE的普及,Windows CE的矩阵键盘开发得到了越来越多开发者的重视,本文与大家分享我在开发矩阵键盘的一些总结。
1.Windows CE驱动分类Windows CE提供了许多用于开发设备驱动的模型,这些驱动程序模型使得Windows CE 能适应大部分的内部和外围设备。
因此,在深入探讨Windows CE矩阵键盘驱动程序之前,先了解在WinCE平台上使用的两种设备:内建设备和可安装设备。
因此,从驱动加载方式来看WinCE可分为本机设备驱动(Built-In Driver)、可加载驱动(Loadable Driver)。
本机设备驱动即Native Device Drivers,WinCE设计成可直接使用内建设备,这些设备由本机驱动过程控制。
本机驱动程序是与WinCE的核心组件紧密相连,这些驱动对应的设备通常在系统启动时,在GWES的进程空间内被加载,因此它们不是以独立的DLL形式存在。
可加载设备是指可与平台连接和分离的第三方接口设备,可由用户随时安装和卸载这些驱动,可以在系统启动时或者和启动后的任何时候由设备管理器动态加载。
通常这类驱动是以DLL动态链接库的形式存在,系统加载后这些驱动程序是以用户态的角色运行,这种外围设备的驱动也被称为流驱动。
两者的差别在于它们提供的编程接口不同:本地设备驱动可以根据具体设备的需求提供本机的相应接口;而流接口驱动则是提供一组通用接口即流接口函数,应用程序可以通过流接口提供的接口函数来访问外围设备。
2.嵌入式矩阵键盘驱动原理嵌入式设备上的键盘受设备本身体积影响,键盘设计大多数采用矩阵形式。
实验5 独立键盘和矩阵键盘一、实验目的1、学会用C语言进行独立按键应用程序的设计。
2、学会用C语言进行矩阵按键应用程序的设计。
二、实验内容1、独立按键:对四个独立按键编写程序:当按k1时,8个LED同时100ms闪烁;当按k2时,8个LED从左到右流水灯显示;当按k3时,8个LED从右到左流水灯显示;当按k4时,8各LED同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭;2、矩阵按键:采用键盘扫描方式,顺序按下矩阵键盘后,在一个数码管上顺序显示0~F,采用静态显示即可。
3、提高部分(独立按键、定时器、数码管动态扫描):编写程序,实现下面的功能。
用数码管的两位显示一个十进制数,变化范围为00~59,开始时显示00,每按一次k1,数值加1;每按一次k2,数值减1;每按一次k3,数值归零;按下k4,利用定时器功能使数值开始自动每秒加1;再按一次k4,数值停止自动加1,保持显示原数。
三、实验步骤1、硬件连接(1)使用MicroUSB数据线,将实验开发板与微型计算机连接起来;(2)在实验开发板上,用数据线将相应接口连接起来;2、程序烧入软件的使用使用普中ISP软件将HEX文件下载至单片机芯片内。
查看结果是否正确。
四、实验结果——源代码1. #include "reg52.h"typedef unsigned char u8;typedef unsigned int u16;#define LED P2sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;const char tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; u8 code begMid[]={0x7e, 0xbd,0xdb,0xe7, 0xdb, 0xbd, 0x7e}; void Delay(u16 i){ while(i--);}void KeyDown(){u8 i;if(key2==0){Delay(1000);if(key2==0){for(i=0;i<8;i++){LED=tab[i];Delay(50000);}while(!key2);}LED=0xff;}else if(key1==0){Delay(1000);if(key1==0)for(i=0;i<3;i++){LED=0x00;Delay(10000);LED=0xff;Delay(10000);}}}}void Int0Init(){IT0=1;EX0=1;EA=1;}void Int1Init(){IT1=1;EX1=1;EA=1;} void main(){Int0Init();Int1Init();while(1){KeyDown();}}void Int0() interrupt 0{u8 i;if(key3==0){Delay(1000);if(key3==0)for(i=7;i>=0;i--){LED=tab[i];Delay(50000);}}}}void Int1() interrupt 2{u8 i;if(key4==0){Delay(1000);if(key4==0){for(i=0;i<=6;i++){LED=begMid[i];Delay(50000);}}}}2.#include "reg52.h"typedef unsigned int u16;typedef unsigned char u8;#define GPIO_DIG P0#define GPIO_KEY P1sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;u8 KeyValue;u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//??0~F?? void delay(u16 i){while(i--);}void KeyDown(void){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f){delay(1000);if(GPIO_KEY!=0x0f){GPIO_KEY=0X0F;switch(GPIO_KEY){case(0X07): KeyValue=0;break;case(0X0b): KeyValue=1;break;case(0X0d): KeyValue=2;break;case(0X0e): KeyValue=3;break;}GPIO_KEY=0XF0;switch(GPIO_KEY){case(0X70): KeyValue=KeyValue;break;case(0Xb0): KeyValue=KeyValue+4;break;case(0Xd0): KeyValue=KeyValue+8;break;case(0Xe0): KeyValue=KeyValue+12;break;}while((a<50)&&(GPIO_KEY!=0xf0)){delay(1000);a++;}}}}void main(){LSA=0;LSB=0;LSC=0;while(1){KeyDown();GPIO_DIG=smgduan[KeyValue];}}3.#include <reg52.h>typedef unsigned int u16;typedef unsigned char u8;#define KEYPORT P3sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;u16 t;u8 sec;u8 DisplayData[2];u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void Time1Init(){TMOD |= 0x10;TH1=0Xd8;TL1=0Xf0;EA=1;ET1=1;}void delay(u16 i){while(i--); }void DigDisplay(){u8 i;for(i=0;i<2;i++){switch(i){case 0:LSA=0;LSB=0;LSC=0;break;case 1:LSA=1;LSB=0;LSC=0;break;}P0=DisplayData[i];delay(100);P0=0x00;}}void datapros(){DisplayData[0]=smgduan[sec%10];DisplayData[1]=smgduan[sec/10];}void main(){Time1Init();while(1){if(key4==0){delay(1000);if(key4==0){TR1=!TR1;while(key4==0);}}if(key3==0){delay(1000);if(key3==0){sec=0;while(key3==0);}}if(key2==0){delay(1000);if(key2==0){sec--;while(key2==0);}}if(key1==0){delay(1000);if(key1==0){sec++;while(key1==0);}}}}void Time1() interrupt 2{TH1=0Xd8;TL1=0Xf0;t++;if(t==100){t=0;sec++;if(sec>=60){sec=0;}}datapros();DigDisplay();}五、实验体会——结果分析1、独立按键:位定义四个按键key1、key2、key3、key4,宏定义LED为P2口,tab数组保存流水灯D0-D7依次点亮的数值,begMid数组保存流水灯同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭的赋值方式。
51单片机学习之5-独立按键和矩阵键盘
第14集
键盘的原理
键盘分编码键盘(例如电脑键盘)和非编码键盘(自己用程序去识别)。
非编码键盘分:独立式非编码键盘(独立按键)、行列式非编码键盘(4*4阵列键盘)
独立键盘的电路图。
因为51单片机的IO口不是双向口而是准双向口,要让IO口具备输入功能,必须将IO口置1,置1之后当按键按下时IO口的电平会被拉低,即被置0。
当检测到IO口为0时即可判断该按键已经按下。
按键按下时会有一个抖动的
过程(弹片会抖动),由于单片机检测IO口速度非常快,超过弹片抖动的频率,所以当单片机检测到IO口为0时需延时一小段时间再检测IO是否为0,如果仍为0就确认该按钮被按下。
因为IO口里面有上拉电阻,所以当松开按钮时,IO口又被拉高。
例程:
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitKey=P3;//按键
sbitLed=P1;//Led灯
voiddelay(uintz);
/********主函数********/
voidmain()。
一、矩阵键盘按键的数码管显示1.实验目的(1)掌握VHDL语言的语法规范,掌握时序电路描述方法(2)掌握多个数码管动态扫描显示的原理及设计方法2.实验所用仪器及元器件计算机一台实验板一块电源线一根扁平线一根下载线一根3.实验任务要求设计出4*4矩阵键盘对某一按键按下就在数码管显示一个数字。
按键从左上角到右下角依次为1,2, (16)4.实验原理按键模块原理键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4行均为高电平,那么肯定没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。
同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。
键盘键值的获取:键盘上的每一个按键其实就是一个开关电路,当某键被按下时,该按键的接点会呈现0的状态,反之,未被按下时则呈现逻辑1的状态。
扫描信号由r o w进入键盘,变化的顺序依次为1110-1101-1011-0111-1110。
每一次扫描一排,依次地周而复始。
例如现在的扫描信号为1011,代表目前正在扫描9,10,11,12这一排的按键,如果这排当中没有按键被按下的话,则由column读出的值为1111;反之当9这个按键被按下的话,则由colu mn读出的值为1110。
根据上面所述原理,我们可得到各按键的位置与数码关系如表所示:1110 1110 1110 1110 1101 1101 1101 1101row1110 1101 1011 0111 1110 1101 1011 0111 column1 2 3 4 5 6 7 8键值row 1011 1011 1011 1011 0111 0111 0111 0111column1110 1101 1011 0111 1110 1101 1011 0111键值9 10 11 12 13 14 15 16动态显示原理为使得输入控制电路简单且易于实现,采用动态扫描的方式实现设计要求。
独立键盘/****************************************************************************** * 按键控制程序* 连接方法:JP10(P2)与JP1 (LED灯)连接,* JP11(P0)与JP5(按键接口)连接* * 开始点亮P1LED* 按P01 LED向右移一位* * 按P00 LED向左移一位* 连续按动按钮LED会不停的左移或右移******************************************************************************** /#include <reg51.h>#include <intrins.h>unsigned char scan_key();void proc_key(unsigned char key_v);void delayms(unsigned char ms);sbit K1 = P0^0; //对应按钮K1sbit K2 = P0^1; //对应按钮K2main(){unsigned char key_s,key_v;key_v = 0x03;P2 = 0xfe;while(1){key_s = scan_key();if(key_s != key_v){delayms(10);key_s = scan_key();if(key_s != key_v){key_v = key_s;proc_key(key_v);}}}}unsigned char scan_key(){unsigned char key_s;key_s = 0x00;key_s |= K2;key_s <<= 1;key_s |= K1;return key_s;}void proc_key(unsigned char key_v){if((key_v & 0x01) == 0){P2 = _crol_(P2,1);}else if((key_v & 0x02) == 0){P2 = _cror_(P2, 1);}}void delayms(unsigned char ms) // 延时子程序{unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}矩阵键盘******************************************************************************* *描述: * * 矩阵键盘数码管显示键值** 排线连接方法:JP8(P1)与JP4(矩阵键盘接口)连接P0与JP3(静态数码管)连接* * 矩阵键盘定义:** P1.1-P1.4为列线,P1.4-P1.7为行线* * 喇叭接P1.5口矩阵键盘P1口,* * 注意:请将JP165短路冒断开* ******************************************************************************* #include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar dis_buf; //显示缓存uchar temp;uchar key; //键顺序吗void delay0(uchar x); //x*0.14MS#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};// 此表为LED 的字模unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5 E,~0x79,~0x71};/*************************************************************//* *//* 延时子程序*//* *//*************************************************************/void delay(uchar x){ uchar j;while((x--)!=0){ for(j=0;j<125;j++){;}}}/*************************************************************//* /* 键扫描子程序(4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行*//* P1.1 P1.2 P1.3为列*/*************************************************************/void keyscan(void){ temp = 0;P1=0xF0; //高四位输入行为高电平列为低电平delay(1);temp=P1; //读P1口temp=temp&0xF0; //屏蔽低四位temp=~((temp>>4)|0xF0);if(temp==1) // p1.4 被拉低key=0;else if(temp==2) // p1.5 被拉低key=1;else if(temp==4) // p1.6 被拉低key=2;else if(temp==8) // p1.7 被拉低key=3;elsekey=16;P1=0x0F; //低四位输入列为高电平行为低电平delay(1);temp=P1; //读P1口temp=temp&0x0F;temp=~(temp|0xF0);if(temp==2) // p1.1 被拉低key=key+0;else if(temp==4) // p1.2 被拉低key=key+4;else if(temp==8) // p1.3 被拉低key=key+8;elsekey=16;dis_buf = key; //键值入显示缓存dis_buf = dis_buf & 0x0f;}/*************************************************************//* *//*判断键是否按下*//* *//*************************************************************/void keydown(void){P1=0xF0;if(P1!=0xF0) //判断按键是否按下如果按钮按下会拉低P1其中的一个端口{keyscan(); //调用按键扫描程序}}/*************************************************************//* *//* 主程序*//* *//*************************************************************/main(){P0=0xFF; //置P0口P1=0xFF; //置P1口delay(10); //延时while(1){keydown(); //调用按键判断检测程序P0 = LED7Code[dis_buf%16]&0x7f; //LED7 0x7f为小数点共阴和共阳此处也是不一样; %16表示输出16进制}}/************************************************************/标题: 试验数码管上如何显示数字(共阳极) * 连接方法:P0 与JP3 用8PIN排线连接*请学员认真消化本例程,用单片机脚直接控制数码管* #include <reg51.h>#include <intrins.h>#define NOP() _nop_() /* 定义空指令*/void delay(unsigned int i); //函数声名// 此表为LED 的字模unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5 E,~0x79,~0x71};main(){unsigned int LedNumVal=1 ,C ; //定义变量while(1){if (++C>= 300){ LedNumVal++ ; //每隔300个扫描周期加一次C =0; //每隔300个扫描清零}// 将字模送到P0口显示P0 = LED7Code[LedNumVal%10]&0x7f; //LED7 0x7f为小数点共阴和共阳此处也是不一样;delay(150); //调用延时程序}}/****************************************************************** ** 延时程序** ******************************************************************/void delay(unsigned int i){char j;for(i; i > 0; i--)for(j = 200; j > 0; j--);}*******************************************************************************标题: 试验数码管上显示数字( 单片机直接实现位选共阴极) * * 连接方法:P0与J12 用8PIN排线连接P1与JP16 用排线连接***************************************************************************** 请学员认真消化本例程,用573锁存器控制和单片机脚直接位选控制(非译码器控制)数码管******************************************************************************** #include <reg51.h>#include <intrins.h>void delay(unsigned int i); //函数声名char DelayCNT;//定义变量//此表为LED 的字模, 共阴数码管0-9 -unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制//此表为8个数码管位选控制, 共阴数码管1-8个-unsigned char code dispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F}; //位选控制查表的方法控制/************主函数**********************/main(){unsigned int i,LedNumVal=1 ; //变量定义unsigned int LedOut[10]; //变量定义DelayCNT=0;while(1){if(++DelayCNT>=20) //控制数字变化速度{DelayCNT=0; //20个扫描周期清零一次++LedNumVal; //每隔20个扫描周期加一次}LedOut[0]=Disp_Tab[LedNumVal%10000/1000];LedOut[1]=Disp_Tab[LedNumVal%1000/100]|0x80;LedOut[2]=Disp_Tab[LedNumVal%100/10];LedOut[3]=Disp_Tab[LedNumVal%10];LedOut[4]=Disp_Tab[LedNumVal%10000/1000]; //千位LedOut[5]=Disp_Tab[LedNumVal%1000/100]|0x80; //百位带小数点LedOut[6]=Disp_Tab[LedNumVal%100/10]; //十位LedOut[7]=Disp_Tab[LedNumVal%10]; //个位for( i=0; i<9; i++){P0 = LedOut[i];P1 = dispbit[i]; //使用查表法进行位选/* switch(i) //使用switch 语句控制位选{case 0:P1 = 0x7F; break;case 1:P1 = 0xbF; break;case 2:P1 = 0xdF; break;case 3:P1 = 0xeF; break;case 4:P1 = 0xf7; break;case 5:P1 = 0xfb; break;case 6:P1 = 0xfd; break;case 7:P1 = 0xfe; break;} */delay(150); //扫描间隔时间太长会数码管会有闪烁感}}}void delay(unsigned int i){char j;for(i; i > 0; i--)for(j = 200; j > 0; j--);}。
第六讲独立按键和矩阵键盘按键是什么东西,我想这个就不必由我向各位阐述了。
嗯,如你所见,按键种类繁多,功能有简有繁,极大的充斥着我们的生活。
但是无论如何,所有的按键其实都有一个原型,来源于同一种原理,所有的按键无论多复杂,多华丽,都是从这样一个原型发展而成的。
好比你就算长的再帅,你也是只猩猩变来的,呵呵。
我们平日所见到的绝大部分的按键,其实都可以归类为一种,叫“接触式按键”。
下图为一个典型的接触式按键(又称轻触开关)。
需要特别说明的是,这里说的“接触”,是指机械层面上的接触,而不是感光或者某些特殊涂层(比如触摸屏)一类的接触。
所以,按键的工作特性其实是一种机械特性,下文会详细说明。
,如上图,请对照图一想象,1、2、3、4 分别对应按键的四个引脚,其中蓝色的线表示按键未被按下之时的状态,我成为初始状态,它是不导通的;而绿色的线是却永久导通的。
各位明白了么,其实是两个相同的结构连在一起了。
我们只要将需要按键开关作用的线路分别接在1、3 和2、4 的任意取一组合,概括起来就是(1,2)、(1,4)、(3,2)、(3,4)四种组合,都可以起到我们预期的开关作用。
相信以上说明使大家对按键的工作原理有了个比较清晰的认识了,现在来说说一个小知识。
先看下图(图4):首先说明的是,上图的连法是不允许的,因为当按键按下之后,电源和地短接,会将导线直接烧毁。
但是此处用作特例,假设导线不会烧毁。
现在来提出一个问题,当按键按下以后,请问如果这时用万用表测量导线上任何一处的电压,得到的结果是VCC 还是GND 的电压?答案是:GND,即表示测出的电压为0V。
为什么呢,因为导线上,对于两端的电平是一种类似于程序语言逻辑运算里面的“与”,即对于导线两端:有零即为零,只有全为一是才为一。
理解了这点,按键的工作前提就有了。
键盘分为编码键盘和非编码键盘。
键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。
而靠软件编程来识别的键盘称为非编码键盘,在单片机组成的各种系统中,用的较多的是非编码键盘。
非编码键盘又分为独立键盘和行列式键盘(常说的矩阵键盘)。
在这一讲中我们介绍一下单片机中键盘使用。
单片机的IO口既可作为输出也可作为输入使用,当检测按键时用的是它的输入功能,我们把按键的一端接地,另一端与单片机的某个I/O口相连,开始时先给该IO口赋一高电平,然后让单片机不断地检测该I/O口是杏变为低电平,当按键闭合时,即相当于该I/O口通过按键与地相连,变成低电平,程序一旦检测到I/O口变为低电平则说明按键被按下,然后执行相应的指令。
我们先来说一下,按键常常遇到的问题—抖动问题。
还以图四为例,按键未按下之前,图四按键左端的导线因为连在VCC 上而显示高电平,右端显示低电平,按键按下后,按键闭合,整个导线都显示低电平,然后按键松开,又回到按键按下之前的点评状态。
如果只考察按键左端的电平变化,应该是上图中所显示的一个负脉冲波形。
但是,实际上,正确的波形应该是下图。
相比于上图,大家都看到了在高低电平直接有一段锯齿一样的波形,这就是所谓的按键抖动。
为什么会有按键抖动呢,原因很简单,接触式按键是靠机械的接触来实现开关作用的。
这种接触方式就注定了它要经历一个“接触不稳定——正在稳定中——彻底稳定”的一种过程。
就好比你用手抓紧一颗石头,即使你一开始就很用力的握紧,也不可能马上就达到最紧的状态,也要经历一个从握住到最紧握的过程。
那么在这个过程里,接触式按键就处于一种徘徊在“闭合”与“断开”两者之间的状态。
体现在电路中,就是在一小段时间内有非常多的“按下——抬起”动作。
而这段抖动的时间,大概是10~20 毫秒,依不同的环境条件而定。
解决这个问题常见的方法有软件去抖动和硬件去抖动。
我们解释一下抖动:关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms 左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们再首次检测到键被按下后延时10ms 左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。
独立按键:我们先将一下独立按键的使用方法,开发板独立按键电路图如下:独立按键一共5个,分别连接在单片机的P3.0到P3.4口。
去抖动的方式,我们采用软件延时的方法。
过程如下:1.先设置IO口为高电平(一般上电默认就为高)2.读取IO口电平确认是否有按键按下3.如有IO电平为低电平后,延时几个ms4.再读取该IO电平,如果任然为低电平,说明对应按键按下5.执行相应按键的程序一个独立键盘程序:基础篇第六个,独立按键控制led灯/*********************************************************************独立按键控制led灯两灭//独立按键排线连接P3.0~P3.4口**********************************************************************/#include "reg51.h"sbit key1=P3^0;sbit key2=P3^1;sbit key3=P3^2;sbit key4=P3^3;sbit key5=P3^4;/*******延时函数**************************************/// 定义一个演示函数,定时时间大概为一个毫秒。
void delay(unsigned int i)unsigned char j;for(i; i > 0; i--)for(j = 100; j > 0; j--);}/***********************************************************************/ main(){P0= 0xff;//初始化P0口,全部置1P2 = 0xff;//初始化P2口,关闭所有led灯while(1){P2 = 0xff;//初始化P2口,关闭所有led灯if(key1==0){delay(5);//为去抖动加的延时,利用软件延时if(key1==0)P2 = 0xfe;while(!key1); //等待按键松开,如果将这句去掉的话,//那么led灯保持打开状态。
}if(key2==0){delay(5);if(key2==0)P2 = 0xfd;while(!key2); //等待按键松开}if(key3==0){delay(5);if(key3==0)P2 = 0xfb;while(!key3); //等待按键松开}if(key4==0){delay(5);if(key4==0)P2 = 0xf7;while(!key4); //等待按键松开}if(!key5){delay(5);if(!key5)P2 = 0xef; // if(!key4) 与if(key4==0) 表达的是一个意思。
就是key4按键按下(按下相应管脚为低电平),就会执行后面的语句。
while(!key5); //等待按键松开}}}连接好电路图,下载独立按键控制led灯.hex,观察实验结果矩阵键盘独立键盘与单片机连接时,每一个按键都需要单片机的一个I/O口若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源。
单片机系统中I/O口资源往往比较宝贵,当用到多个按键时为了节省I/O口口线,我们引入矩阵键盘。
我们以4X4矩阵键盘为例讲解其工作原理和检测方法。
将16个按键排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线,我们将这8根线连接到单片机的8个I/O口上,通过程序扫描键盘就可检测16个键。
用这种方法独立按键控制led 灯.hex我们也可实现3行3列9个键、5行5列25个键、6行6列36个键等。
无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的I/O口是否为低电平。
独立键盘有一端固定为低电平,单片机写程序检测时比较方便。
而矩阵键盘两端都与单片机I/O口相连,因此在检测时需人为通过单片机I/O口送出低电平。
检测时,先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的,用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键,当有键被按下时便可判断出按下的键是哪一个键。
当然我们也可以将行线置低电平,扫描列是否有低电平。
这就是矩阵键盘检测的原理和方法。
首先看一下电路图上图是一个4X4 的矩阵键盘,一共是16 个按键。
我们照习惯称横为“行”,“竖”为列。
那么5、6、7、8 我们称之为“行线”,则1、2、3、4 称为“列线”。
要正确记住各个行列线各自对应的IO。
注意看,每一个按键的两端,都分别接在某一个列线和行线上,即:“行线和列线是通过某个按键的按下和抬起实现联通和断开的”,和“导线两端上的信号是经过“与”的关系再体现到导线上的。
”这两句话便构成了矩阵键盘扫描的全部。
要理解好,理解不了就背下来。
现在详细讲述一下矩阵键盘扫描的原理和步骤:扫描矩阵键盘,即是把某一条(只有一条)行线置为低电平,而列线全部置为输入方向,然后检测列线,如果检测到某一条列线是低电平,那么就表示位于这条列线与输出低电平的行线的交点处的按键被按下了。
要扫描16个按键,就依次以这样的方法扫描16次,之后就可以确定哪一个按键被按下了。
当然这里也少不了延时消除按键抖动的环节。
下面看一下程序/******************************************矩阵键盘控制led显示实验*******************************************/#include"reg51.h"#define key_port P0 //定义矩阵键盘扫描的端口sbit hc573_en = P1^3;unsigned char key_value;void delay(unsigned int z) //延时函数{unsigned int x,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}void key_scan(){unsigned char temp; //定义一个临时变量,用来读取键盘扫描端口的值,key_port = 0x7f; //第一行送低电平delay(5);temp=key_port; //获取按键状态,switch(temp){case 0x77: key_value=1;break;case 0x7b: key_value=2;break;case 0x7d: key_value=3;break;case 0x7e: key_value=4;break;default:break;}while(key_port!=0x7f); // 等待按键松下key_port = 0xbf; //第二行送低电平 delay(5);temp=key_port;switch(temp){case 0xb7: key_value=5;break;case 0xbb: key_value=6;break;case 0xbd: key_value=7;break;case 0xbe: key_value=8;break;default:break;}while(key_port!=0xbf); // 等待按键松下key_port = 0xdf; //第三行送低电平 delay(5);temp=key_port;switch(temp){case 0xd7: key_value=9;break;case 0xdb: key_value=10;break;case 0xdd: key_value=11;break;case 0xde: key_value=12;break;default:break;}while(key_port!=0xdf); // 等待按键松下key_port = 0xef; //第四行送低电平 delay(5);temp=key_port;switch(temp){case 0xe7: key_value=13;break;case 0xeb: key_value=14;break;case 0xed: key_value=15;break;case 0xee: key_value=0;break;default:break;}while(key_port!=0xef); // 等待按键松下}main(){hc573_en=0;P1=0; // 执行这句是为了屏蔽数码管和点阵hc573_en=1; //关闭锁存器P2=0;key_value=0xff;while(1){key_scan();P2=~key_value;}}下载矩阵键盘控制led.hex,看实验结果第七讲数码管我们先看看什么是数码管,上图就是各种长相各种样子的数码管了,肯定很眼熟了吧。