矩阵键盘扫描显示键值
矩阵键盘的工作原理和扫描确认方式
// 扫描键盘
{
PORTD = ~key_line; PORTD = ~key_line;
key_value = Key_mask & PIND; if (key_value == Key_mask)
key_line <<= 1; else {
key_state++; break; } } break; case 1: if (key_value == (Key_mask & PIND)) { switch (key_line | key_value) { case 0b00001110:
号码后,原 8 位 LED 数码管的显示内容向左移动一位,最右边一位则显示键盘
上刚按下的数字(“*”键用“A”表示,“#”键用“b”表示)。要求:对键盘按
键操作的反应迅速而且无误,同时按键操作过程中应保证 LED 的扫
矩阵键盘检测
C51矩阵键盘的检测要求:扫描矩阵键盘,并将对应按键的值显示在LED上方法一(传统检测):#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit dula=P2^6;sbit wela=P2^7;//sbit key1=P3^4;uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar num,temp,num1;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}uchar keyscan();void display(uchar aa);void main(){while(1){display(keyscan());}}void display(uchar aa){/*先送数,后选通,延时以后,将所有端口都不选通,这样,拖影就消失了*/ dula=1;P0=table[aa-1];dula=0;wela=1;P0=0x01;wela=0;delay(5);wela=1;P0=0x00;wela=0;}uchar keyscan(){P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xee:num=1;break;case0xde:num=2;break;case0xbe:num=3;break;case0x7e:num=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xed:num=5;break;case0xdd:num=6;break;case0xbd:num=7;break;case0x7d:num=8;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xeb:num=9;break;case0xdb:num=10;break;case0xbb:num=11;break;case0x7b:num=12;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xe7:num=13;break;case0xd7:num=14;break;case0xb7:num=15;break;case0x77:num=16;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}return num;}方法二(技巧检测):#include<reg51.h>#include<intrins.h>sbit dula=P2^6;sbit wela=P2^7;#define uint unsigned int#define uchar unsigned char//uchar code table[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01, 0x09};uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar Key_Value;void Delay_1ms(uint x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<=148;j++);}void Getkey(){uchar i,j,temp,num,Key_Temp1,Key_Temp2,Buffer[4]={0xfe,0xfd,0xfb, 0xf7};for(j=0;j<4;j++)//循环四次{P3=Buffer[j];_nop_();_nop_();temp=0x10;for(i=0;i<4;i++)//循环四次{if(!(P3&temp)){num=i+j*4;//返回取得的按键值}temp<<=1;//换左边一位}}P3=0xff;Key_Temp1=num;//读入按键if(Key_Temp1<16)//有键按下{Delay_1ms(5);//延时消抖Key_Temp2=num;//再读一次if(Key_Temp1==Key_Temp2)//两次相等Key_Value=Key_Temp1;//就确认下来}}void Display(uchar k){dula=1;P0=table[k];dula=0;wela=1;P0=0x01;wela=0;Delay_1ms(5);wela=1;P0=0x00;wela=0;}void Main(void){while(1){Getkey();Display(Key_Value);//显示键值}}。
基于AT89S52的矩阵键盘及键值显示
摘要:本文介绍了用单片扫描一个4*4的矩阵键盘,得出其键盘按下的位置,并在数码管中显示对应的值键。
本系统主要包括三大模块:单片机最小模块、矩阵键盘模块、键值显示模块。
绘制电路原理图与工作流程图,并进行调试,最终设计完成了该系统的硬件电路。
在软件编程上,采用了汇编语言进行编程,开发环境使用Keil集成开发环境。
开发了矩阵键盘程序、数码管显示程序。
关键词:矩阵键盘,数码管显示目录第1章总体设计1.1 系统设计任务1.2 设计方案第2章硬件电路设计2.1 单片机最小系统模块2.1.1复位电路2.1.2时钟电路2.2矩阵键盘模块2.3键值显示模块第3章软件设计3.1 主程序设计3.2 模块程序设计3.2.1 矩阵键盘扫描程序3.2.2 数码管显示程序附录1:原理图附录2:程序清单参考文献第一章总体设计1.1 系统设计任务设计4×4矩阵键盘与单片机的接口电路,并用数码管显示被按下的键的键值。
1.2 设计方案4×4矩阵键盘与AT89S52单片机的P1口相连,单片机工作时候不停的扫描P1,当有键按下时,通过行列的扫描,判断出按下的键。
再通过74LS164串入并出移位寄存器将对应的键值传送到数码管显示出来。
系统总体设计原理如下图所示:图1 系统总体设计框图第2章 硬件电路设计 2.1单片机最小系统模块在本次课题设计中我们选择了AT89S52芯片,其具有功能强、体积小、成本低、功耗小等特点,它可单独地完成现代工业控制所要求的智能化控制功能,能在软件的控制下准确、迅速、高效地完成程序设计者事先规定的任务。
2.1.1复位电路复位电路如图2.1所示,单片机系统常常有上电复位和操作复位两种。
上电复位是指单片机上点瞬间,要在RST 引脚上出现宽度大于10ms 的正脉冲,才能使单片机进入复位状态。
操作复位是指用户按下“复位”按钮使单片机进入复位状态。
2122232425262728293031323334353637383940U1图2.1 复位电路2.1.2时钟电路晶振电路用于产生单片机工作所需的时钟信号,使用晶体震荡器,CY1,CY2取值20~40PF ,使用陶瓷震荡器时CY1,CY2取值30~50PF 。
矩阵键盘的工作原理和扫描确认方式
来源:《AVR 单片机嵌入式系统原理与应用实践》M16 华东师范大学电子系 马潮 当键盘中按键数量较多时,为了减少对 I/O 口的占用,通常将按键排列成
矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图 9-7 所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交 点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU 通过检测行 或列线上的电平变化可以确定哪个按键被按下。
图 9-7 为一个 4 x 3 的行列结构,可以构成 12 个键的键盘。如果使用 4 x 4 的行列结构,就能组成一个 16 键的键盘。很明显,在按键数量多的场合,矩 阵键盘与独立式按键键盘相比可以节省很多的 I/O 口线。
矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式 按键复杂。在矩阵键盘的软件接口程序中,常使用的按键识别方法有行扫描法和 线反转法。这两种方法的基本思路是采用循环查循的方法,反复查询按键的状态, 因此会大量占用 MCU 的时间,所以较好的方式也是采用状态机的方法来设计, 尽量减少键盘查询过程对 MCU 的占用时间。
key_return = K1_1; break; case 0b00001101: key_return = K1_2; break; case 0b00001011: key_return = K1_3; break; case 0b00010110: key_return = K2_1; break; case 0b00010101: key_return = K2_2; break; case 0b00010011: key_return = K2_3; break; case 0b00100110: key_return = K3_1; break; case 0b00100101: key_return = K3_2; break; case 0b00100011: key_return = K3_3; break;
行列式键盘扫描显示
单片机实验六行列式键盘扫描显示一.实验目的1.通过实验掌握查询式键盘的原理和编程方法2.理解按键防抖技术。
二.实验内容数码管为共阴型,P0输出7段码,开机运行数码管显示P,当按键按下时,数码管显示相应的数字键号(1-F)。
三.实验原理图四.实验步骤1.在KEIL4中编写、调试、编译程序。
2.在PRTUSE中设计电路,加载HEX文件运行仿真,按各键观察LED的显示。
3.在实验箱上用杜邦线连接JP4和JP8,JP10和JP3,打开实验箱电源开关,下载*.hex文件到单片机,按键观查运行状态。
五.实验参考程序ORG 0000HAJMP STARTORG 0030HSTART: MOV P0,#73HAN: MOV R1,#0FEHMOV P1,R1JNB P1.4, K1_1JNB P1.5, K2_1JNB P1.6, K3_1JNB P1.7, K4_1MOV A,R1RL AMOV R1,AMOV P1,R1JNB P1.4, K1_2JNB P1.5, K2_2JNB P1.6, K3_2JNB P1.7, K4_2MOV A,R1RL AMOV R1,AMOV P1,R1JNB P1.4, K1_3JNB P1.5, K2_3JNB P1.6, K3_3JNB P1.7, K4_3MOV A,R1RL AMOV R1,AMOV P1,R1JNB P1.4, K1_4JNB P1.5, K2_4JNB P1.6, K3_4JNB P1.7, K4_4AJMP ANK1_1: AJMP K11K1_2: AJMP K12K1_3: AJMP K13K1_4: AJMP K14K2_1: AJMP K21K2_2: AJMP K22K2_3: AJMP K23K2_4: AJMP K24K3_1: AJMP K31K3_2: AJMP K32K3_3: AJMP K33K3_4: AJMP K34K4_1: AJMP K41K4_2: AJMP K42K4_3: AJMP K43K4_4: AJMP K44K11: LCALL DL Y20MSJB P1.4,N0MOV A,#00HLCALL SEG_DISP N0: AJMP ANK12: LCALL DL Y20MSJB P1.4,N1MOV A,#01HLCALL SEG_DISP N1: AJMP ANK13: LCALL DL Y20MSJB P1.4,N2MOV A,#02HLCALL SEG_DISP N2: AJMP ANK14: LCALL DL Y20MSJB P1.4,N3MOV A,#03HLCALL SEG_DISP N3: AJMP ANK21: LCALL DL Y20MSJB P1.5,N4MOV A,#04HLCALL SEG_DISP N4: AJMP ANK22: LCALL DL Y20MSJB P1.5,N5MOV A,#05HLCALL SEG_DISP N5: AJMP ANK23: LCALL DL Y20MSJB P1.5,N6MOV A,#06HLCALL SEG_DISP N6: AJMP ANK24: LCALL DL Y20MSJB P1.5,N7MOV A,#07HLCALL SEG_DISP N7: AJMP ANK31: LCALL DL Y20MSJB P1.6,N8MOV A,#08HLCALL SEG_DISPN8: AJMP ANK32: LCALL DL Y20MSJB P1.6,N9MOV A,#09HLCALL SEG_DISPN9: AJMP ANK33: LCALL DL Y20MSJB P1.6,N10MOV A,#0AHLCALL SEG_DISPN10: AJMP ANK34: LCALL DL Y20MSJB P1.6,N11MOV A,#0BHLCALL SEG_DISPN11: AJMP ANK41: LCALL DL Y20MSJB P1.7,N12MOV A,#0CHLCALL SEG_DISPN12: AJMP ANK42: LCALL DL Y20MSJB P1.7,N13MOV A,#0DHLCALL SEG_DISPN13: AJMP ANK43: LCALL DL Y20MSJB P1.7,N14MOV A,#0EHLCALL SEG_DISPN14: AJMP ANK44: LCALL DL Y20MSJB P1.7,N15MOV A,#0FHLCALL SEG_DISPN15: AJMP ANSEG_DISP: MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ARETDL Y20MS: MOV R6,#14HDL2: MOV R7,#250DL1: NOPNOPDJNZ R7,DL1DJNZ R6,DL2RETTABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;/0123456789 DB 77H,7CH,39H,5EH,79H,71H ;/ABCDEFEND。
4X4矩阵键盘控制数码管显示按键值
4X4矩阵键盘控制数码管显示按键值4X4矩阵键盘控制数码管显示按键值一、设计内容与要求用80C51单片机控制系统显示按键值0~F。
二、设计目的意义2.1 设计目的1、了解单片机系统中实现LED动态显示的原理及方法;2、详细了解8051芯片的性能及编程方法;3、了解单片机系统基本原理,了解单片机控制原理;4、掌握AT89C51输入/输出接口电路设计方法;5、掌握AT89C51程序控制方法;6、掌握单片机汇编编程技术中的设计和分析方法;7、掌握使用PROTEUS软件进行仿真的方法。
8、学会使用并熟练掌握电路绘制软件Protel99SE;9、掌握电路图绘制及PCB图布线技巧。
2.2 设计意义1、在系统掌握单片机相应基础知识的前提下,熟悉单片机应用系统的设计方法及系统设计的基本步骤。
2、完成所需单片机应用系统原理图设计绘制的基础上完成系统的电路图设计。
3、完成系统所需的硬件设计制作,在提高实际动手能力的基础上进一步巩固所学知识。
4、进行题目要求功能基础上的软件程序编程,会用相应软件进行程序调试和测试工作。
5、用AT89C51设计出题目所要求的数码管动态循环显示,并针对实际设计过程中软、硬件设计方面出现的问题提出相应解决办法。
6、通过单片机应用系统的设计将所学的知识融会贯通,锻炼独立设计、制作和调试单片机应用系统的能力;领会单片机应用系统的软、硬件调试方法和系统的研制开发过程,为进一步的科研实践活动打下坚实的基础。
三、系统硬件电路图3.1 Proteus软件简介以及仿真电路图Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。
是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、1ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。
4×4矩阵键盘数码管显现按键值程序
4×4矩阵键盘数码管显现按键值程序4;x;4矩阵键盘数码管显现按键值程序//电路阐明如下。
//单片机:运用51系列兼容的即可;//4;x;4矩阵键盘:接在P1口;//两位数码显现器:P0口输出七段码,P2口输出位选码。
//===================================================== =========//C言语程序如下。
/****************************************************** ********文件名:KEY_LED.c*功用:对4;x;4矩阵键盘进行输出,在数码管后两位显现按键值。
******************************************************* *******/#includelt;reg51.h#includelt;intrins.h#defineuintunsignedint#defineucharunsignedchar//ucharcodetable[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x 01,0x09};ucharcodetable[10]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x8 0,0x90};/****************************************************** *********称谓:Delay_1ms()*功用:延时子程序,延时时刻为1ms*x*输入:x(延时一毫秒的个数)*输出:无******************************************************* ********/voidDelay_1ms(uintx){uinti;ucharj;for(i=0;ilt;x;i++)for(j=0;jlt;=148;j++);}/*******************************************************称谓:Keyscan()*功用:P1外接4;x;4按键,依照扫描法读出键值*输出:按键值0~15/如无键按下,回来16******************************************************* ********/ucharKeyscan(void){uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};for(j=0;jlt;4;j++){//循环四次P1=Buffer[j];//在P1高四位别离输出一个低电平temp=0x01;//方案先判别P1.0位for(i=0;ilt;4;i++){//循环四次if(!(P1temp))//从P1低四位,截取1位return(i+j*4);//回来获得的按键值templt;lt;=1;//判别的位,左移一位}}return16;//判别完毕,没有键按下,回来16}//哈哈,实质性的句子不过8行,即是这么简练!/*******************************************************称谓:Display(uchark)*功用:将参数分红十位、个位别离显现*输入:k(键盘数值)*输出:P0口输出七段码,P2口输出位选码******************************************************* ********/voidDisplay(uchark){P2=0;//消隐P0=table[k/10];P2=0x02;Delay_1ms(5);//显现5ms十位P2=0;//消隐P0=table[k%10];P2=0x01;Delay_1ms(5);//显现5ms个位}/****************************************************** *********称谓:Main()*功用:主函数******************************************************* ********/voidMain(void){ucharKey_Value=16,Key_Temp1,Key_Temp2;//两次读出的键值while(1){//---------以下读入按键、消抖、等候按键开释P1=0xff;Key_Temp1=Keyscan();//先读入按键if(Key_Temp1!=16){//假如有键按下//Delay_1ms(10);//延时一下Display(Key_Value);//可用显现替代延时Key_Temp2=Keyscan();//再读一次按键if(Key_Temp1==Key_Temp2){//有必要是两次持平Key_Value=Key_Temp1;//才保留下来,这即是消除颤动while(Keyscan()lt;16)//等候按键开释Display(Key_Value);//等候时期显现键值//---------以下是对按键的处理Display(Key_Value);//显现键值}}Display(Key_Value);//没有按键按下,也显现键值}}//用PROTEUS仿真作业时的屏幕截图如下:。
1位数码管显示矩阵键盘的按下键的键值
K5 键-计数值加1(外部中断0)K6 键-计数值减1(外部中断1)K5 BIT P3.2K6 BIT P3.3DISSTART EQU 40H ;显示单元首地址LED_DATA EQU P0 ;数码管数据口定义COUNT EQU 30H ;计数单元;******************************************************************* ORG 0000HAJMP MAINORG 0003HAJMP INT0_EX0ORG 0013HAJMP INT1_EX1ORG 0050H;*********************************************************; 主程序;*********************************************************MAIN:MOV SP,#60HMOV P0,#0FFHMOV P2,#0FFHMOV COUNT,#00H ;计数单元清零MOV R0,#DISSTARTCLR1:MOV @R0,#00H ;清显存单元INC R0CJNE R0,#DISSTART+3,CLR1CLR IT0 ;INT0为电平触发; SETB IT0 ;INT0为下降沿触发CLR IT1 ;INT1为电平触发; SETB IT1 ;INT1为下降沿触发SETB EASETB EX0SETB EX1MAIN1:ACALL CONVTACALL PLAYAJMP MAIN1;*********************************************************; INT0 外部中断服务子程序 (加计数);*********************************************************INT0_EX0:PUSH ACC ;入栈保护PUSH PSWSETB RS0 ;更换寄存器组CLR RS1CLR EX0 ;关闭INT0中断INC COUNT ;计数值加1MOV R4,#70EX0_PLAY:MOV A,COUNT ;用显示程序进行延时ACALL CONVTACALL PLAYDJNZ R4,EX0_PLAYSETB EX0 ;开启INT0中断POP PSW ;出栈POP ACCRETI;********************************************************* ; INT1 外部中断服务子程序 (减计数);********************************************************* INT1_EX1:PUSH ACC ;入栈保护PUSH PSWSETB RS0 ;更换寄存器组CLR RS1CLR EX1 ;关闭INT1中断DEC COUNT ;计数值减1MOV R4,#70EX1_PLAY:MOV A,COUNT ;用显示程序进行延时ACALL CONVTACALL PLAYDJNZ R4,EX1_PLAYSETB EX1 ;开启INT1中断POP PSW ;出栈POP ACCRETI;********************************************************* ;数据转换 (HEX TO BCD);********************************************************* CONVT:MOV A,COUNT ;计数值处理MOV B,#100DIV ABMOV DISSTART+2,A ;百位存放在DISSTART+2MOV A,#10XCH A,BDIV ABMOV DISSTART+1,A ;十位存放在DISSTART+1MOV DISSTART,B ;个位存放在DISSTARTMOV A,DISSTART+2 ;高位为0,不显示CJNE A,#00H,CONVT1MOV DISSTART+2,#0AHMOV A,DISSTART+1CJNE A,#00H,CONVT1MOV DISSTART+1,#0AHCONVT1:RET;********************************************************* ; 数码管显示子程序;********************************************************* PLAY:MOV R0,#DISSTART ;获得显示单元首地址MOV R1,#0FEH ;从第一个数码管开始MOV R2,#03H ;共显示3位数码管DISP1:MOV A,@R0 ;获得当前位地址MOV DPTR,#TAB_NU ;获得表头MOVC A,@A+DPTR ;查表获得显示数据MOV LED_DATA,A ;送段码MOV P2,R1 ;送位码MOV A,R1 ;准备下一位的位码RL AMOV R1,AINC R0 ;取下一个显存单元地址ACALL DELAY1MS ;延时 1 MSDJNZ R2,DISP1 ;重复显示下一个MOV P2,#0FFH ;关闭显示RET ;显示完成,返回;*********************************************************;延时子程序;********************************************************* DELAY1MS:MOV R6,#5DEL1:MOV R7,#93DJNZ R7,$DJNZ R6,DEL1RET;*********************************************************TAB_NU:DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H???DB 080H,090H,0FFH;*********************************************************END ;结束BEEP BIT P3.7KEYNUM EQU 30HORG 0000HAJMP MAINORG 0050H;**********************************************************; 主程序;********************************************************** MAIN:MOV SP,#60HMOV KEYNUM,#10H ;开机时显示"-"ACALL KEY_PLAYLOOP:ACALL KEY_SCANAJMP LOOP;**********************************************************;矩阵键盘键值查找程序;键值存入30H单元;**********************************************************KEY_SCAN:MOV P1,#0F0H ;置列线为0,行线为1MOV A,P1 ;读入P1口状态ANL A,#0F0H ;保留高4位MOV B,A ;保存数据MOV P1,#0FH ;置列线为1,行线为0MOV A,P1 ;读入P1口状态ANL A,#0FH ;保留低4位ORL A,B ;高四位与低四位重新组合CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键AJMP KEY_END KEY_IN1:MOV B,A ;保存键值MOV DPTR,#KEYTABLE ;置键编码表首址MOV R3,#0FFH ;KEY_IN2:INC R3 ;查表次数加1MOV A,R3MOVC A,@A+DPTR ;取出键码CJNE A,B,KEY_IN3 ;比较MOV A,R3 ;找到,取次数值MOV KEYNUM,A ;送显示单元ACALL KEY_PLAY ;显示键值ACALL BEEP_BL ;蜂鸣器响一声AJMP KEY_ENDKEY_IN3:CJNE A,#00H,KEY_IN2 ;继续查 ;00H为结束码KEY_END:RET;********************************************************** ; 键编码表;********************************************************** KEYTABLE:DB 0EEH,0EDH,0EBH,0E7H,0DEHDB 0DDH,0DBH,0D7H,0BEH,0BDHDB 0BBH,0B7H,07EH,07DH,07BHDB 077H,00H ;00H为结束码;********************************************************** ;;蜂鸣器响一声子程序;;********************************************************** BEEP_BL:MOV R6,#200BL1:ACALL BL2CPL BEEP ;蜂鸣器取反产生驱动脉冲DJNZ R6,BL1SETB BEEP ;关闭蜂鸣器MOV R5,#25ACALL DELAYRETBL2:MOV R7,#220BL3:NOPDJNZ R7,BL3RET;********************************************************** ; 延时子程序;********************************************************** DELAY: ;延时R5×10MSMOV R6,#50DEL1:MOV R7,#100DJNZ R7,$DJNZ R6,DEL1DJNZ R5,DELAYRET;********************************************************** ;键值显示子程序;********************************************************** KEY_PLAY:MOV A,KEYNUM ;要显示的数据MOV DPTR,#TABLE ;置段码表地址MOVC A,@A+DPTR ;查显示数据段码MOV P0,A ;输出段码至P0CLR P2.0 ;第一个数码管亮RET;**********************************************************; 数码管段码表;**********************************************************TABLE:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8HDB 80H,90H,88h,83h,0c6h,0a1h,86h,8eh,0BFH ;0-F,-;**********************************************************END ;结束1位数码管显示矩阵键盘的按下键的键值。
矩阵键盘状态机之74HC164驱动数码管依次显示键值要点
用视图Web模式看uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭; 按键对应的数字不是上图,而是-------------------------这里下面的{//用IO口P0,所以把A B C D E F G DP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下---------- --------------|-1--|-2--|-3--|-----------------------------------|-4--|-5--|-6--|-----------------------0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00---------------|-7--|-8--|-9--|-----------------//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了---------------|-C--|-0--|-E--|---------------------/* 0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00 //多写了0x00,代表段选全部熄灭*/};0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x7 1,0X00//可以把0x71或任意一个改为0x00,这样就可以按下0x71这个案件时清楚显示了完整程序如下:/*==========================================================* 开发人员:laowang* 当前版本:V1.0* 创建时间:11/26/2013* 修改时间:04/21/2017* 功能说明:对4*3矩阵键盘扫描,用4位共阴数码管进行显示,刚开始时不亮,依次按下按键时数码管依次显示0-F,扫描方法为状态机方法+定时器中断* 修改人员:梁超云*==========================================================*/#include<reg52.h>#include"Define.h"#include"display.h"#include"matrixkeyscan.h"#include "74HC164.h"void Timer0_init(); //定时器初始化函数uint flag1=0;uint flag=0; //按键扫描标志,每中断一次,扫描一次bit power_on=1;//主函数void main(){uchar key_state=0;uchar readkey;readkey=0xff;Timer0_init();Display_init(); //使之不亮while(1){if(flag==1){flag=0;flag1++;if(flag1>=4){flag1=0;}readkey=Keyscan();if (power_on==0){power_on=1;num2++;if(num2>=4){num2=0;}DisplayBUFF(readkey);}Display();}}}void Timer0() interrupt 1{// TH0=0xD8; //10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;flag++;}void Timer0_init(){// TH0=0xD8; //12MHz--10Ms产生一次中断// TL0=0xF0;// TH0=0xB1; //20Ms产生一次中断// TL0=0xE0;// TH0=0xec; //5Ms产生一次中断// TL0=0x78;TH0=0x63; //40Ms产生一次中断TL0=0xc0;EA=1;ET0=1;TR0=1;}/*==================硬件电路===============================*说明:数码管为共阴数码管,驱动方式为74hc164扫描方式为动态扫描*==========================================================*/ //梁超云改为P0.0-P0.7直接数码管的A-H,P2接数码管位选#include<reg52.h>#include"Define.h" //把常用的宏定义写成了头文件,包含进来#include"display.h"#include "74HC164.h"#include"matrixkeyscan.h"uchar segbuff[4];uchar num2=0;//sbit wela=P3^5; //位选//sbit dula=P3^4; //段选uchar code smg_duan[]= //数码管(共阴)编码0-F,全灭;{//用IO口P0,所以把A B C D E F G GP分别接到P0^0 P0^1 P0^2 P0^3 P0^4 P0^5 P0^6 PO^7 所以编码如下0X3f,0X06,0X5B,0X4f,0X66,0X6D,0X7D,0x07,0x7f,0x6F,0x77,0x7C,0x39,0x5E,/*0x79*/0 x00,0x71,0X00//用IO口P0,所以把A B C D E F G GP分别接到P0^7 P0^6 P0^5 P0^4 P0^3 P0^2 P0^1 PO^0 所以编码如下//可以把0x79或任意一个改为0x00,这样就可以按下0x79这个案件时清楚显示了//0xfC,0x0C,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,/*0x9E*/ 0X00,0x8E,0x00 //多写了0x00,代表段选全部熄灭};//uchar code smg_wei[]={0xfe,0xfd,0xfB,0xf7};//数据向左移动。
51单片机数码管显示及矩阵键盘扫描程序
51单片机数码管显示及矩阵键盘扫描程序硬件实验十一八段数码管实验一、实验任务1、在静态数码管上轮流显示数字0-9。
2、在两个4位数码管上动态显示数字0-9二、流程图及程序静态显示:流程图:程序代码:#include#define uchar unsigned chucharcodevalue[10]={0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0 x80,0x90};//0 -9数码管显示段码void delay(char x) //延时子程序{uchar i;for(i=0;i<200;i++);}main() //主函数{int i;while(1){for(i=0;i<10;i++) //显示0-9{P0=codevalue[i];delay(500); //延时1秒}}}动态显示:#include#includetab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //数码管显示数字字段unsigned char tab2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//片选字段unsigned char i,k,j,x;void delay(x); //声明延时子函数void main() //主函数{while(1){for(i=0;i<8;i++) //显示0-7{ P1=tab1[i];P0=tab2[i];delay(5); //延时}P1=tab1[8]; P0=tab2[0]; delay(5); //显示8-9P1=tab1[9]; P0=tab2[1]; delay(5);}}void delay(x) //延时函数定义{do{for(j=0;j<250;j++)for(k=0;k<250;k++);}}硬件实验十二矩阵键盘扫描显示一、实验任务1、把矩阵键盘上的按键输入的键码在静态数码管上显示出来。
实验五 矩阵式键盘按键值的数码管显示
实验五矩阵式键盘按键值的数码管显示一实验目的将矩阵键盘的键值采用LED数码管显示出来(分别考虑用动态显示、静态显示)二实验内容与具体任务描述任务1:行列式键盘接口,扫描实现LED动态显示键盘被按下。
将图中的动态显示改成静态显示。
:修改代码及图,2任务三设计的电路图与描述P1口控制键盘,P0口控制LED显示器。
四程序清单任务1:#include<reg51.h> //包含51单片机寄存器定义的头文件sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字的段码0~9.unsigned char keyval; //定义变量储存按键值/**************************************************************函数功能:数码管动态扫描延时**************************************************************/ void led_delay(void){unsigned char j;for(j=0;j<200;j++);}/************************************************************** 函数功能:按键值的数码管显示子程序**************************************************************/ void display(unsigned char k){P2=0xbf; //点亮数码管DS6P0=Tab[k/10]; //显示十位led_delay(); //动态扫描延时P2=0x7f; //点亮数码管DS7P0=Tab[k_x0010_]; //显示个位led_delay(); //动态扫描延时}/************************************************************** 函数功能:软件延时子程序**************************************************************/ void delay20ms(void){unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<60;j++);}/************************************************************** 函数功能:主函数**************************************************************/ void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%6; //定时器T0的高8位赋初值TR0=1; //启动定时器T0按键值初始化为// keyval=0x00;while(1) //无限循环{display(keyval); //调用按键值的数码管显示子程序}}/**************************************************************函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位**************************************************************/void time0_interserve(void) interrupt 1 using 1{TR0=0; //关闭定时器T0P1=0xf0; //所有行线置为低电平“0”,所有列线置为高电平“1”if((P1&0xf0)!=0xf0) //列线中有一位为低电平“0”,说明有键按下delay20ms(); //延时一段时间、软件消抖if((P1&0xf0)!=0xf0) //确实有键按下{P1=0xfe; //第一行置为低电平“0”(P1.1出低电平“0”)if(P14==0) keyval=1; //可判断是S1键被按下if(P15==0) keyval=2; //可判断是S2键被按下if(P16==0) keyval=3; //可判断是S3键被按下if(P17==0) keyval=4; //可判断是S4键被按下P1=0xfd; //第二行置为低电平“0”(P1.1出低电平“0”)if(P14==0) keyval=5; //可判断是S5键被按下if(P15==0) keyval=6; //可判断是S6键被按下if(P16==0) keyval=7; //可判断是S7键被按下if(P17==0) keyval=8; //可判断是S8键被按下P1=0xfb; //第三行置为低电平“0”(P1.2输出低电平“0”)if(P14==0) keyval=9; //可判断是S9键被按下if(P15==0) keyval=10; //可判断是S10键被按下if(P16==0) keyval=11; //可判断是S11键被按下if(P17==0) keyval=12; //可判断是S12键被按下P1=0xf7;if(P14==0) keyval=13; //可判断是S13键被按下if(P15==0) keyval=14; //可判断是S14键被按下if(P16==0) keyval=15; //可判断是S15键被按下if(P17==0) keyval=16; //可判断是S16键被按下}TR0=1; //开启定时器T0TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%6; //定时器T0的高8位赋初值}任务2:#include<reg51.h> //包含51单片机寄存器定义的头文件sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; 数字// 0~9的段码//定义变量储存按键值unsigned char keyval;/**************************************************************函数功能:数码管动态扫描延时**************************************************************//*void led_delay(void){unsigned char j;for(j=0;j<20;j++);}/**************************************************************函数功能:按键值的数码管显示子程序**************************************************************/void display(unsigned char k){DS6 点亮数码管// P2=0x3f;P0=Tab[k/10]; //显示十位//动态扫描延时//led_delay();DS7 //点亮数码管//P2=0x7f;显示个位// P3=Tab[k_x0010_];//led_delay(); //动态扫描延时}/**************************************************************函数功能:软件延时子程序**************************************************************/void delay20ms(void){unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<60;j++);}/**************************************************************函数功能:主函数**************************************************************/void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%6; //定时器T0 的高8位赋初值TR0=1; //启动定时器T0keyval=0x00; //按键值初始化为0while(1) //无限循环{display(keyval); //调用按键值的数码管显示子程序}}/**************************************************************函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位**************************************************************/void time0_interserve(void) interrupt 1 using 1{TR0=0; //关闭定时器T0P1=0xf0; //所有行线置为低电平ぜ,所有列线置为高电平if((P1&0xf0)!=0xf0) //列线中有一位为低电平ぜ,说明有键按下delay20ms(); //延时一段时间、软件消抖if((P1&0xf0)!=0xf0) //确实有键按下{P1=0xfe; //第一行置为低电平ぜ(P1.1 出低电平ぜ)if(P14==0) keyval=1; //可判断是S1键被按下if(P15==0) keyval=2; //可判断是S2键被按下if(P16==0) keyval=3; //可判断是S3键被按下if(P17==0) keyval=4; //可判断是S4键被按下P1=0xfd; //第二行置为低电平ぜ(P1.1出低电平ぜ)if(P14==0)keyval=5; //可判断是S5键被按下if(P15==0) keyval=6; //可判断是S6键被按下if(P16==0) keyval=7; //可判断是S7键被按下if(P17==0) keyval=8; //可判断是S8键被按下P1=0xfb; //第三行置为低电平ぜ(P1.2输出低电平ぜ)if(P14==0) keyval=9; //可判断是S9键被按下if(P15==0) keyval=10; //可判断是S10键被按下if(P16==0) keyval=11; //可判断是S11键被按下if(P17==0) keyval=12; //可判断是S12键被按下P1=0xf7;键被按下S13可判断是// keyval=13; if(P14==0)if(P15==0) keyval=14; //可判断是S14键被按下if(P16==0) keyval=15; //可判断是S15键被按下if(P17==0) keyval=16; //可判断是S16键被按下}TR0=1; //开启定时器T0TH0=(65536-500)/256; //定时器T0的高8位赋初值TL0=(65536-500)%6; //定时器T0的高8位赋初值}五运行结果任务1:两个LED显示器动态显示被按下键盘号。
实验8-矩阵键盘扫描实验
//查询按键键值
key = Key_Scan() ;
if( key != 0xff )
printf( "Interrupt occur... K%d is pressed!\n", key ) ;
//重新初始化IO口
rGPGCON = rGPGCON & (~((3<<12)|(3<<4))) | ((1<<12)|(1<<4)) ;//GPG6,2 set output
6.EINT19、EINT11、EINT2、EINT0中断开启
}
6.2键盘中断响应
void __irq KeyISR(void)
{
1.GPG13、GPG11、GPF2、GPF0设为input端口
2.清楚中断EINT19、EINT11、EINT2、EINT0
3.键盘扫描Key_Scan(),并在串口输出
else if( (rGPGDAT&(1<< 3)) == 0 )return 14 ;
else if( (rGPGDAT&(1<<11)) == 0 )return 13 ;
//扫描键盘第2列K11、K8、K5、K2
rGPGDAT = rGPGDAT & (~((1<<6)|(1<<2))) | (0<<6) | (1<<2) ;//GPG6 output 0;GPG2 output 1
rEXTINT0 &= ~(7|(7<<8));
rEXTINT0 |= (2|(2<<8));//set eint0,2 falling edge int
数码管显示矩阵按键键值笔记
delay10ms(1);/******单行扫描时间不能太长***********/
//temp=P1; //读入当前P1口的行状态1111 1110
//temp=temp|0xf0;//或‘|’屏蔽行P1.0~P1.3,使保留原值;P1.4~P1.7初始化高电平
{
uchar temp;
char i;/***********若定义为unsigned型,i=0即0000 0000在执行循环时,********
**********i--后变为-1,无符号后i变成1111 1111即2^8-1=256***********/
while(1)//死循环一直扫描
{
P1=0xf7;//行扫描初值,第四行P1.3,P1.0=0,P1.0~P1.0=1
temp=P1;
temp=temp|0xf0;
temp=temp>>1;
temp=temp|0xf0;
P1=temp;
}
}
}
0xc6,0xa1,0x86,0x8e};//共阳极0—F对应的段码值
void delay10ms(uint c)//延时10ms,误差0us
{
unsigned char a, b;
for (;c>0;c--)
for (b=38;b>0;b--)
for (a=130;a>0;a--);
}
void main()
下一行的行扫描值送p1口为下一行扫描做准备以上从第一行p10扫描开始初值11111110左移一位时低位自动补0难保证低位故以下从第四行p13扫描开始初值11110111通过右移保证高位值为1
矩阵键盘的键值用数码管显示
矩阵键盘的键值用数码管显示�矩阵按键项目:分别按下4*4 矩阵键盘,一共16 个按键,数码管会相应的显示1-16 不同的数字。
最终效果图:现象说明:效果图中我们看到:按 4 键,数码管上即显示04,同理按5 键数码管上即显示05。
上面显示的 2 个LED 灯是硬件上特意设计的,只要按键按下,相应的灯就亮了。
目前不用太在意。
此项目练习的目的:(1)认识矩阵键盘。
(2)了解矩阵键盘的原理。
(3)熟悉软件编程。
(4)熟悉软件的使用。
完整代码:(注意,代码中省略的部分是我们目前可以不关心的内容,在下一阶段将着重介绍,此代码已编译测试通过)#include <reg52.h> //头文件#include "digitron_drv.h" //调用数码管显示程序,现在可以把它当做一个主体#define uint unsigned int //宏定义#define uchar unsigned charuchar key_num; //矩阵键盘键值/*延时函数*/void delay(uchar x){uchar i,j;for(i = x;i > 0;i--)for(j = 100;j > 0;j--);}/*键盘键值显示*/void display(void){DigShowNumber(1,key_num%10,0); //个位除以10 取余DigShowNumber(2,key_num/10,0); //十位除以10 取整}/*键盘扫描*/void keyboard(void){uchar temp;P1=0xef; //将第1 列置位低电平,其余的为高电平temp=P1; //读取P1 口当前的状态,赋值给临时变量temp,用于后面的计算temp=temp&0x0f; //判断temp 的,低四位是否为0,if(temp!=0x0f) //如果temp 不等于0x0f,说明有按键按下{delay(10); //延时消抖temp=P1; //重新读一次P1 口数据temp=temp&0x0f;// 如果temp 仍然不等于0x0f,这次说明第1 列真的有按键按下if(temp!=0x0f){temp=P1;switch(temp) //判断按下的是该列的第几行{case 0xee: //如果读到P1 是0xee,说明是第1 列和第1 行的交叉键,即数字键7key_num=7;break;case 0xed: //如果读到P1 是0xed,说明是第1 列和第2 行的交叉键,即数字键4key_num=4;break;case 0xeb: //如果读到P1 是0xeb,说明是第1 列和第3 行的交叉键,即数字键1key_num=1;break;case 0xe7: //如果读到P1 是0xe7,说明是第1 列和第4 行的交叉键,即数字键0key_num=0;break;}}//在判断完按键序号后,还要等待按键被释放,检测释放语句如下:while(temp!=0x0f) //等待按键被释放{temp=P1;temp=temp&0x0f; //不断的读取P1 口数据,然后和0x0f“与”运算,只要结果不等于0x0f,说明按键没有被释放,直到按键被释放才退出whiledisplay();}}//以下程序意义同上,继续进行第2、3、4 列的检测P1=0xdf;temp=P1;temp=temp&0x0f;if(temp!=0x0f){delay(10);temp=P1;temp=temp&0x0f;if(temp!=0x0f){temp=P1;switch(temp){case 0xde:key_num=8;break;case 0xdd:key_num=5;break;case 0xdb:key_num=2;break;case 0xd7:key_num=10;break;}}while(temp!=0x0f){temp=P1;temp=temp&0x0f;display();}}P1=0xbf;temp=P1;temp=temp&0x0f; if(temp!=0x0f) {delay(10);temp=P1;temp=temp&0x0f; if(temp!=0x0f) {temp=P1;switch(temp){case 0xbe:key_num=9; break;case 0xbd:key_num=6; break;case 0xbb:key_num=3; break;case 0xb7:key_num=11; break;}}while(temp!=0x0f){ temp=P1;temp=temp&0x0f; display();}}P1=0x7f;temp=P1;temp=temp&0x0f; if(temp!=0x0f) {delay(10);temp=P1;temp=temp&0x0f; if(temp!=0x0f) {temp=P1;switch(temp){case 0x7e:key_num=12;break;case 0x7d:key_num=13;break;case 0x7b:key_num=14;break;case 0x77:key_num=15;break;}}while(temp!=0x0f){temp=P1;temp=temp&0x0f;display();}}}void main(void){while(1){keyboard();display();}}长见识:(1)按键实物:也称轻触开关按键之前也已经见过了,再回忆一下。
矩阵按键控制数码管显示
定时消抖 Case 0xee; P0口送0 段码 Case 0xed; P0口送1 段码 Case 0x77; …… P0口送F 段码
有键按下?
是
否
存储当前P2的状态1 Break P2=0X0F 结束 存储当前P2的状态2
返回(状态1|状态2)
返回0XFF
程序编写
//========================================== //函数名称: keyscan() //函数功能: 检测按键 //入口参数:无 //出口参数:cord_h|cord_1 //备注: //========================================== UINT8 keyscan(void) { INT8 cord_h=0; INT8 cord_1=0; P2=0xf0; if(P2!=0xf0) { delay_ms(10); if(P2!=0xf0) { cord_h=P2; P2=0x0f; cord_1=P2; return(cord_h|cord_1); } } return(0xff); }
在没有按键按下时,即DS2450 的输入量时0,当有丌 同的按键按下时,DS2450 的输入量丌同,微处理器就会 得到丌同的数字量,微处理器根据采集到的数字量可判断 按键情况。
单片机控制的“机电一体化产品”中按键的接口设计 科技咨询,李迚波
键盘扫描子程序一般包括以下内容:
1.判别有无键按下;
2.消除键盘机械抖动;
出线输出为全低电平,则列线中电平由高变低所在列为按
键所在列。
两步即可确定按键所在的行和列,从而识别出所按的键。
采用线反转法的矩阵式键盘
假设键3被按下。
第一步,P1.0~P1.3输出全为“0”,然后,读入 P1.4~P1.7线的状态,结果P1.4=0,而P1.5~P1.7均为 1,因此,第1行出现电平的变化,说明第1行有键按下; 第二步,让P1.4~P1.7输出全为“0”,然后,读入 P1.0~P1.3位,结果P1.0=0,而P1.1~P1.3均为1,因 此第4列出现电平的变化,说明第4列有键按下。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程报告课程新型单片机实践题目4*4矩阵键盘扫描显示键值二级学院班级姓名学号指导教师设计时间2011.11.15~2011.12.14常州工学院《新型单片机》设计任务书学院:专业:自动化班级:绪论 (4)第一章总体方案设计 (5)第二章系统硬件电路的设计 (6)第三章系统软件电路的设计 (8)3.1软件设计思想 (8)3.2主程序设计 (9)3.3子程序设计 (9)3.3.1 动态显示程序设计 (10)3.3.2 按键程序设计 (11)第四章调试及性能分析 (14)4.1软件调试 (14)4.2性能分析 (15)总结 (16)参考文献 (16)附录 (17)A元件清单 (17)8、瓷片电容 (17)B总原理图 (18)C程序清单 (19)C实物图 (22)绪论制作一个检测4*4 矩阵键盘的按键编码的实验,把实际按键的键值的八位编码先转换成从0000—1111 的编码,再译成数码管能识别的八位编码,在数码管动态显示时,矩阵键盘的第一行对应00—03,4*4 第二行对应04—07,第三行08—11,第四行对应12—15。
原理:1.键盘的工作原理:.键盘的工作原理:按键设置在行、列线交点上,行、列线分别连接到按键开关的两端。
行线通过上拉电阻接到+5V 电源上。
无按键按下时,行线处于高电平的状态,而当有按键按下时,行线电平与此行线相连的列线电平决定。
2.行列扫描法原理:原理:.行列扫描法原理第一步,使行线为编程的输入线,列线是输出线,拉低所有的列线,判断行线的变化,如果有按键按下,按键按下的对应行线被拉低,否则所有的行线都为高电平。
第二步,在第一步判断有键按下后,延时10ms 消除机械抖动,再次读取行值,如果此行线还处于低电平状态则进入下一步,否则返回第一步重新判断。
第三步,开始扫描按键位置,采用逐行扫描,每间隔1ms 的时间,分别拉低第一列,第二列,第三列,第四列,无论拉低哪一列其他三列都为高电平,读取行值找到按键的位置,分别把行值和列值储存在寄存器里。
第四步,从寄存器中找到行值和列值并把其合并,得到按键值,对此按键值进行编码,按照从第一行第一个一直到第四行第四个逐行进行编码,编码值从“0000” 至“1111” ,再进行译码,最后显示按键号码。
3.数码管动态扫描原理:.数码管动态扫描原理:数码管的7 个段及小数点都是由LED 块组成的,显示方式分为静态显示和动态显示两种。
数码管在静态显示方式时,其共阳管的位选信号均为低电平,四个数码管的共用段选线a、b、c、d、e、f、g、dp 分别与单片机的8 根I/O 口线相连,显示数字时只要给相应的段选线送低电平。
数码管在动态显示方式时,在某一时刻只能有一个数码管被点亮显示数字,其余的处于非选通状态,位选码端口的信号改变时,段选码端口的信号也要做相应的改变,每位显示字符停留显示的时间一般为1-5ms,利用人眼睛的视觉惯性,在数码管上就能看到相当稳定的数字显示。
第一章总体方案设计(1)总体设计要求本系统采用单片机STC89C52为数码管的控制核心,制造一种简单的4×4键盘扫描显示,能够在目测条件下两位数码管各段亮度均匀、充足,本系统具有硬件少,结构简单,容易实现,性能稳定可靠,成本低等特点。
根据设计要求,初步确定设计方案如下:1. 选择STC89C52单片机(晶振频率为f=12MHZ)作为整个系统的核心器件,对整个系统进行总体控制,发送并时时处理系统信息。
2.通过编程显示数字: 00~15。
3.当有按键按下时显示数字。
4. 扫描信号连接到单片机的P2口,显示信号连接到单片机的P0口。
5.数码管点亮过程有程序控制,通过P1.0,P1.1分别扫描点亮两位数码管完成,数码管采用直接驱动方式,共阳极接法。
(2)系统框图本文设计行、列驱动电路,显示屏电路,运用单片机的智能化,系统的将每个功能电路模块连接在一起,总体结构设计如下图1所示:图1-1系统框图第二章系统硬件电路的设计本系统的硬件电路是由单片机最小系统、按键电路、动态显示驱动电路三部分组成。
其中,单片机最小系统包括电源电路、复位电路和晶振电路构成;按键电路采用独立编码方式;显示部分使用共阳型高台扫描、高态显示信号驱动电路,完成数字效果。
总原理图见附录B。
2.1晶振电路晶振是为电路提供频率基准的元器件,通常分成有源晶振和无源晶振两个大类,无源晶振需要芯片内部有振荡器,并且晶振的信号电压根据起振电路而定,允许不同的电压,但无源晶振通常信号质量和精度较差,需要精确匹配外围电路(电感、电容、电阻等),如需更换晶振时要同时更换外围的电路。
有源晶振不需要芯片的内部振荡器,可以提供高精度的频率基准,信号质量也较无源晶振要好。
如图2-1为晶振电路。
图 2-1 晶振电路图2.2复位电路为确保微机系统中电路稳定可靠工作,复位电路是必不可少的一部分,复位电路的第一功能是上电复位。
一般微机电路正常工作需要供电电源为5V±5%,即4.75~5.25V。
由于微机电路是时序数字电路,它需要稳定的时钟信号,因此在电源上电时,只有当VCC超过4.75V低于5.25V以及晶体振荡器稳定工作时,复位信号才被撤除,微机电路开始正常工作。
如图2-2为复位电路图。
图2-2 复位电路图第三章系统软件电路的设计3.1 软件设计思想主程序先进行设置数码管闲时显示‘- -’,并启动,再进行键盘扫描载入00~15字型,然后判断一组字型是否扫描完,按不同情况进行循环调用子程序。
进入子程序后,首先设置相应的程序,反复调用显示子程序,并在显示过程中反复调用键盘扫描子程序进行延时,判断是否退出相应的方式显示子程序。
设计过程中,能很好得提高按键响应速度。
如图2所示为软件系统框图。
图3-1软件设计框图字符编码:因为该数码管为共阳型显示,可以把I/O口输出位对应每段数码管显示段,因此若要使数码管一段点亮,则该位为“0”;该段不亮,则该位为“1”。
所以对“00~15”的编码,并将编码写入数组中便于查表操作,数组定义编码程序如下:unsigned char code TAB[18]= // 共阳7节显示器(g~a)编码{ 0xbf,0xc0, 0xf9, 0xa4, 0xb0, 0x99, // 数字0-40x92, 0x82, 0xf8, 0x80, 0x98, // 数字5-90xa0, 0x83, 0xa7, 0xa1, 0x84, // 字母a-e(10-14)0x8e, 0xbf}; // 字母F(15),负号(-)3.2 主程序设计主程序里只有一个不断执行扫描函数scanner()的循环。
图3为主程序流程图。
图3-2 主程序流程图主程序如下://==主程序================================================main() // 主程序开始{ while(1) // 无穷回圈,程序一直跑scanner(); // 扫瞄键盘及显示7段显示器} // 主程序结束3.3 子程序设计子程序中包括动态显示程序、按键程序、延时程序三种,下面依次详细介绍。
3.3.1 动态显示程序设计本系统中采用依次开关断数码管静态显示方式。
当第一个位扫描完成后,就进行这样的调整动作,以产生第二位的编码。
同样的,当第二个字型扫描完成后,就进行这样的调整动作。
这个调整动作是将2个编码根据顺序填入存储器,调整存储器地址的程序流程图如图4所示。
图3-3 动态显示流程图显示子程序如下:void display(unsigned char x,unsigned char y){SEG_0=1;SEG7P=TAB[x];delay1ms(1);SEG_0=0;SEG_1=1;SEG7P=TAB[y];delay1ms(1);SEG_1=0;}3.3.2 按键程序设计系统中采用4×4矩阵键盘,在P2口接按键,P0端口控制数码管显示。
在扫描函数里,依次送出列扫描信号,而每组列扫描信号输出后,即读取按键状态,若有按下按键,则进行键值的判断与计算,再将其对应的显示信号送入显示管。
在组列扫描的最后,还要确定按键已放开,才进行下一组列扫描。
如图3-4所示为按键控制流程图。
图3-4按键流程图按键子程序如下:if(rowkey != 0) // 若有按键{ if(rowkey == 0x01) row=0; // 若第0列被按下else if(rowkey == 0x02) row=1; // 若第1列被按下else if(rowkey == 0x04) row=2; // 若第2列被按下else if(rowkey == 0x08) row=3; // 若第3列被按下kcode = 4 * col + row; // 算出按键之号码 dig1=kcode/10+1;dig0=kcode%10+1;while(rowkey != 0) // 当按钮未放开rowkey=~KEYP & 0x0f; // 再读入列键值} // if叙述(有按键时)结束第四章 调试及性能分析4.1 软件调试软件调试主要是利用计算机仿真针对程序中可能存在的错误进行检测,直到得到正确的显示结果。
按照程序流程图在KEIL C51软件中编写好程序,在PROTEUS 软件中仿真,并观察其结果,如图8、9所示。
图 4-1 KEIL 仿真图 4-2 动态显示仿真结果(按键状态)4.2 性能分析此次系统设计结果较好,七段数码管能很好的显示信息。
这个方案设计的4x4的键盘扫描显示数字,电路简单,成本较低,且较容易扩展;数码管各段亮度均匀、充足;显示数字稳定、清晰无串扰;可用静止、移入移出等多种显示方式显示图形或文字。
通过此次论文设计,让我学到了许多知道的和不知道的,都有提高,在单片机的选择、数码管的组合、键盘扫描还有各种器件的选用有了一个明确的认识,程序设计上清晰地思路,理论在实践方面的运用能力有巨大的提高。
在实践以前,由于对单片机有一定的兴趣,我通过课外学习已经接触了很多概念以及设计方式,但不专业。
但是通过这次深层次的学习、设计我有了一定的实践经验和理论基础,也让我可以进行更深的研究学习,在设计思路上,通过查阅资料了解了许多方法,认识到形式的多样性,模仿优秀作品是每个设计师必走之路,但是做设计必须要有自己的思想,人也要有自己的鲜明个性,久了就成了自己的风格,风格的养成与一个人的艺术素养和个人修养有直接关系。
要拓展自己的知识面,使自己的知识系统化知识需要接触社会的方方面面,光有书本知识是远远不够的。
要求自己在以后的学习中多想,多读,多学。
要求自己的写作水平一定要过硬。
经验的提高,让我今后在设计时更加方便、快捷,也为毕业后的就业提供了保障。