基于51单片机的红外数码管计算器
(完整版)基于51单片机的数码管简易计算器

基于51/52单片机的简易计算器制作11级自动化2班王栎斐宋为为闫巨东一、题目利用单片机芯片STC89C52、四位八段共阳数码管及已制作好的电路板等器件设计制作一个计算器。
二、任务与要求要求计算器能实现加减乘除四种运算具体如下1. 加法:四位整数加法计算结果若超过八位则显示计算错误2. 减法:四位整数减法计算结果若超过八位则显示计算错误3. 乘法:多位整数乘法计算结果若超过四位则显示计算错误4. 除法:整数除法5. 有清除功能三、课程设计简述总体设计思路简述1.按照系统设计的功能的要求初步确定设计系统由主控模块、显示模块、键扫描接口电路共三个模块组成。
主控芯片使用STC89C52单片机。
2.键盘电路采用4*4矩阵键盘电路。
3.显示模块采用共阳极数码管构成。
四、硬件电路五、软件编程部份#include<reg52.h>#define uchar unsigned char#define uint unsigned int//uchar code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//共阴极// 0 1 2 3 4 5 6 7 8 9 熄灭-//uchar code loc[]={0xff,0xfe,0xfd,0xfb,0xf7};//uchar code ero[]={0x79,0x50,0x5c};uchar code num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x40};//共阳极uchar code loc[]={0x00,0x80,0x40,0x20,0x10};uchar code ero[]={~0x79,~0x50,~0x5c};uint n=0,n1=0,n2=0; //赋初值uchar flag=0; //计算类型选择关键字void delay(int t);void display(int n);void error();main(){while(1){uchar temp;//第一行检测P3=0xfe;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xfe;if(temp!=0xfe){temp=P3;switch(temp){case 0xee:n1=0;n2=0;n=0;flag=0;break; //清零case 0xde:n1=10*n1+0;n=n1;break;case 0xbe: if(flag==1)n=n2+n1; //=if(flag==2)n=n2-n1;if(flag==3)n=n2*n1;if(flag==4)n=n2/n1;n1=0;break;case 0x7e: // +n2=n1;n1=0;flag=1;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第二行P3=0xfd;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xed:n1=10*n1+1;n=n1;break; //4case 0xdd:n1=10*n1+2;n=n1;break; //5case 0xbd:n1=10*n1+3;n=n1;break; //6case 0x7d:// -n2=n1;n1=0;flag=2;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第三行P3=0xfb;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xeb:n1=10*n1+4;n=n1;break;case 0xdb:n1=10*n1+5;n=n1;break;case 0xbb:n1=10*n1+6;n=n1;break;case 0x7b: // *n2=n1;n1=0;flag=3;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第四行P3=0xf7;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xe7:n1=10*n1+7;n=n1;break; //7case 0xd7:n1=10*n1+8;n=n1;break; //8case 0xb7:n1=10*n1+9;n=n1;break; //9case 0x77: // /n2=n1;n1=0;flag=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}display(n);}}//延时函数void delay(int t){int x,y;for(x=0;x<t;x++)for(y=0;y<t;y++);}//数码管显示void display(int n){//溢出处理uchar g,s,b,q;int abs;if((n>9999)||(n<-999)) error();//正数if((n>=0)&&(n<=9999)) {g=n%10;s=n/10%10;b=n/100%10;q=n/1000%10;P0=num[g];delay(5);P2=loc[4];delay(2);P2=loc[0];delay(3);if(n>=10){P0=num[s];P2=loc[3];delay(2);P2=loc[0];delay(3);}if(n>=100){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(3);}if(n>=1000){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(3);}}//负数if((n<0)&&(n>=-999)){abs=-n;g=abs%10;s=abs/10%10;b=abs/100%10;q=abs/1000%10;P0=num[g];P2=loc[4];delay(2);P2=loc[0];delay(2);if((abs/10%10>0)||(abs/100%10>0)){P0=num[s];P2=loc[3];;delay(2);P2=loc[0];delay(2);if((abs/100%10>0)){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(2);if((abs/1000%10>0)){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(2);}else{P0=num[11];P2=loc[1];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[2];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[3];delay(2);P2=loc[0];delay(2);}}}//溢出显示void error(){P2=loc[1];P0=ero[0];delay(2);P2=loc[0];delay(3);P2=loc[2];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[3];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[4];P0=ero[2];delay(2);P2=loc[0];delay(3); }。
基于51单片机的计算器设计

基于51单片机的计算器设计计算器作为一种常用的电子设备,广泛应用于各个领域。
在本文中,我们将基于51单片机来设计一个简单的计算器,并对其进行详细介绍。
一、设计目标我们所设计的计算器需要具备以下功能:1.实现基本的算术运算,包括加、减、乘、除等;2.具备显示功能,能够将输入和运算结果以数字的形式显示在液晶屏上;3.提供清零和删除功能,方便计算器的操作;4.具备较高的计算精度和稳定性。
二、硬件设计计算器的硬件设计主要包括键盘输入、液晶屏输出和计算程序控制三个部分。
1.键盘输入为了简化设计的复杂度,我们采用矩阵键盘来实现输入功能。
矩阵键盘由多个行和多个列交叉连接而成,通过扫描行和列的方式来检测键盘输入的按键信息。
2.液晶屏输出我们选择16x2字符液晶显示屏来作为计算结果的输出设备。
这种液晶屏可以显示16个字符,每个字符由5x8像素点阵组成,具备较好的显示效果。
3.计算程序控制我们将基于51单片机来编写计算器的计算程序,并通过电路连接键盘输入和液晶屏输出设备。
通过读取键盘输入的按键信息,计算程序能够判断用户输入的数字和操作符,并进行相应的计算操作。
最后,计算结果将以数字的形式显示在液晶屏上。
三、软件设计计算器的软件设计主要包括键盘扫描与输入处理、计算程序控制和液晶屏显示三个模块。
1.键盘扫描与输入处理通过循环扫描矩阵键盘的行和列,可以得到按键信息。
根据按键信息的不同,我们可以判断用户输入的数字和操作符,并将其传递给计算程序模块进行处理。
同时,我们需要对一些特殊按键(如清零和删除)做特殊处理。
2.计算程序控制计算程序模块将根据键盘输入的数字和操作符,进行相应的算术运算。
我们可以采用栈的数据结构来处理运算符和运算数,以实现复杂的算术运算。
3.液晶屏显示计算结果将以数字的形式显示在液晶屏上。
我们可以通过51单片机的GPIO口控制液晶显示屏的操作,包括写入指令和写入数据。
通过设定光标位置及写入数字数据,可以将计算结果显示在液晶屏的指定位置上。
基于51单片机的简易计算器

基于51单片机的简易计算器51单片机是一种广泛应用于嵌入式系统中的常用微控制器。
我们可以利用51单片机的强大功能和丰富的外设资源,设计一个简易计算器。
这个计算器可以进行基本的加减乘除运算,并且具备显示结果的功能。
首先,我们需要准备一块51单片机开发板,一块1602液晶显示屏模块,以及一些按键开关和电阻。
我们可以将运算器主要分为以下几个模块:数码管显示模块、键盘输入模块、运算模块和存储模块。
数码管显示模块:我们使用1602液晶显示屏模块来显示计算器的结果。
我们可以通过51单片机的IO口,将计算结果发送给液晶显示屏模块,实现结果的显示。
键盘输入模块:我们可以使用几个按键开关来实现数字和运算符的输入。
通过对按键的检测,我们可以将用户输入的数字和运算符转化为字符形式,并保存到内存中。
运算模块:我们需要根据用户输入的数字和运算符,进行相应的运算。
我们可以使用栈来实现这个功能。
栈是一种常用的数据结构,具有"先进后出"的特点。
我们可以将用户输入的数字和运算符按照一定的规则入栈,然后按照相应的顺序进行出栈和运算。
最后将结果保存到内存中。
存储模块:我们可以使用内部RAM来保存运算结果。
51单片机的内部RAM具有一定的存储能力,可以满足我们的基本需求。
在编写程序时,我们可以使用汇编语言或者C语言。
通过合理的编程,我们可以实现计算器的各项功能。
总结一下,基于51单片机的简易计算器主要包括数码管显示模块、键盘输入模块、运算模块和存储模块。
我们可以通过合理的编程,将这些模块相互配合,实现一个功能完善的计算器。
这个计算器不仅可以进行基本的加减乘除运算,还可以显示结果,方便用户进行计算。
基于51单片机红外计数器设计毕业设计(论文)

毕业设计论文红外线自动计数器的设计毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。
尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得及其它教育机构的学位或学历而使用过的材料。
对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。
作者签名:日期:指导教师签名:日期:使用授权说明本人完全了解大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。
作者签名:日期:学位论文原创性声明本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。
除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。
对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。
本人完全意识到本声明的法律后果由本人承担。
作者签名:日期:年月日学位论文版权使用授权书本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。
本人授权大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
涉密论文按学校规定处理。
作者签名:日期:年月日导师签名:日期:年月日注意事项1.设计(论文)的内容包括:1)封面(按教务处制定的标准封面格式制作)2)原创性声明3)中文摘要(300字左右)、关键词4)外文摘要、关键词5)目次页(附件不统一编入)6)论文主体部分:引言(或绪论)、正文、结论7)参考文献8)致谢9)附录(对论文支持必要时)2.论文字数要求:理工类设计(论文)正文字数不少于1万字(不包括图纸、程序清单等),文科类论文正文字数不少于1.2万字。
基于51单片机的计算器(附Proteus仿真图且程序有详细注释)

}
while(temp!=0xf0)
{
temp=P1;temp=temp&0xf0;
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
x--;
delay(3);
}
}
}
else if ((flag1==1)&&(flag2==1))
{
for(i=7;i>=px3;i--)
{
display(i,RESUIT[i]);
delay(3);
}
}
}
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xee: key=0;flag=1;break;
case 0xde: key=1;flag=1;break;
case 0xbe: key=2;flag=1;break;
{
k=k*10;
}
x1=x1+k;
}
x1=x1+DATA1[px1-1];
for(i=0;i<(px2-1);i++) //把第二个数组中的数处理成十进制数
{
k=DATA2[i];
for(j=0;j<(px2-i-1);j++)
基于51单片机的红外遥控计算器程序(附电路图,注释详细)

/*************************基于51单片机的红外遥控计算器程序****************/ /****本程序用基于TC9012遥控器可直接操作,电路图,遥控器编码图在最后****/ #include<reg52.h>#include<stdio.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned char#define lint unsigned long intsbit IR=P3^2; //红外接口标志bit irpro_ok,irok;uchar irtime,X,mir,fir; //红外用全局变量uchar IRcord[4], irdata[33];uchar DA TA1[8]={0,0,0,0,0,0,0,0}; //第一个数uchar DA TA2[8]={0,0,0,0,0,0,0,0}; //第二个数uchar RESUIT[8]={0,0,0,0,0,0,0,0}; //结果uchar px1=0,px2=0,px3=0,flag=0,flag1=0,flag2=0,flag3=0,f1=0,f2=0,f3=0,f4=0; //各全局变量uchar temp,key,fang1,fang2;lint x1=0,x2=0,y=0; //输入的数及其结果void delay(msx); //ms延时函数void Init(); //系统初始化void INTInit(); //中断初始化void Ircordpro(); //红外码值处理函数void keyscan(); //键值检测void delay(uint); //延时void DataOper(); //数据运算void DataHandle(); //数据接收void DisplayHandle(); //显示处理void display(uchar,uchar); //数码管显示函数void main(){INTInit();P0=0x00;while(1){keyscan();DataHandle();DisplayHandle();}}void INTInit(){TMOD=0x02; //定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00; //reload valueTL0=0x00; //initial valueET0=1; //开中断TR0=1;IT0 = 1; // Configure interrupt 0 for falling edge on /INT0 (P3.2)EX0 = 1; // Enable EX0 InterruptEA = 1;}void Init() //初始化,所有数据归零{uchar i;px1=0;px2=0;px3=0;flag=0;flag1=0;flag2=0;flag3=0;f1=0;f2=0;f3=0;f4=0;x1=0;x2=0;y=0;for(i=0;i<8;i++){DA TA1[i]=0;DATA2[i]=0;RESUIT[i]=0;}}void delay(msx) //msx为延时毫秒数{uint i,j;for(i=0;i<=msx;i++)for(j=0;j<=110;j++);}void display(uchar n,uchar m) //n是第几只数码管,m是显示的数字是多少{P0=P0&0x80;P0=P0|(n<<4);P0=P0|m;}void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数{irtime++;}void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数{if(fir){if(irtime<49&&irtime>=31)mir=0; //4.5ms+4.5msirdata[mir]=irtime;irtime=0;mir++;if(mir==33){irok=1;mir=0;fir=0;}}else{irtime=0;fir=1;}}void Ircordpro(void) //红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7) value=value|0x80;else value=value;if(j<8)value=value>>1;k++;}IRcord[i]=value;value=0;}if((IRcord[0]=~IRcord[1])&&(IRcord[2]=~IRcord[3])) {X=IRcord[2];fang2=1;}}void keyscan() //矩阵键值扫描子函数{if(irok){Ircordpro();irok=0;fang1=1;}if((fang1==1)&&(fang2==1)){fang1=0;fang2=0;switch(X){case 0x08: key=0;flag=1;break;case 0x01: key=1;flag=1;break;case 0x02: key=2;flag=1;break;case 0x03: key=3;flag=1;break;case 0x05: key=4;flag=1;break;case 0x06: key=5;flag=1;break;case 0x07: key=6;flag=1;break;case 0x09: key=7;flag=1;break;case 0x0A: key=8; flag=1;break;case 0x0B: key=9; flag=1;break;case 0x10: key=10;flag1=1;display(7,0);break;case 0x1A: key=11;flag1=1;display(7,0);break;case 0x16: key=12;flag2=1;Init();break;case 0x11: key=13;flag2=1;DataOper();break;case 0x15: key=14;flag1=1;display(7,0);break;case 0x19: key=15;flag1=1;display(7,0);break;}}}void DataOper(){uchar i,j,m=0;lint k=0;for(i=0;i<(px1-1);i++) //把第一个数组中的数处理成十进制数{k=DATA1[i];for(j=0;j<(px1-i-1);j++){k=k*10;}x1=x1+k;}x1=x1+DATA1[px1-1];for(i=0;i<(px2-1);i++) //把第二个数组中的数处理成十进制数{k=DATA2[i];for(j=0;j<(px2-i-1);j++){k=k*10;}x2=x2+k;}x2=x2+DATA2[px2-1];if(f1==1) y=x1+x2; //根据标志位进行运算else if(f2==1) y=x1-x2;else if(f3==1) y=x1*x2;else if(f4==1) y=x1/x2;RESUIT[0]=y/10000000; //把各位分离出来存入结果数组中RESUIT[1]=(y%10000000)/1000000;RESUIT[2]=(y%1000000)/100000;RESUIT[3]=(y%100000)/10000;RESUIT[4]=(y%10000)/1000;RESUIT[5]=(y%1000)/100;RESUIT[6]=(y%100)/10;RESUIT[7]=y%10;while(!RESUIT[m]) m++;px3=m;}void DataHandle() //把每次按键的结果记录下来,并存到适当的位置{if((key<10)&&(flag==1)&&(flag1==0)){DATA1[px1]=key;px1++;flag=0;}else if((key<10)&&(flag==1)&&(flag1==1)){DATA2[px2]=key;px2++;flag=0;}else if(flag1==1){switch(key){case 10 : f1=1;f2=0;f3=0;f4=0;break; // "+"case 11 : f1=0;f2=1;f3=0;f4=0;break; // "-"case 14 : f1=0;f2=0;f3=1;f4=0;break; // "*"case 15 : f1=0;f2=0;f3=0;f4=1;break; // "/"}}}void DisplayHandle() //将数据显示在数码管上{uchar i,x;if((flag1==0)&&(flag2==0)){x=px1;if(px1==0) display(7,0);else{for(i=0;i<px1;i++){display(8-x,DA TA1[i]);x--;delay(5);}}}else if((flag1==1)&&(flag2==0)){x=px2;if(px2==0) display(7,0);else{for(i=0;i<px2;i++){display(8-x,DA TA2[i]);x--;delay(3);}}}else if ((flag1==1)&&(flag2==1)){for(i=7;i>=px3;i--){display(i,RESUIT[i]);delay(3);}}}。
基于51单片机的计算器开题报告

主要研究内容
本系统的研究分三部分:
1.探头选择。
2.软件设计。
3.语音报警。
实验设计
8051是MCS-51系列单片机的典型产品,我们以这一代表性的机型进行系统的讲解。
8051单片机包含中央处理器、程序存储器(ROM)、数据存储器(RAM)、定时/计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线。
主要参考文献(研究综述:作者、题目、杂志、卷号、页码)
【1】杨文龙编.单片机原理及应用[M].西安:西安电子科技大学出版社,2005.
【2】杨将新,李华军编.单片机程序设计及应用[M].北京:电子工业出版社,2006.
【3】陈有卿,张晓东编.报警集成电路和报警器制作实例[M].北京:北京人民邮电出版社2001.
(2)以MCS-51单片机为核心,开发一个完整)使用Protel软件,绘制原理图、PCB,并进行元器件安装、焊接及调试检测达到预期的目的。
论文(设计)拟定提纲
第一部分:引言
第二部分:单片机计算器的设计方案
第三部分:硬件、软件的设计
第四部分:安装、调试
第五部分:结论、致谢、参考文献与附录
指导教师意见及建议
签字:年月日
课题答辩组意见及建议
组长签字:年月日
系主任意见
签字:年月日
闽西职业技术学院电气工程系
毕
业
设
计
开
题
报
告
班级:
学号:姓名:指导老师:
毕业设计开题报告
论文(设计)题目
基于单片机的红外线监控报警器设计
学生姓名
林文虎
系、专业
应用电子
指导教师
林金亮
基于51单片机计算器设计

基于51单片机计算器设计计算器是一种常见的电子设备,可以进行数学运算、数据处理等功能。
本文将基于51单片机进行计算器设计。
一、设计目标:1.实现基本的数学运算功能,如加减乘除、取余等。
2.能够进行复杂的数学运算,如平方、开方等。
3.具备记忆功能,能够存储中间结果和运算符号。
4.设置输入界面,允许用户输入数字和操作符。
5.显示运算结果和中间过程。
二、硬件系统设计:1.使用51单片机作为主控芯片,具有高集成度和处理能力。
2.连接光栅液晶显示屏,用于显示数值和操作符。
3.连接矩阵键盘,用于获取用户的输入。
4.连接电源电路,保证计算器正常运行。
三、软件系统设计:1.确定界面设计,包括数值显示区、操作符显示区和功能键区。
2.设计输入处理模块,根据用户输入获取相应的数值和操作符,并进行相应的处理。
3.设计运算模块,根据用户输入的操作符进行相应的数学运算,并将结果存储起来。
4.设计显示模块,将计算结果和中间过程显示在液晶屏上。
5.设计存储模块,用来存储中间运算结果和操作符号。
四、软件流程设计:1.系统初始化:包括设置显示模式、清零中间结果等。
2.输入处理:通过矩阵键盘输入数字和操作符,并进行相应的处理。
3.运算处理:根据用户输入的操作符,进行相应的数学运算,并将结果存储起来。
4.结果显示:将计算结果和中间过程显示在液晶屏上。
5.存储结果:将计算结果和操作符存储起来,以备后续计算。
五、测试和调试:在设计完成后,需要进行系统测试和调试,确保计算器的各项功能正常运行。
首先进行单元测试,验证各个模块的功能是否按照设计要求正确执行。
然后进行综合测试,模拟用户输入各种情况下的运算过程,检测是否能够正确进行运算并显示结果。
如果发现问题,则进行调试和修改,直到计算器满足设计要求。
六、总结:基于51单片机进行计算器设计,可以实现基本的数学运算功能,并具备记忆功能。
设计步骤包括确定硬件系统和软件系统设计,设计界面、输入处理、运算处理、显示和存储模块,进行测试和调试确保计算器功能正常运行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于51单片机的数码管应用一、设计要求1、基本要求(1)焊接一个单片机最小系统,接通电源后,至少能在四位数码管上同时显示四个非0的相同的数字。
(2)至少四位数码管能动态显示出[0,1,2,3],达到一定的效果。
(3)能用按键改变显示的数字。
2、发挥部分(1)增加数码管至8位。
(2)增加4*4矩阵按键,实现简易的8位计算器功能。
(3)增加红外接收模块,实现遥控功能。
(4)增加蜂鸣器,当有按键按下时发声。
(5)利用遥控器实现倒计时功能。
二、系统硬件配置本系统采用STC89C52RC单片机作为微控制器,分为6个模块(如下图所示):按键电路,红外感应电路,蜂鸣器响应电路,数码管显示电路,晶振以及复位电路。
下面是电路图部分: 主控单片机红外接收复位电路晶振电路按键矩阵运算低频电流产生按键消抖及计数码管显示结果蜂鸣器响应三、系统软件设计1、主程序模块主程序需要调用5 个子程序,各模块程序功能如下:●数码管显示程序:向数码的显示送数,控制系统的显示部分。
●按键消抖程序:采用检验连续四次按键状态的方式软件消抖。
●矩阵按键扫描程序:每4*4 ms扫描一次按键。
●中断设定程序:实现定时功能。
●数值计算程序:实现8位计算四则运算功能。
主程序流程见图如下:四、系统源代码Main.c部分代码如下:#include <reg52.h>sbit BUZZ = P3^3;sbit KEY_IN_1 = P2^3;sbit KEY_IN_2 = P2^2;sbit KEY_IN_3 = P2^1;sbit KEY_IN_4 = P2^0;sbit KEY_OUT_1 = P2^4;sbit KEY_OUT_2 = P2^5;sbit KEY_OUT_3 = P2^6;sbit KEY_OUT_4 = P2^7;unsigned char code LedChar[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E };unsigned char code KeyCodeMap[4][4]={{0x31,0x32,0x33,0x25},{0x34,0x35,0x36,0x26},{0x37,0x38,0x39,0x27},{0x1B,0x30,0x0D,0x28}};unsigned char KeySta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};unsigned char LedBuff[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };unsigned char T0RH = 0;unsigned char T0RL = 0;extern bit irflag;extern unsigned char ircode[4];extern void InitInfrared(void);void ConfigTimer0(unsigned int ms);void KeyDriver();void Action(unsigned char keycode);void InfraredScan();void Timer();void Starter();void main(){EA = 1;InitInfrared();ConfigTimer0(1);PT0 = 1;Timer();Starter();while(1){InfraredScan();KeyDriver();}}void Timer(){unsigned int t = 0;LedBuff[7] = LedChar[4];LedBuff[6] = LedChar[4];for(t=0;t<33000;t++);BUZZ = 0;for(t=0;t<8000;t++);BUZZ = 1;LedBuff[7] = 0xFF;LedBuff[6] = 0xFF;LedBuff[5] = LedChar[3];LedBuff[4] = LedChar[3];for(t=0;t<33000;t++);BUZZ = 0;for(t=0;t<8000;t++);BUZZ = 1;LedBuff[5] = 0xFF;LedBuff[4] = 0xFF;LedBuff[3] = LedChar[2];LedBuff[2] = LedChar[2];for(t=0;t<33000;t++);BUZZ = 0;for(t=0;t<8000;t++);BUZZ = 1;LedBuff[3] = 0xFF;LedBuff[2] = 0xFF;LedBuff[1] = LedChar[1];LedBuff[0] = LedChar[1];for(t=0;t<33000;t++);BUZZ = 0;for(t=0;t<8000;t++);BUZZ = 1;LedBuff[1] = 0xFF;LedBuff[0] = 0xFF;LedBuff[0] = LedChar[0];for(t=0;t<33000;t++);BUZZ = 0;for(t=0;t<33000;t++);BUZZ = 1;}void Starter(){LedBuff[0] = LedChar[8];LedBuff[1] = LedChar[8];LedBuff[2] = LedChar[8];LedBuff[3] = LedChar[8];LedBuff[4] = LedChar[3];LedBuff[5] = LedChar[2];LedBuff[6] = LedChar[1];LedBuff[7] = LedChar[0];void ConfigTimer0(unsigned int ms) {unsigned long tmp;tmp = 12000000 / 12;tmp = (tmp * ms) / 1000;tmp = 65536 - tmp;tmp = tmp + 13;T0RH = (unsigned char)(tmp>>8);T0RL = (unsigned char)tmp;TMOD &= 0xF0;TMOD |= 0x01;TH0 = T0RH;TL0 = T0RL;ET0 = 1;TR0 = 1;}void PrintNumber(unsigned long n) {signed char i ;unsigned char buf[8];for (i=0;i<8;i++){buf[i] = n % 10;n = n / 10;}for (i=7;i>=1;i--){if(buf[i]==0){LedBuff[i]=0xFF;}elsebreak;}for (;i>=0;i--){LedBuff[i]=LedChar[buf[i]];}}void Action(unsigned char keycode){static char ysf = 0;static long b = 0;static long a = 0;unsigned int i = 0;if ((keycode>=0x0D) && (keycode<=0x39)){BUZZ = ~BUZZ;for(i=0;i<8000;i++);BUZZ = ~BUZZ;if ((keycode>=0x30) && (keycode<=0x39)){a = (a*10)+(keycode-0x30);PrintNumber(a);}else if (keycode == 0x25){ysf = 0;b = a;a = 0;PrintNumber(a);}else if (keycode == 0x26){ysf = 1;b = a;a = 0;PrintNumber(a);}else if (keycode == 0x27){ysf = 2;b = a;a = 0;PrintNumber(a);}else if (keycode == 0x28){ysf = 3;b = a;a = 0;PrintNumber(a);}else if (keycode == 0x0D){if (ysf == 0){b += a;}else if(ysf == 1){b -= a;}else if(ysf == 2){b *= a;}else if(ysf == 3){b /= a;}a = 0;PrintNumber(b);}else if (keycode == 0x1B){a = 0;b = 0;PrintNumber(a);}}}void KeyDriver(){unsigned char i,j;static unsigned char backup [4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};for(i=0;i<4;i++){for(j=0;j<4;j++){if(backup[i][j] != KeySta[i][j]){if(backup[i][j] == 0){Action(KeyCodeMap[i][j]);}backup[i][j] = KeySta[i][j];}}}}void KeyScan(){unsigned char i ;static unsigned char keyout = 0;static unsigned char keybuf[4][4]={{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF} };keybuf[keyout][0]=(keybuf[keyout][0] << 1)|KEY_IN_1;keybuf[keyout][1]=(keybuf[keyout][1] << 1)|KEY_IN_2;keybuf[keyout][2]=(keybuf[keyout][2] << 1)|KEY_IN_3;keybuf[keyout][3]=(keybuf[keyout][3] << 1)|KEY_IN_4;for(i=0;i<4;i++){if((keybuf[keyout][i] & 0x0F)==0x00){KeySta[keyout][i]=0;}else if((keybuf[keyout][i] & 0x0F)==0x0F){KeySta[keyout][i]=1;}}keyout++;keyout = keyout & 0x03;switch (keyout){case 0: KEY_OUT_4=1;KEY_OUT_1=0;break;case 1: KEY_OUT_1=1;KEY_OUT_2=0;break;case 2: KEY_OUT_2=1;KEY_OUT_3=0;break;case 3: KEY_OUT_3=1;KEY_OUT_4=0;break;default:break;}}void LedScan(){static unsigned char i = 0;P0=0xFF;switch(i){case 0: P1=0xF7;i++;P0=LedBuff[0];break;case 1: P1=0xFB;i++;P0=LedBuff[1];break;case 2: P1=0xFD;i++;P0=LedBuff[2];break;case 3: P1=0xFE;i++;P0=LedBuff[3];break;case 4: P1=0x7F;i++;P0=LedBuff[4];break;case 5: P1=0xBF;i++;P0=LedBuff[5];break;case 6: P1=0xDF;i++;P0=LedBuff[6];break;case 7: P1=0xEF;i=0;P0=LedBuff[7];break;default: break;}}void InfraredScan(){if (irflag){if (ircode[2] == 0x0C){Action(0x31);}else if (ircode[2] == 0x18){Action(0x32);}else if (ircode[2] == 0x5E){Action(0x33);}else if (ircode[2] == 0x09){Action(0x25);}else if (ircode[2] == 0x08)Action(0x34);}else if (ircode[2] == 0x1C) {Action(0x35);}else if (ircode[2] == 0x5A) {Action(0x36);}else if (ircode[2] == 0x15) {Action(0x26);}else if (ircode[2] == 0x42) {Action(0x37);}else if (ircode[2] == 0x52) {Action(0x38);}else if (ircode[2] == 0x4A) {Action(0x39);}else if (ircode[2] == 0x0D) {Action(0x27);}else if (ircode[2] == 0x40) {Action(0x1B);}else if (ircode[2] == 0x16) {Action(0x30);}else if (ircode[2] == 0x43) {Action(0x0D);}else if (ircode[2] == 0x19)Action(0x28);}irflag = 0;}KeyScan();}void InterruptTimer() interrupt 1{TH0 = T0RH;TL0 = T0RL;LedScan();}}Infrared.c部分代码如下:#include <reg52.h> sbit IR_INPUT = P3^3;bit irflag = 0;unsigned char ircode[4];void InitInfrared(){IR_INPUT = 1;TMOD &= 0x0F;TMOD |= 0x10;TR1 = 0;ET1 = 0;IT1 = 1;EX1 = 1;}unsigned int GetHighTime(){TH1 = 0;TL1 = 0;TR1 = 1;while (IR_INPUT){if (TH1 >= 0x40){break;}}TR1 = 0;return (TH1*256 + TL1);}unsigned int GetLowTime(){TH1 = 0;TL1 = 0;TR1 = 1;while (!IR_INPUT){if (TH1 >= 0x40){break;}}TR1 = 0;return (TH1*256 + TL1);}void EXINT1_ISR() interrupt 2 {unsigned char i, j;unsigned char byt;unsigned int time;time = GetLowTime();if ((time<7833) || (time>8755)){IE1 = 0;return;}time = GetHighTime();if ((time<3686) || (time>4608)){IE1 = 0;return;}for (i=0; i<4; i++){for (j=0; j<8; j++){time = GetLowTime();if ((time<313) || (time>718)){IE1 = 0;return;}time = GetHighTime();if ((time>313) && (time<718)){byt >>= 1;}else if ((time>1345) && (time<1751)){byt >>= 1;byt |= 0x80;}else{IE1 = 0;return;}}ircode[i] = byt;}irflag = 1;IE1 = 0;}五、总结经过两周的学习与实践,本组组员成功的完成了数码管计算器的设计,最终作品的出炉离不开每个人的努力。