实验四 动态显示与矩阵式键盘实验 计科17-3BJ 李浩葳_第1页
实验四 动态显示与矩阵式键盘实验 计科17-3BJ 李浩葳_第2页
实验四 动态显示与矩阵式键盘实验 计科17-3BJ 李浩葳_第3页
实验四 动态显示与矩阵式键盘实验 计科17-3BJ 李浩葳_第4页
实验四 动态显示与矩阵式键盘实验 计科17-3BJ 李浩葳_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验四动态显示与矩阵式键盘实验一、实验内容1、动态显示。 未按键不显示,按K1键,动态显示“19491001”;按K2键,动态显示“20141210”。2、动态显示与按键识别。 矩阵式键盘键值分别是0-F,未按键不显示。每按键一次,键值在最低位显示,原键值向高位移一位。3、可控动态显示与按键识别。 矩阵式键盘键值分别是0-9,最下面一排键位功能键,左右两个键分别为“清0键”“C”,和”“回车键”“”,其它键无效。未按键不显示,每按键一次,键值在最低位显示,原键值向高位移一位。按8个键后,再按键无效。按清0键全显示“0”。按“”后全部熄灭,再按键重新开始。二、实验方案1、总体方案设计 所用硬件:AT89C52、BUTTON、AND_4、74HC573、RESPACK-8、7SEG-MPX8-CC-BLUE、电源。 外部中断有4个按键K1、K2、K3、K4,分别连接到单片机P2.0、P2.1、P2.2、P2.3引脚,按键后对应引脚为低电平,通过4与门连接到P3.2(外部中断0)。动态显示共8个共阴极数码管,采用两片74LS573进行驱动,74LS573与74LS373都是8D锁存器,只是573引脚排列更易于布线。其引脚功能为:D1-D8为数据输入端;Q1-Q8为数据输出端;LE为数据输入锁存端,LE=1数据输入D锁存器,LE=0数据不能输入D锁存器,即LE下降沿锁存当前输入数据;地址输出允许端,=0输出锁存数据,=1输出高阻。电路中,U1输出段码abcdefgdb,控制显示的字形与小数点,U2输出位选码,控制第几个数码管显示。单片机P14、P15分别连接到U1、U2的LE,连接U1、U2的。软件设计:本实验采用外部中断和矩阵键盘合为同一个程序的方式,但不能同时使用。 1、动态显示 采用中断处理按键,利用全局变量strKey控制要显示的数字串,数字串保存在二维数组str[][]中,按下K1置strKey为0利用数码管显示第0行的数字串,按下K2置strKey为1利用数码管显示第1行的数字串。 数码管的显示:T0每500us中断1次,在T0中断中点亮一个数码管。在T0中断函数中,①P1.3(OE)=1,U3、U4输出高阻;②P1.4(LE1)=1,P0口输出段码,P1.4=0,U3锁存输入的段码;③P1.5(LE2)=1,P0口输出位选码,P1.5=0,U4锁存输入的位选码;④P1.3=0,U3、U4同时输出段码和位选码,进行显示。 2、矩阵式键盘按键识别 采取行列扫描方式判断按键,利用数组N[]储存矩阵键盘的十六个按键值。以备方便使用。 在判断为相应的键值后,要利用while(P2==键值)来等待键抬起(消抖),否则可能会出现一次按键发生多次事件的情况(本次按键在按键扫描循环里再次执行到了该按键判断语句,造成错误)。主要算法1:1、全局变量的定义:ucharN[17]={0x00,0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};//矩阵键盘ucharnumCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//共阴极数码段码ucharmark[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共阴极位选码ucharint_mark; //定义位选中断次数计数变量ucharkey_mark=16; //定义按键标志ucharstr[2][8]={{2,0,1,9,1,2,0,2},{1,9,4,9,1,0,0,1}};//定义显示的两串数字ucharstrKey=2; //定义显示数字串标志ucharcount=0; //定义已显示的数字个数ucharnumStr[9]={16,16,16,16,16,16,16,16,16};//记录矩阵键盘按下的数字count用来记录当前输入了几个数字,当为8时禁止键盘输入数字,numStr用来记录已输入的数字。int_mark用来控制位选。2、定时器T0中断函数://定时器T0中断,刷新数码管voidrefresh()interrupt1{ if(int_mark==9){ //位选计数溢出清零 int_mark=1; } //外部中断0模式:动态显示 if(EX0&&strKey!=2){ display(str[strKey][int_mark-1],int_mark); } //矩阵键盘模式:可控动态显示与按键识别 elseif(!EX0){ display(numStr[int_mark],int_mark); } int_mark++; TH0=TH(500); //给定时器T1高8位赋值 TL0=TL(500); //给定时器T1低8位赋值}3、显示单个数码管函数:voiddisplay(ucharn,ucharm){ OE=1; LE1=1; out=numCode[n]; LE1=0; LE2=1; out=mark[m]; LE2=0; OE=0;}4、主函数初始化及矩阵键盘行列扫描函数局部:voidmain(){ uchartemp; uchari; TMOD=0x01; //设置定时器T0为方式1定时 IE=0x83; //总中断开,允许定时器T0、外部中断0中断 IT0=1; //选择外部中断0为跳沿触发方式 TH0=TH(500); //给定时器T0高8位赋值 TL0=TL(500); //给定时器T0低8位赋值 int_mark=0; //位选中断次数清零 TR0=1; //启动定时器T0 while(1){ if(count<9&&!EX0){ P2=0xef; for(i=0;i<=3;i++){ if(L1==0&&count<8){//第一行 key_mark=i+0; if(P2==N[1]){//数字7 N1 inputNum(7); while(P2==N[1]); } if(P2==N[2]){//数字8 N2 inputNum(8); while(P2==N[2]); } if(P2==N[3]){//数字9 N3 inputNum(9); while(P2==N[3]); } if(P2==N[4]){//无效键 N4 //inputNum(key_mark); while(P2==N[4]); } }5、数字串数组的操作://设置全部数字voidsetAllNum(ucharnum){ uinti; for(i=0;i<9;i++){numStr[i]=num;} count=8;}//清零已有数字voidsetNumZero(){ uinti; for(i=0;i<9;i++){numStr[i]=numStr[i]==16?16:0;}}//键盘输入数字voidinputNum(ucharnum){ uinti; //数字数组左移 for(i=0;i<8;i++){numStr[i]=numStr[i+1];} numStr[8]=num; count++;}2、实验原理图图2-1实验原理图3、程序流程图图2-2程序流程图三、源程序#include"reg51.h"#defineucharunsignedchar#defineuintunsignedint#defineTH(a)(65536-a)/256 //定义装入定时器高8位的时间常数#defineTL(a)(65536-a)%256 //定义装入定时器低8位的时间常数#defineoutP0//锁存器开关sbitOE=P1^3;sbitLE1=P1^4;sbitLE2=P1^5;//外部中断按键sbitK1=P2^0;sbitK2=P2^1;sbitK3=P2^2;sbitK4=P2^3;//行扫描标志sbitL1=P2^0;sbitL2=P2^1;sbitL3=P2^2;sbitL4=P2^3;ucharN[17]={0x00,0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};//矩阵键盘ucharnumCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//共阴极数码段码ucharmark[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共阴极位选码ucharint_mark; //定义位选中断次数计数变量ucharkey_mark=16; //定义按键标志ucharstr[2][8]={{2,0,1,9,1,2,0,2},{1,9,4,9,1,0,0,1}};//定义显示的两串数字ucharstrKey=2; //定义显示数字串标志ucharcount=0; //定义已显示的数字个数ucharnumStr[9]={16,16,16,16,16,16,16,16,16};//记录矩阵键盘按下的数字//延时函数voiddelay(time){ uintj; for(j=0;j<time;j++){}}//设置全部数字voidsetAllNum(ucharnum){ uinti; for(i=0;i<9;i++){ numStr[i]=num; } count=8;}//清零已有数字voidsetNumZero(){ uinti; for(i=0;i<9;i++){ numStr[i]=numStr[i]==16?16:0; }}//键盘输入数字voidinputNum(ucharnum){ uinti; //数字数组左移 for(i=0;i<8;i++){ numStr[i]=numStr[i+1]; } numStr[8]=num; count++;}//判断是否是正常按键uintisNormalKey(ucharkey){ if(key==0xee||key==0xde||key==0xbe||key==0x7e|| key==0xed||key==0xdd||key==0xbd||key==0x7d|| key==0xeb||key==0xdb||key==0xbb||key==0x7b|| key==0xe7||key==0xd7||key==0xb7||key==0x77){ return1; }else{ return0; }}voidmain(){ uchartemp; uchari; TMOD=0x01; //设置定时器T0为方式1定时 IE=0x83; //总中断开,允许定时器T0、外部中断0中断 IT0=1; //选择外部中断0为跳沿触发方式 TH0=TH(500); //给定时器T0高8位赋值 TL0=TL(500); //给定时器T0低8位赋值 int_mark=0; //位选中断次数清零 TR0=1; //启动定时器T0 while(1){ if(count<9&&!EX0){ P2=0xef; for(i=0;i<=3;i++){ if(L1==0&&count<8){//第一行 key_mark=i+0; if(P2==N[1]){//数字7 N1 inputNum(7); while(P2==N[1]); } if(P2==N[2]){//数字8 N2 inputNum(8); while(P2==N[2]); } if(P2==N[3]){//数字9 N3 inputNum(9); while(P2==N[3]); } if(P2==N[4]){//无效键 N4 //inputNum(key_mark); while(P2==N[4]); } } if(L2==0&&count<8){//第二行 key_mark=i+4; if(P2==N[5]){//数字4 N5 inputNum(4); while(P2==N[5]); } if(P2==N[6]){//数字5 N6 inputNum(5); while(P2==N[6]); } if(P2==N[7]){//数字6 N7 inputNum(6); while(P2==N[7]); } if(P2==N[8]){//无效键 N8 //inputNum(key_mark); while(P2==N[8]); } } if(L3==0&&count<8){//第三行 key_mark=i+8; if(P2==N[9]){//数字1 N9 inputNum(1); while(P2==N[9]); } if(P2==N[10]){//数字2 N10 inputNum(2); while(P2==N[10]); } if(P2==N[11]){//数字3 N11 inputNum(3); while(P2==N[11]); } if(P2==N[12]){//切换到外部中断 N12 while(P2==N[12]); strKey=2; EX0=1; //打开外部中断0 } } if(L4==0){//第四行 key_mark=i+12; if(P2==N[13]){//全部清零N13 setAllNum(0); while(P2==N[13]); } if(P2==N[14]){//数字0 N14 inputNum(0); while(P2==N[14]); } if(P2==N[15]){//局部清零N15 setNumZero(); while(P2==N[15]); } if(P2==N[16]){//回车键 N16 setAllNum(16); count=0; while(P2==N[16]); } } delay(500); temp=P2; temp=temp|0x0f; temp=temp<<1; temp=temp|0x0f; P2=temp; } } }}//显示单个数码管voiddisplay(ucharn,ucharm){ OE=1; LE1=1; out=numCode[n]; LE1=0; LE2=1; out=mark[m]; LE2=0; OE=0;}//定时器T0中断,刷新数码管voidrefresh()interrupt1{ if(int_mark==9){ //位选计数溢出清零 int_mark=1; } //外部中断0模式:动态显示 if(EX0&&strKey!=2){ display(str[strKey][int_mark-1],int_mark); } //矩阵键盘模式:可控动态显示与按键识别 elseif(!EX0){ display(numStr[int_mark],int_mark); } int_mark++; TH0=TH(500); //给定时器T1高8位赋值 TL0=TL(500); //给定时器T1低8位赋值}//外部中断0,按键控制voidkeyControl()interrupt0{ if(INT0==0){ //K1键按下,动态显示"20191202" if(K1==0){ strKey=0; } //K2键按下,动态显示"19491001" if(K2==0){ strKey=1; } //K3键按下,关闭外部中断0 if(K3==0){ while(!K3); EX0=0; } //K4键按下, if(K4==0){ } }}四、实验结果动态显示:1、开机即等待外部中断键盘按下,K1键按下动态显示"20191202"(如图4-1)图4SEQ图\*ARABIC\s11K1键按下动态

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论