1、项目项目 电子闹钟电子闹钟 主要内容 1、项目介绍 2、相关知识 3、难点、问题分析 4、小结项目介绍 学习内容:动态、静态数码结构、特点与控制;独立、矩阵键盘结构、特点与识别。(在proteus界面上仿真电路,完成C51程序的编制与功能调试。);带8155扩展的键盘系统.24课时 任务一、0-9显示器 任务二、学号显示器 任务三、可控显示器 任务四、可设定显示器 任务五、定时报警钟 任务六、带扩展的电子钟(8155)相关知识 一、显示 1、基础知识 2、静态显示 3、动态显示 二、按键 1、键盘接口 2、独立按键 3、行列按键 三、单片机应用 1、数组 2、中断 3、定时器 四、拓展部分 5
2、1单片机常识 辅助任务难点、问题分析 1、数组 2、地址的形成 3、特殊功能寄存器(SFR)4、中断(定时器)八段LED显示块基础知识-数码显示共阴结构共阴结构共阳结构共阳结构基础知识-数码显示 共阴数码:假定 Px.0-a,Px.1-b,Px.2-c,Px.3-d,Px.4-e,Px.5-f,Px.6-g,Px.7-dp 则从Px口,送0 x3f,显示0,送0 x06,显示1 送0 x5b,显示2,送0 x4f,显示3 送0 x66,显示4,送0 x6d,显示5 送0 x7d,显示6,送0 x07,显示7 送0 x7f,显示8,送0 x6f,显示9a b cd e f Rdpa bcd e
3、f Rdpa b cd e f Rdpa bcd ef Rdpa b cd e f Rdp3.83.83.83.83.8 I/O口位选控制 I/O口段选控制 N位LED显示器基础知识-数码显示 GND/+5VGND/+5VGND/+5VGND/+5VGND/+5VI/O(1)I/O(2)I/O(3)I/O(4)四位静态LED显示器电路静态数码显示每一个数码管的显示笔画都要占用每一个数码管的显示笔画都要占用单独单独的具有锁存功能的的具有锁存功能的I/O接口。即需接口。即需N8个个I/O控制线控制线 静态显示数码管相应笔段一直处于点亮状态,静态显示数码管相应笔段一直处于点亮状态,因此功耗大,而且占
4、用硬件资源多,几乎只因此功耗大,而且占用硬件资源多,几乎只能用在显示位数极少的场合。能用在显示位数极少的场合。优点:优点:LED亮度高,可用在室外显示场合。亮度高,可用在室外显示场合。程序工作量小。程序工作量小。例如:例如:静态显示技术静态显示技术静态显示技术静态显示技术显示显示 60111 1101P2=0X7DDPabcdefg1 在在proteus上画出如下电上画出如下电路图路图.2 在在keil中编制程序中编制程序,要求要求能显示学号最后能显示学号最后4位数位数.3 运行程序运行程序,观察电路中数观察电路中数码管显示码管显示.#include#define uchar unsigned
5、 charuchar xdata*Led_D;void main()Led_D=0 x0800;*Led_D=0 x6f;/9 Led_D=0 x0900;*Led_D=0 x5b;/2 Led_D=0 x0a00;*Led_D=0 x06;/1 Led_D=0 x0b00;*Led_D=0 x3f;/0 while(1);八位LED动态显示器电路 I/O(1)DDDDDDDDI/O(2)75643210动态数码显示所有数码管的所有数码管的8个笔画段个笔画段同名端连同名端连在一起,在一起,公共端公共端各自独立。即需各自独立。即需N+8个个I/O控制线控制线 动态显示是多只数码管共享段码线,通动
6、态显示是多只数码管共享段码线,通过位选线(公共端)逐位逐位过位选线(公共端)逐位逐位分时分时进行进行扫描显示(任时刻只有扫描显示(任时刻只有一只一只点亮)。其点亮)。其优点是占用硬件资源少,功耗小。软件优点是占用硬件资源少,功耗小。软件工作量大工作量大.必须注意:扫描周期必须控制在必须注意:扫描周期必须控制在视觉停顿时间内,一般在视觉停顿时间内,一般在20ms以内,否以内,否则会出现闪烁或跳动现象。则会出现闪烁或跳动现象。最为广泛的一种显示方式。最为广泛的一种显示方式。动态显示技术动态显示技术首先扫描最后扫描动态显示技术动态显示技术1 在在proteus上画出如下电路图上画出如下电路图.2 在
7、在keil中编制程序中编制程序,要求能显示学号要求能显示学号最后最后8位数位数.3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.(注意注意:换位前先清段码换位前先清段码)#include#define uchar unsigned char void delay()uchar i;for(i=0;i100;i+);void main()while(1)P2=0Xfe;P0=0X7f;delay();/8 P2=0Xfd;P0=0X06;delay();/1 P2=0Xfb;P0=0X5b;delay();/2 P2=0Xf7;P0=0X4f;delay();/3 P2=0Xef
8、;P0=0X66;delay();/4 P2=0Xdf;P0=0X6d;delay();/5 P2=0Xbf;P0=0X7d;delay();/6 P2=0X7f;P0=0X07;delay();/7 P0=0X00;P0=0X00;P0=0X00;P0=0X00;P0=0X00;P0=0X00;P0=0X00;P0=0X00;消除拖尾消除拖尾重影现象重影现象#include#define uchar unsigned charcode uchar display=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x00
9、;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;void delay()uchar i;for(i=0;i100;i+);void main()while(1)P2=Tab7;P0=display 8;delay();/8 P2=Tab6;P0=display 1;delay();/1 P2=Tab5;P0=display 2;delay();/2 P2=Tab4;P0=display 3;delay();/3 P2=Tab3;P0=display 4;delay();/4 P2=Tab2;P0=display 5
10、;delay();/5 P2=Tab1;P0=display 6;delay();/6 P2=Tab0;P0=display 7;delay();/7 P0=display 10;P0=display 10;P0=display 10;P0=display 10;P0=display 10;P0=display 10;P0=display 10;P0=display 10;使用数组使用数组1 在在proteus上画出如下电路图上画出如下电路图.2 在在keil中编制程序中编制程序,要求能显示学要求能显示学号最后号最后8位数位数.3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.(
11、注意注意:换位前先清段码换位前先清段码)#include#define uchar unsigned charuchar xdata*Led_D=0 xc000;uchar xdata*Led_W=0 xc800;code uchar display=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x0;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;uchar led8;/数组长度要给出数组长度要给出void delay()uchar i;
12、for(i=0;i100;i+);void display()int i;for(i=0;i8;i+)*Led_D=0;*Led_W=Tabi;*Led_D=ledi;delay();void main()led0=display 0;led1=display 1;led2=display 2;led3=display 3;led4=display 4;led5=display 5;led6=display 6;led7=display 7;while(1)display();8个共阴数码管1 根据根据 如上电路图如上电路图.2 在在keil中编制程序中编制程序,要求显示时分秒要求显示时分秒.
13、3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.根据实验电路图根据实验电路图.在在keil中编制程序中编制程序,要求能显示学号要求能显示学号.辅助任务 一 设计两位数的十进制减法显示电路原理图并编制程序.二 设计电子时钟显示(时-分-秒)电路原理图并编制程序.三 设计用数码显示8只LED循环次数,显示的范围为0-99.减法运算显示#include#define uchar unsigned charuchar xdata*Led_D=0 xc000;uchar xdata*Led_W=0 xc800;code uchar display_code=0 x3f,0 x06,0 x
14、5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;bit bzie=1;uchar led8;/数组长度要给出数组长度要给出void delay()uchar i;for(i=0;i100;i+);void display()int i;for(i=0;i8;i+)*Led_D=0;*Led_W=Tabi;*Led_D=ledi;delay();void main()unsigned int X=98,Y=
15、56,Z;Z=X-Y;*Led_D=0;*Led_W=0 xff;led2=display_code10;led5=display_code11;while(1)if(bzie)led0=display_codeX/10;led1=display_codeX%10;led3=display_codeY/10;led4=display_codeY%10;led6=display_codeZ/10;led7=display_codeZ%10;bzie=0;display();X-Y=Z 显示显示#include#include#define uchar unsigned char#define L
16、ed_D XBYTE0 xc000#define Led_W XBYTE0 xc800uchar code display_code=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;uchar code Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;uchar led8;bit bzie=1;void delay()uchar i;for(i=0;i100;i+);void display()int i;for(i=0;i8;i+)Led_D
17、=0;Led_W=Tabi;Led_D=ledi;delay();void main()unsigned int X=98,Y=56,Z;Z=X-Y;Led_D=0;Led_W=0 xff;led2=display_code10;led5=display_code11;while(1)if(bzie)led0=display_codeX/10;led1=display_codeX%10;led3=display_codeY/10;led4=display_codeY%10;led6=display_codeZ/10;led7=display_codeZ%10;bzie=0;display();
18、X-Y=Z 显示显示#include#define uchar unsigned charuchar xdata*Led_D=0 xc000;uchar xdata*Led_W=0 xc800;code uchar display_code=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;bit bzie=1;int i;uchar led8;void display()in
19、terrupt 1 TH0=(256*256-1*f/12000)/256;TL0=(256*256-1*f/12000)%256;if(i=8)i=0;*Led_D=0;*Led_W=Tabi;*Led_D=ledi;i+;void main()unsigned int X=98,Y=56,Z;Z=X-Y;TH0=(256*256-1*f/12000)/256;TL0=(256*256-1*f/12000)%256;/1ms 时间间隔不能长i=0;IE=0 x82;TMOD=0 x01;TCON=0 x10;led2=display_code10;led5=display_code11;wh
20、ile(1)if(bzie)led0=display_codeX/10;led1=display_codeX%10;led3=display_codeY/10;led4=display_codeY%10;led6=display_codeZ/10;led7=display_codeZ%10;bzie=0;X-Y=Z 显示显示时钟显示#include#define uchar unsigned charuchar xdata*Led_D=0 xc000;uchar xdata*Led_W=0 xc800;code uchar display_code=0 x3f,0 x06,0 x5b,0 x4
21、f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;bit bzie=1;unsigned int x=0;uchar led8;/数组长度要给出数组长度要给出void delay()uchar i;for(i=0;i100;i+);if(+x)=1000)x=0;bzie=1;void display()int i;for(i=0;i=60)sec=0;if(+mit)=60)mit=0;if(+hour)=24)hour=0;le
22、d0=display_codehour/10;led1=display_codehour%10;led3=display_codemit/10;led4=display_codemit%10;led6=display_codesec/10;led7=display_codesec%10;bzie=0;display();时分秒时分秒 显示显示#include#include#define uchar unsigned char#define Led_D XBYTE0 xc000#define Led_W XBYTE0 xc800uchar code display_code=0 x3f,0 x
23、06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;uchar code Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;uchar led8;bit bzie=1;unsigned int x=0;void delay()uchar i;for(i=0;i100;i+);if(+x)=1000)x=0;bzie=1;void display()int i;for(i=0;i=60)sec=0;if(+mit)=60)mit=0;if(+hour)=24)hour=
24、0;led0=display_codehour/10;led1=display_codehour%10;led3=display_codemit/10;led4=display_codemit%10;led6=display_codesec/10;led7=display_codesec%10;bzie=0;display();时分秒显示时分秒显示#include#define uchar unsigned charuchar xdata*Led_D=0 xc000;uchar xdata*Led_W=0 xc800;code uchar display_code=0 x3f,0 x06,0
25、x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;code uchar Tab=0 x7f,0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe;bit bzie=1;int i;uchar led8;unsigned int x=0;void display()interrupt 1 TH0=(256*256-1*f/12000)/256;TL0=(256*256-1*f/12000)%256;if(i=8)i=0;*Led_D=0;*Led_W=Tabi;*Led_D=ledi;i+;if(+x
26、)=1000)x=0;bzie=1;void main()unsigned int hour=0,mit=0,sec=0;TH0=(256*256-1*f/12000)/256;TL0=(256*256-1*f/12000)%256;/1ms,时间间隔不能长i=0;IE=0 x82;TMOD=0 x01;TCON=0 x10;led2=display_code10;led5=display_code10;while(1)if(bzie)if(+sec)=60)sec=0;if(+mit)=60)mit=0;if(+hour)=24)hour=0;led0=display_codehour/10
27、;led1=display_codehour%10;led3=display_codemit/10;led4=display_codemit%10;led6=display_codesec/10;led7=display_codesec%10;bzie=0;时分秒显示时分秒显示任务一任务一:根据实验电路图根据实验电路图.在在keil中编制程序中编制程序,实现实现数码管显示数码管显示LED循环循环点亮的次数点亮的次数.#include#define uchar unsigned charcode uchar display_code=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0
28、 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x48;code uchar Tab=0 x01,0 x02;unsigned int i;uchar led2;void display()interrupt 1 TH0=0 xf0;TL0=0 xa0;if(i=2)i=0;P0=0;P2=Tabi;P0=ledi;i+;void main()uchar n;unsigned int m,j,k;TH0=0 xf0;TL0=0 xa0;i=0;IE=0 x82;TMOD=0 x01;TCON=0 x10;while(1)for(j=0;j=99;j+)n=0 x01;
29、for(m=0;m8;m+)P3=n;n=1;for(k=0;k10000;k+);led0=display_codej/10;led1=display_codej%10;xdata unsigned char OUTBIT _at_ 0 xc800;/位控制口位控制口xdata unsigned char OUTSEG _at_ 0 xc000;/段控制口段控制口unsigned char LEDBuf18,LEDBuf28;/显示缓冲显示缓冲 LEDBuf1为原码为原码,LEDBuf2中为段码中为段码 code unsigned char LEDW8=0 xfe,0 xfd,0 xfb,0
30、 xf7,0 xef,0 xdf,0 xbf,0 x7f;code unsigned char LEDMAP=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;void Delay(unsigned char CNT)unsigned char i;while(CNT-!=0)for(i=100;i!=0;i-);void DisplayLED()unsigned char i,Pos;for(i=0;i 8;i+)OUTBIT=0 xff;/关所有八段
31、管关所有八段管 Pos=LEDWi;OUTSEG=LEDBuf2i;OUTBIT=Pos;/显示一位八段管显示一位八段管 Delay(1);/显示下一位显示下一位 OUTBIT=0 xff;/关所有八段管关所有八段管void main()unsigned char i=0,j;while(1)LEDBuf20=LEDMAPLEDBuf10&0 x0f;LEDBuf21=LEDMAP LEDBuf11&0 x0f;LEDBuf22=LEDMAPLEDBuf12&0 x0f;LEDBuf23=LEDMAPLEDBuf13&0 x0f;LEDBuf24=LEDMAPLEDBuf14&0 x0f;LE
32、DBuf25=LEDMAPLEDBuf15&0 x0f;LEDBuf26=LEDMAPLEDBuf16&0 x0f;LEDBuf27=LEDMAPLEDBuf17&0 x0f;DisplayLED();八位数码显示参考程序八位数码显示参考程序LED点阵点阵结构结构新任务新任务:根据实验电路图根据实验电路图.在在keil中中编制程序编制程序,实现实现LED点阵显点阵显示,循环显示姓名字母示,循环显示姓名字母.#include#define uchar unsigned char sbit key1=P10;sbit key2=P12;sbit key3=P14;sbit key4=P16;uch
33、ar nkey1=0,nkey2=0,nkey3=0,nkey4=0,nkey;code uchar dis=0 x3F,0 x06,0 x5B,0 x4F,0 x66,0 x6D,0 x7D,0 x07,0 x7F,0 x6F;code uchar wie=0 x01,0 x02;uchar led2;void delay()uchar k;for(k=0;k250;k+);void key()interrupt 0if(key1=0)nkey1+;nkey=nkey1;if(key2=0)nkey2+;nkey=nkey2;if(key3=0)nkey3+;nkey=nkey3;if(ke
34、y4=0)nkey4+;nkey=nkey4;led1=nkey/10;led0=nkey%10;void main()uchar ii;IE=0X81;IP=0X0;TCON=0X01;while(1)for(ii=0;ii2;ii+)P0=0 x00;P2=wieii;P0=disledii;delay();#include#define uchar unsigned char sbit key1=P10;sbit key2=P12;sbit key3=P14;sbit key4=P16;sbit kled1=P34;sbit kled2=P35;sbit kled3=P36;sbit k
35、led4=P37;uchar nkey1=0,nkey2=0,nkey3=0,nkey4=0,nkey;code uchar dis=0 x3F,0 x06,0 x5B,0 x4F,0 x66,0 x6D,0 x7D,0 x07,0 x7F,0 x6F;code uchar wie=0 x01,0 x02;uchar led2;void delay()uchar k;for(k=0;k250;k+);void key()interrupt 0 kled1=1;kled2=1;kled3=1;kled4=1;if(key1=0)nkey1+;nkey=nkey1;kled1=0;if(key2=
36、0)nkey2+;nkey=nkey2;kled2=0;if(key3=0)nkey3+;nkey=nkey3;kled3=0;if(key4=0)nkey4+;nkey=nkey4;kled4=0;led1=nkey/10;led0=nkey%10;void main()uchar ii;IE=0X81;IP=0X0;TCON=0X01;while(1)for(ii=0;ii2;ii+)P0=0 x00;P2=wieii;P0=disledii;delay();1 在在proteus上画出如下电路图上画出如下电路图.2 在在keil中编制程序中编制程序,要求能对应要求能对应LED显示按键按下
37、的次数值显示按键按下的次数值(累计累计).Key1Key2key3123#include#define uchar unsigned charuchar displayD2;/显示段码缓冲单元uchar code displayW=0 x01,0 x02;/显示位码uchar code displayB=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;sbit led1=P10;sbit led2=P11;sbit led3=P12;/LED显示uchar i=0,key=0;uchar NUMW=0,NUMC=0,NUM
38、G=0;/计数 初值 void disW()interrupt 0 using 1 /led1 if(+NUMW)=100)NUMW=0;key=0 x01;void disG()interrupt 2 using 1 /led2 if(+NUMC)=100)NUMC=0;key=0 x02;void disC()interrupt 3 using 1 /led3 if(+NUMG)=100)NUMG=0;TH1=0 xff;TL1=0 xff;key=0 x03;void displlay()interrupt 1 using 2 /显示程序 TH0=(65536-10*11059/12)/
39、256;/10MS TL0=(65536-10*11059/12)%256;P0=0 x00;P2=displayWi;P0=displayDi;if(+i=2)i=0;void main()IE=0 x8f;TMOD=0 x51;TH1=0 xff;TL1=0 xff;IP=0 x02;TH0=(65536-10*11059/12)/256;/10ms TL0=(65536-10*11059/12)%256;TCON=0 x55;/下降沿触发 0 x50 电平触发 led1=0;led2=0;led3=0;P2=0 x0ff;displayD0=0 x3f;displayD1=0 x3f;w
40、hile(1)switch(key)case 0 x01:displayD1=displayBNUMW/10;displayD0=displayBNUMW%10;led1=1;led2=0;led3=0;break;case 0 x02:displayD1=displayBNUMC/10;displayD0=displayBNUMC%10;led1=0;led2=1;led3=0;break;case 0 x03:displayD1=displayBNUMG/10;displayD0=displayBNUMG%10;led1=0;led2=0;led3=1;break;default:brea
41、k;数组概念 数组的本质则是一系列的数据元素(变量)。数组的本质则是一系列的数据元素(变量)。该数组中若干个元素必须是同一个类的。对象数组的定义、赋值和引用和普通数组相同。1.数组的定义数组的定义数组定义格式如下:.其中,指出该数组元素是属于该类的对象,方括号内的给出某一维的元素个数。一维对象数组只有一个方括号,二维对象数组要有两个方括号,等等,例如:data dates7;表明dates是一维对象数组名,该数组有7个元素,每个元素都是类data的对象。2.对象数组的赋值对象数组的赋值对象数组能够被赋初值,也能在程序中被赋值(除 code类)。例如 code add3=0 x3f,0 x06,
42、0 x4f;数组应用(查表程序)code unsigned char LEDMAP=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;unsigned char i;unsigned char LED;.LED=LEDMAPi;/i取值0-15或16进制0-F键盘接口技术1、键盘消抖、键盘消抖2、键盘形式、键盘形式软件去抖动软件去抖动前沿抖动稳定后沿抖动 按键抖动信号波形键盘消抖键盘消抖即检测出键闭合后执行一个即检测出键闭合后执行一个延时程序延时程序,产
43、生产生5ms10ms的延时的延时,让前沿抖动消失后让前沿抖动消失后再一次检测键的状态再一次检测键的状态,如果如果仍保持闭合状态电平仍保持闭合状态电平,则确则确认为真正有键按下。认为真正有键按下。键盘消抖键盘消抖 硬件消抖硬件消抖:如RC滤波电路2RV5+1R1V2V图 5-3 滤波延时消抖电路SiVoV(D i)(D i)键盘消抖键盘消抖 硬件消抖硬件消抖:如双稳态电路:RS触发器为常用的硬件消抖电路。CD键盘的形式有以下两种:独立式键盘行列式键盘 2、键盘的形式独立式键盘结构独立式键盘结构每一个按键的电路是独立的,占用每一个按键的电路是独立的,占用一条一条I/O数据线数据线1 在在prote
44、us上画出如下电路图上画出如下电路图.2 在在keil中编制程序中编制程序,要求能显示按键数值要求能显示按键数值.3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.if(P1=P1|0 x55)!=0 xff)delay();if(P1=P1|0 x55)=0 xfd)*pled=0 x06;if(P1=P1|0 x55)=0 xf7)*pled=0 x5b;if(P1=P1|0 x55)=0 xdf)*pled=0 x4f;if(P1=P1|0 x55)=0 x7f)*pled=0 x66;1 在在proteus上画出如下电路图上画出如下电路图.2 在在keil中编制程序中编制
45、程序,要求能显示按键数要求能显示按键数值值.3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.行列式行列式键盘结构键盘结构每一个按键的电路是由行列组成,每一个按键占用每一个按键的电路是由行列组成,每一个按键占用两条两条I/O数据线。数据线。当键盘按下时,相应的行列线呈现当键盘按下时,相应的行列线呈现短路短路。求键的位置(行、列)若若D1=0,则,则D5=0假定假定 S6 按下按下求键的位置(行、列)假定假定 S7 按下按下若若D1=0,则,则D5=?只有只有D2=0,则,则D5=0 扫描原理:首先确定是否有键闭合(消抖,再判)然后逐一扫描以进一步确定是哪一键闭合 (用编码方式,找
46、出唯一)以44键盘为例:(1 1)判断是否有键按下:使列线)判断是否有键按下:使列线D0D0D3D3都输都输出出0 0,检测行线,检测行线D4D4D7D7的电平。如果的电平。如果D4D4D7D7上上的电平全为高,则表示没有键被按下。如果的电平全为高,则表示没有键被按下。如果D4D4D7D7上的电平不全为高,则表示有键被按下。上的电平不全为高,则表示有键被按下。(2 2)扫面按键键值:如果有键闭合,进行)扫面按键键值:如果有键闭合,进行逐列扫描,找出闭合键的键号。逐列扫描,找出闭合键的键号。行列式键盘的工作原理unsigned char I;全局变量全局变量void Scankey()unsig
47、ned char N,m,L;P1=P1&0Xf0;/列全送低电平列全送低电平 delay(1);/等低电平稳定等低电平稳定 while(P1|0X0f)!=0Xff)delay(2);/有按键,延时有按键,延时 if(P1|0X0f)!=0Xff)/再判,有按键再判,有按键 L=0X01;/第一列第一列 for(m=0;m4;m+)/共四列共四列 P1=L;/送送m列零列零 delay(1);if(N=P1&0Xf0)!=0Xf0)I=N|L;return;/返回行列信息返回行列信息 L0;x-)for(y=110;y0;y-);void scanner()unchar col,row,sc
48、an,keyin,kcode;scan=0 xef;for(col=0;col4;col+)P3=scan;P2=disp;keyin=rowkey();if(keyin!=0)for(row=0;row4;row+)if(keyin=(0 x01row)/判断列号判断列号 kcode=row+4*col;/求出具体的按键号求出具体的按键号 disp=tablekcode;P2=disp;/显示显示 break;while(rowkey()!=0);delay(10);scan=(scan1)|0 x01;/这个扫描信号用来判断行号这个扫描信号用来判断行号 void main()while(1
49、)scanner();左边程序为行列键盘、数码显示程序。要求:分析程序功能,画出原理图,调试,并修正程序。1 在在proteus上画出如下电路图上画出如下电路图.2 在在keil中编制程序中编制程序,要求能显示按键数值要求能显示按键数值.3 运行程序运行程序,观察电路中数码管显示观察电路中数码管显示.提示提示逐列扫描参考:逐列扫描参考:P1_4=0;P1_5=1;P1_6=1;P1_7=1;if(P1_0=0)P0=0X3F ;/KEY0 if(P1_1=0)P0=0X 06;/KEY1 if(P1_2=0)P0=0X.;/KEY2 if(P1_3=0)P0=0X.;/KEY3P1_4=1;P
50、1_5=0;P1_6=1;P1_7=1;if(P1_0=0)P0=0X.;/KEY4 if(P1_1=0)P0=0X.;/KEY5 if(P1_2=0)P0=0X.;/KEY6 if(P1_3=0)P0=0X.;/KEY7P1_4=1;P1_5=1;P1_6=0;P1_7=1;if(P1_0=0)P0=0X.;/KEY8 if(P1_1=0)P0=0X.;/KEY9 if(P1_2=0)P0=0X.;/KEY-if(P1_3=0)P0=0X.;/KEY+P1_4=1;P1_5=1;P1_6=1;P1_7=0;if(P1_0=0)P0=0X.;/KEY=if(P1_1=0)P0=0X.;/KEY