电子计算器的设计_第1页
电子计算器的设计_第2页
电子计算器的设计_第3页
电子计算器的设计_第4页
电子计算器的设计_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

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

文档简介

PAGE15毕业设计(论文)中文摘要(题目):电子计算器的设计摘要:本设计是实现一个有加、减、乘、除、函数计算功能和电子时钟的多功能计算器。它的硬件主要由四部分组成,一个STC89C52单片机芯片,一块LCD1602液晶显示器,一个4*4的键盘,各种功能设置按键。采用STC89C52单片机为主要控制电路,然后使用液晶显示管显示数据,利用4*4矩阵键盘加上一些功能键完成电路的输入操作部分。电路比较简单,但是很实用方便。

软件设计采用C语言编写,实现了14位浮点数内的加、减、乘、除基本的四则运算,带有‘sin’、‘cos’、‘tan’、‘exp’、‘ln’、‘lg’、‘倒数’、‘x^y’、‘sqrt’、‘fmod’10个常用数学函数运算。此外该计算器除了计算功能以外还具有时钟的功能(采用24小时制显示),也就是说该计算器具有两个工作模式,计算模式和时钟模式,这样一个简易的计算器实现了多功能,比较实用和方便。关键词:计算器显示键盘加、减、乘、除函数毕业设计(论文)外文摘要Title:ThedesignofelectroniccalculatorsAbstract:Thisdesignistoachieveanaddition,subtraction,multiplication,division,functioncalculationfunctionandelectronicclockmulti-functioncalculator.Itshardwareismainlycomposedoffourparts,aSTC89C52microcontrollerchip,aLCD1602LCDdisplay,a4*4keyboardkeystosetvariousfunctions.UsingSTC89C52microcontrollerasthemaincontrolcircuit,andthenusetheLCDdisplaydata,use4*4matrixkeyboardfunctionkeysplussomeinputoperationofthecircuitiscompleted.Circuitisrelativelysimple,butverypracticalandconvenient.SoftwaredesignusingClanguagetoachievewithinplus14floatingpoint,subtract,multiply,anddividethefourbasicarithmetic,witha'sin','cos','tan','exp','ln','lg','countdown','x^y','sqrt','fmod'10commonlyusedmathematicalfunctions.Inaddition,thecalculatorinadditiontocomputingalsohasaclockfunction(24-hourdisplay),thatistosaythatthecalculatorhastwooperatingmodes,thecalculationmodeandclockmodesothatasimplecalculatortoachieveamulti-functional,morepracticalandconvenient.keywords:Calculatordisplaykeyboardaddsubtractmultiplyanddividefunctions目录1引言 52系统设计 52.1总体设计方案 52.2方案论证与比较 52.2.1控制部分设计方案与选择 52.2.2显示部分设计方案与选择 62.2.3输入模块设计方案与选择 62.2.4电源部分的设计方案与选择 62.3总体设计结果 63软件设计与流程 73.1系统介绍 73.2程序设计过程 83.3程序流程图 8结论 14致谢 14参考文献 15附加 15附件A 15附加B 44附件C 45附件D 47附件E 481引言当今社会,随着人们物质生活的不断提高电子产品已经走进家家户户,无论是生活和学习还是娱乐和消遣,几乎样样都离不开电子产品。计算器可谓是我们最亲密的电子伙伴之一。随着科技的发展人们对计算要求的精确度越来越高,各种不同功能的计算器已经悄悄走进我们的生活和学习中。与此同时,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用。基于单片机的电子计算器的设计不仅可以让我们进一步了解计算器的功能,而且巩固和提高了我们运用单片机进行编程设计的能力。2系统设计2.1总体设计方案本设计主要采用以下模块:控制器模块、输入模块、输出模块和电源模块;通过对控制器进行编程,时期对输入模块的信号进行处理计算,然后通过输出模块反馈给使用者计算结果。2.2方案论证与比较2.2.1控制部分设计方案与选择方案一:采用计算器专用芯片进行设计并编程实现。由于对计算器专用芯片掌握的不够,还不足以实现设计计算器,所以这个方案不可取。方案二:用单片机实现由于单片机集成于运算器电路、控制电路、中断系统、定时器/计算器以及输入/输出口电路等,所以用单片机设计控制电路省去了很多分立元器件。由于单片机是可编程芯片,并且可以运用C语言编写,对于一些复杂的计算功能,可任意调用C语言库函数,使编写程序变得非常简单。所以该课题用单片机实现,不仅功能易于实现,而且精确度较高,稳定性好,抗干扰能力强。并且由于其成本低,体积小,技术成熟和功耗小等优点,性价比也相当高。更重要的是本人经过学习,对单片机已经有较深刻的理解,因此,通过各个方面综合比较为了达到最佳效果,采用本方案来实现此设计。2.2.2显示部分设计方案与选择方案一:利用单片机外接显示驱动器驱动八位共阴极LED数码管进行显示。方案二:采用点阵字符型LCD液晶显示,可以显示数字与字母等字符。比较这两种方案,数码管显示信息量少,功耗大;利用液晶显示可以工作在低电压、低功耗下,显示界面友好、内容丰富,综合考虑,选用LCD来实现显示功能。2.2.3输入模块设计方案与选择方案一:单个IO口位连一个按钮。方案二:4*4矩阵式键盘,外加一个复用按钮,使4*4矩阵式键盘输入信息达到32个。比较这两种方案,方案一所需的IO口太多,而方案二比较节省I/O口,而且此键盘的编程方法已很成熟,所以采用采用此种矩阵式键盘最佳。2.2.4电源部分的设计方案与选择由于本次设计中单片机工作电源为5V,所以要求稳压。有以下两种方案:方案一:用固定式三角稳压管7805如下图所示:图1此部分可以输出5V电压,输入端接电容C1可以进一步滤除纹波,输出端结电容C2可以改变负载的稳态影响,使得电路稳定工作。方案二:直接用电源端用USB接口连接电脑使用。考虑实际情况,两种方案都有采用,即电路上有加电源端口用电脑提供电源,也有用7805加上蓄电池提供电源。2.3总体设计结果图2原理框图3软件设计与流程3.1系统介绍软件部分采用模块化程序设计的方法,由主控制程序、时钟子程序、计算器子程序、液晶显示部分子程序、键盘服务子程序组成,使用KeilC编程。3.2程序设计过程程序设计主要有以下几个阶段:阶段1:只有简单的加减乘除运算功能阶段2:增加了电子时钟的功能,利用计时器0的中断来计时,用CS按键再时钟和计算器间切换。阶段3:增加函数计算功能,使用shift复用键,让数字键复用时为函数输入,使用C语言数学函数库内的函数进行计算。阶段4:增加了退格功能,使用一个变量组来记录操作过程,按退格键时,根据变量组中的符号恢复除了最后输入的操作总过程,来达到退格功能。阶段5:增加了连续计算功能,让本次计算结果成为下次计算的输入。3.3程序流程图以下是程序中的子程序及简单说明,具体程序见附件1voiddelay(ucharz);延时voidwrite_com(ucharcom);lcd写命令voidwrite_date(uchardate);lcd写数据voidread_date(void);lcd读状态*voidwrite_str(uchar*str);lcd写字符串voidinit(void);液晶初始化voidshift(void);复用提示开关ucharkeyscan(void);键盘扫描voidfuwei();计算器复位voidcallerror(void);error处理voidhuifu(void);撤销键入ucharfunqian(void);函数组前符号处理*voidcullars(uchar);运算符预处理charmemory(void);输出存储数据预处理voidprocess_date(ucharpress_date);按键功能主处理voidcalculator(ucharpress_date);按键功能子处理voidsettime(void);时间设置程序voidTimer0(void);定时器溢出中断程序voidtime(void);时钟voidmain(){uchara=0;fuwei(); //计算器初始化init();//显示初始化 TH0=0x3c;//定时器0初始化TL0=0xb7;TMOD=0x1;//定时器0,方式1TR0=1;//开始计时ET0=1;EA=1;//允许溢出中断设置 form=1; //显示方式初始化 proc=0; //计算工程存储初始化while(1)//默认时钟显示{choose=1;if(choose==0) { a++; while(choose==0); a=a%2; write_com(0x01); }if(a==1)process_date(keyscan());//计算器elsetime(); //时钟}}以下是主要程序流程图

YN主程序模式键是否按下YesYN主程序模式键是否按下Yesmode+1mode%2Mode=1YesNO时钟计算器设置时间键按下设置时间键按下时钟子程序YesNO时间设置子程序RETRET显示时间计时器0中断更新时间RETI初始化NO计算器计算器键盘扫描计算处理子程序RET键盘扫描子程序扫描第一行有键入Return键入值NesYes扫描第二行有键入Return键入值NesYes扫描第三行有键入Return键入值NesYes扫描第四行有键入Return键入值NesYes扫描功能键有键入Return键入值NesYesReturnNULL(符)A运算符(符)A运算符(符)B‘=’计算结果YN运算符计算结果Y(符)A<--结果<--结果ReturnRET算结果运算符<--运算符<--结果N(符)+、-A可以是浮点数,也可以是单参数的函数。运算符可以是+-*/,也可以是双参数的函数。同(符)A计算处理子程计算处理子程退格键退格处理NesYes存储键入的符号用于退格处理和恢复操作!RETShift键复用处理NesYesRET数字键复用处理NesYesRET是M上次结果值输出处理NesYesRET是‘N’记忆值输出处理NesYesRET+或-+-处理NesYesRET*或/*/处理NesYesRET‘=‘等号处理NesYesRET复位复位处理NesYesRETRET显示器LCD1602子程序显示器LCD1602子程序写命令读地址写数据RS置0RW置0EN置1EN置0P1口输com延时延时EN置0RETRS置1RW置0EN置1EN置0P1口输date延时延时EN置0RETRS置0RW置1保存状态EN置1P1置ffH延时延时EN置0RET延时延时保存状态是否‘=’是否‘=’时间设置子程序保存输入数键盘子程序保存的输入是否错误CS是否按下RETRET显示输入数显示error更新时间NOYesNOYesNOYesRET结论这次毕业设计我学到很多很多的东西,学会了怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识,掌握了一种系统的研究方法,可以进行一些简单的编程。通过这次毕业设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。此次设计的计算器以STC89C52芯片和LCD1602为核心器件,能实现实现14位浮点数的基本运算和10~12位浮点数函数运算,具有撤销操作功能、复位功能、连续计算功能、角度输入功能。计算结果10^6~10^-6以内以f%方式显示,超过范围以e%方式显示,保留有六位有效数字,结果范围不能超过10^38~10^-38,另外具有时钟功能。致谢在本次论文设计过程中,感谢我的学校,给了我学习的机会,在学习中,老师从选题指导、论文框架到细节修改,都给予了细致的指导,提出了很多宝贵的意见与建议,老师以其严谨求实的治学态度、高度的敬业精神、兢兢业业、孜孜以求的工作作风和大胆创新的进取精神对我产生重要影响。他渊博的知识、开阔的视野和敏锐的思维给了我深深的启迪。这篇论文是在老师的精心指导和大力支持下才完成的。感谢所有授我以业的老师,没有这些年知识的积淀,我没有这么大的动力和信心完成这篇论文。感恩之余,诚恳地请各位老师对我的论文多加批评指正,使我及时完善论文的不足之处。谨以此致谢最后,我要向百忙之中抽时间对本文进行审阅的各位老师表示衷心的感谢。参考文献1杨恢先、黄辉先,《单片机原理及应用》,人民邮电出版社,2006年。2徐维祥、刘旭敏,《单片微型机原理及应用》,大连理工大学出版社,1996年。附件附件A程序#include"reg52.h"#include<stdlib.h>//包含atof(),字符串->实数#include<stdio.h>//包含sprintf(),实数->字符串#include<string.h>//包含strcpy(),字符串复制#include<math.h> //数学函数头文件#defineucharunsignedchar#defineuintunsignedintsbitchoose=P3^4;//时钟和计算器选择键/*************lcd****************/sbitlcdrs=P3^7;//LCD控制脚sbitlcdrw=P3^6;sbitlcden=P3^5;bitidataform;//lcd显示方式切换ucharidatastate;//lcd状态字存储/************计算器*************/sbitreset=P3^0;//计算器复位sbitback=P3^1;//撤销上次键入键sbitsave=P3^2;//存储键,存储有上次的结果和另外某次计算值bitidataeqsign;//按等号标志bitidatapress;//键按标志bitidatasavesign;//可存储结果标志bitidatasc; //复用标志ucharidataprocess[30],proc;//记忆计算过程,以便错误恢复和撤销输入ucharidatacontinu=0;//连续计算运算符号存储ucharidatapai[2][2];//π前有数据标志ucharidataferror;//计算检错标志 ucharidataywei; //屏幕移位ucharidatacount=0;//输入计数ucharidatacount_num=0;//组号计数ucharidataresult[15];//计算结果立存,saveucharidatasaveresult[15];//存储结果数组,sc+saveucharidatajieguo[15];//结果字符串ucharidatabdate[2][14];//待计算字符串二维组ucharidataon_symbol;//运算符号ucharidatafsym[2];//函数前符号ucharidatassym[2];//存储组前符号ucharidatabfun[2];//计算值调用函数选择ucharidatafutojiao[2];//幅度to角度变换doubleidatadate[2];//计算值双精度变量组doubleidataresultdate;//双精度结果值/***************时钟****************/sbitstime=P3^3;//时间设置键,同时用于计算器模式的复用键ucharidatams50=0;//时间调节变量ucharidatas=0;//秒ucharidatam=0;//分ucharidatah=0;//小时/******************函数声明**********************//***************延时******************/voiddelay(ucharz); /*************lcd写命令***************/voidwrite_com(ucharcom);/*************lcd写数据***************/voidwrite_date(uchardate);/*************lcd读状态***************/voidread_date(void);/*************lcd写字符串*************/voidwrite_str(uchar*str);/************液晶初始化***************/voidinit(void);/**********复用提示开关***************/voidshift(void);/**************键盘扫描***************/ucharkeyscan(void);/*************计算器复位**************/voidfuwei();/************error处理****************/voidcallerror(void);/***************撤销键入**************/voidhuifu(void);/**********函数组前符号处理***********/ucharfunqian(void);/************运算符预处理*************/voidcullars(uchar);/***********输出存储数据预处理********/charmemory(void);/***********按键功能主处理************/voidprocess_date(ucharpress_date);/***********按键功能子处理************/voidcalculator(ucharpress_date);/************时间设置程序*************/voidsettime(void);/*********定时器溢出中断程序**********/voidTimer0(void);/*****************时钟****************/voidtime(void);/************************************************//*************LCD程序****************//**************延时******************/voiddelay(ucharz) //0.2ms{ucharx,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}/**************写命令*****************/voidwrite_com(ucharcom){lcdrs=0;lcdrw=0;lcden=0;P1=com;delay(5);lcden=1;delay(5);lcden=0;}/*************写数据******************/voidwrite_date(uchardate){lcdrs=1;lcdrw=0;lcden=0;P1=date;delay(5);lcden=1;delay(5);lcden=0;}/*************读AC地址*****************/voidread_date(void){lcdrs=0;lcdrw=1; delay(5); P1=0xff;lcden=1;delay(5);state=P1;delay(5);lcden=0;delay(5); state=state&127;}/*************写字符串******************/voidwrite_str(uchar*str){ucharidatai;for(i=0;str[i]!='\0';i++)write_date(str[i]);}/***********液晶初始化***************/voidinit(void){write_com(0x38);//模式:8位数据,两行,5*7字体write_com(0x0c);//开显示,无光标write_com(0x06);//向左增量移动write_com(0x01);//清屏}/*************************************//**********复用提示开关***************/voidshift(void){if(sc==1){ read_date(); //读状态write_com(0xc0); //显示复用提示,左下角's' write_date('s'); write_com(state+0x80);//光标还回原来位置}else{read_date();write_com(0xc0); //关闭复用提示 write_date(''); write_com(state+0x80);} return;}/**************键盘扫描*************/ucharkeyscan(void)//按行扫描,有键按下则返回键符号,否则返回null{ucharidatakey0,key1,keyment=0;P2=0XFe; //行1key0=P2;key0=key0&0xf0;key1=key0;if(key0!=0xf0){delay(5);//键抖动处理P2=0XFe;key0=P2;key0=key0&0xf0;if(key0==key1){switch(key0){case0xe0:keyment='7';break;case0xd0:keyment='8';break;case0xb0:keyment='9';break;case0x70:keyment=0xfd;break;//0xfd除号在1602液晶中的代码}while(key0!=0xf0)//键释放处理{key0=P2;key0=key0&0xf0;}press=1; //键按标志置1return(keyment);}}P2=0XFd; //行2key0=P2;key0=key0&0xf0;key1=key0;if(key0!=0xf0){delay(5);P2=0XFd;key0=P2;key0=key0&0xf0;if(key0==key1){switch(key0){case0xe0:keyment='4';break;case0xd0:keyment='5';break;case0xb0:keyment='6';break;case0x70:keyment='*';break;}while(key0!=0xf0){key0=P2;key0=key0&0xf0;}press=1;return(keyment);}}P2=0XFb; //行3key0=P2;key0=key0&0xf0;key1=key0;if(key0!=0xf0){delay(5);P2=0XFb;key0=P2;key0=key0&0xf0;if(key0==key1){switch(key0){case0xe0:keyment='1';break;case0xd0:keyment='2';break;case0xb0:keyment='3';break;case0x70:keyment='-';break;}while(key0!=0xf0){key0=P2;key0=key0&0xf0;}press=1;return(keyment);}}P2=0XF7; //行4key0=P2;key0=key0&0xf0;key1=key0;if(key0!=0xf0){delay(5);P2=0XF7;key0=P2;key0=key0&0xf0;if(key0==key1){switch(key0){case0xe0:keyment='.';break;case0xd0:keyment='0';break;case0xb0:keyment='=';break;case0x70:keyment='+';break;}while(key0!=0xf0){key0=P2;key0=key0&0xf0;}press=1;return(keyment);}}if(reset==0)//复位键{keyment='';press=1;while(reset==0);//键释放return(keyment);}if(back==0) //撤销前次输入{ keyment='c';press=1;while(back==0);shift();return(keyment); }if(save==0) //储存数据键{ if(sc==0) //输出前次计算结果键 { keyment='m';press=1;while(save==0);return(keyment); } else //更新存储的数据或输出存储的数据 {keyment='n';press=1;while(save==0);return(keyment); sc=0; }} if(stime==0) //计算器时为复用功能键{ keyment='h';press=1;while(stime==0);return(keyment);}elsereturn(0); //无键按下返回null}/**************计算器复位****************/voidfuwei(){ucharidataj,i;write_com(0x0f); //lcd设置write_com(0x01);write_com(0x80);resultdate=0;for(i=0;i<2;i++) { date[i]=0; bfun[i]=0; pai[0][i]=0; pai[1][i]=0; fsym[i]=0; futojiao[i]=0;//各标志置0 for(j=0;j<14;j++) //字符数组初始化{ bdate[i][j]='\0';} }count=0; //各标志置0count_num=0; proc=0;ferror=0;eqsign=0; sc=0; savesign=0; ywei=0; press=0; on_symbol=0;}/**************error处理******************/voidcallerror(void){ucharidatai;write_com(0x01);write_com(0x80);write_str("error!");for(i=0;i<200;i++)delay(25);//持续显示1s}/*************函数组前符号处理************/ucharfunqian(void) //输入函数前检查是否错误{if((bdate[ferror][0]=='+'||bdate[ferror][0]=='-')&&count==1) { fsym[ferror]=bdate[ferror][0]; bdate[ferror][0]='\0'; bdate[ferror][1]='\0'; count=0;}if(bdate[ferror][0]!='\0'||bfun[ferror]!=0)//错误输入方式处理{callerror();huifu(); return(1);} return(0);}/****************撤销上次输入****************/voidhuifu(void){ ucharj,pro; //pro变量用于恢复procif(proc!=0)proc--; pro=proc; fuwei(); proc=pro; for(j=0;j<proc;j++) calculator(process[j]); //依次恢复之前的操作 return;}/*****************运算符预处理*****************/voidcullars(ucharcsym){ read_date(); //看第二组是否有输入 ferror++;//检错标志+1 continu=csym; //存储运算符号 futojiao[1]=0; futojiao[0]=0; if(ferror==2&&state<0x43) { callerror();huifu();return; }//第二组无输入且ferror=2,错误 if(ferror==2&&state>0x42)//第二组有输入且ferror=2,则进行连续计算 { press=1;//模拟按键‘=’和‘M+’;将本次的计算结果作为下一次计算的第一组 process_date('='); press=1; process_date('m'); ferror=1; //恢复现场,避免变化 if(continu=='^'||continu=='%') { process[proc]='h'; proc++;process[proc]=continu;proc++; } Else { process[proc]=continu;proc++; } //恢复连续计算过程 } if(continu=='%') { {write_str("f"); } Else { write_date(''); write_date(continu);//将用与连续计算的运算符号取出 ywei=0; savesign=0; count_num=1;//组标志加1 count=0; //输入计数清零 on_symbol=continu;//运算符号调用 write_com(0xc2); return; }/*************输出存储数据预处理************/charmemory(void){ if((bdate[count_num][0]=='+'||bdate[count_num][0]=='-')&&count==1)//符号处理 { ssym[count_num]=bdate[count_num][0]; bdate[count_num][0]='\0'; bdate[count_num][1]='\0'; count=0; }if(bdate[count_num][0]!='\0'){callerror();huifu();return(1);} //错误输入方式处理 return(0);}/**************按键功能主处理****************/voidprocess_date(ucharpress_date){if(form==0){write_com(0x0f);form=1;}//显示方式切换光标闪烁 if(eqsign==1&&press==1)fuwei(); //复位再次计算,记忆过程清零 press=0; if(press_date=='c'){huifu();press_date=0;} if(press_date==0)return; //无按键 process[proc]=press_date; proc++; calculator(press_date); return;}/***************按键功能子处理***************/voidcalculator(ucharpress_date){ ucharidataj=0; /*************************************/ if(press_date==('h')) //复用键 { sc=~sc; //按键功能切换,sc为1时调用函数 shift(); //显示与关闭复用提示 }/*************************************/elseif((press_date<='9'&&press_date>='0')||(press_date=='.'))//数字键处理{ savesign=0; //不可更新存储数据if(sc==0) //是否为复用sc为0,是数字{if(count<14-ywei)//未调用函数时最多输入14位数,包括小数点{ write_date(press_date);bdate[count_num][count]=press_date;//储存键值count++;}else{callerror();huifu();}//超出14位出错,恢复}elseswitch(press_date) //复用时{//排错 置函数标志符复用清零移位,此时数据只能(14-ywei)位case'7': j=funqian(); if(j==1)return; bfun[ferror]='s'; sc=0;shift(); ywei=4; write_str("sin"); break;//函数sincase'8': j=funqian(); If(j==1)return; bfun[ferror]='c'; sc=0; shift(); ywei=4; write_str("cos"); break;//函数coscase'9': j=funqian(); if(j==1)return; bfun[ferror]='t'; sc=0; shift(); ywei=4; write_str("tan"); break;//函数tan case'4': j=funqian(); if(j==1)return; bfun[ferror]='e'; sc=0; shift(); ywei=4; write_str("exp"); break;//函数exp case'5': j=funqian(); if(j==1)return; bfun[ferror]='l'; sc=0; shift(); ywei=3; write_str("ln"); break;//函数ln case'6': j=funqian(); if(j==1)return; bfun[ferror]='g'; sc=0; shift(); ywei=3; write_str("Lg"); break;//函数Lg case'1':j=funqian(); if(j==1)return; bfun[ferror]='q'; sc=0;shift(); ywei=5; write_str("sqrt"); break;//函数sqrt case'0': j=funqian(); if(j==1)return; bfun[ferror]='d'; sc=0; shift(); ywei=4; write_str("dao"); break;//函数dao(倒数) case'.': if(count==0) { pai[count_num][0]=1;count=14-ywei; } //圆周率pai处理 π前面无加权 Else { pai[count_num][1]=1;count=14; }//π前面可以有加权,后面不能跟数据 write_date(247);sc=0;shift();break; /************************2和3是双参数函数当运算符使用*************************/ case'2': //x^yx的y次方 cullars('^'); //调用运算符号处理程序 sc=0;shift(); break; case'3': //A/B的余数(双精度) cullars('%'); //调用运算符号处理程序 sc=0;shift(); break; }}/*************************************************/elseif(press_date=='m')//上次计算结果输出{ if(memory()==1)return; //输出存储数据预处理for(j=0;result[j]!='\0';j++)write_date(result[j]); //输出存储值strcpy(bdate[count_num],result); savesign=1; //此时可以更新saveresult中存储的数据 count=14;//count=14是让本组数据已确定 }/*************************************************/elseif(press_date=='n')//存储的数据更新或输出{if(savesign==1){strcpy(saveresult,result);savesign=0; //标志重新置零write_com(0x01);write_com(0x80);write_str("success!");//存储成功提示for(j=0;j<200;j++)delay(25);fuwei();}else{ if(memory()==1)return; //输出存储数据预处理for(j=0;saveresult[j]!='\0';j++) write_date(saveresult[j]); //输出存储值strcpy(bdate[count_num],saveresult); count=14;}}/****************'+','-'处理*****************/elseif((press_date=='+')||(press_date=='-')){ if(count==0)//表示输入数据的符号,此时默认数值为0{ write_date(press_date);bdate[count_num][0]=press_date; bdate[count_num][1]='0'; read_date(); //读状态 write_date('0'); write_com(state+0x80);//光标还回原来位置count=1;}else //为运算符号{ cullars(press_date);}}/****************'*','/'处理*****************/elseif(press_date==0xfd)//0xfd除号在1602液晶中的代码{ if(sc==1&&count!=0) //幅度to角度 { futojiao[count_num]=1; sc=0; shift(); write_date(0xDF); count=14; } elsecullars(press_date);} elseif(press_date=='*')//0xfd除号在1602液晶中的代码{ cullars(press_date);}/*******************'='号处理*****************/elseif(press_date=='='){write_com(0x01);//清屏write_com(0x80);write_date(press_date);//显示等号 for(j=0;j<2;j++) //两运算组的函数处理 { date[j]=atof(bdate[j]);//俩组数据,字符串->实数 if(pai[j][0]==1) {date[j]=3.1415926535897932384626433832795;} if(pai[j][1]==1) //π前缀加权计算 {date[j]=date[j]*3.1415926535897932384626433832795;} if(ssym[j]=='-') {date[j]=-date[j];} //数据前符号 if(futojiao[j]==1) {date[j]=date[j]*3.1415926535897932384626433832795/180;} if(bfun[j]!=0) //是否有调用函数,有则先函数运算 { switch(bfun[j]) { case's': date[j]=sin(date[j]);break; //函数sin case'c': date[j]=cos(date[j]);break; //函数cos case't': date[j]=tan(date[j]);break; //函数tan case'e': date[j]=exp(date[j]);break; //函数exp case'l': date[j]=log(date[j]);break; //函数ln case'g': date[j]=log10(date[j]);break;//函数Lg case'q': date[j]=sqrt(date[j]);break;//函数sqrt case'd': date[j]=1/date[j];break; //函数dao(倒数) } } if(fsym[j]=='-')date[j]=-date[j]; //函数前的符号处理 } if(ferror==0) //仅仅函数计算 {resultdate=date[0];}else //运算符号计算 { switch(on_symbol){case'+':resultdate=date[0]+date[1];break;case'-':resultdate=date[0]-date[1];break;case'*':resultdate=date[0]*date[1];break;case0xfd:resultdate=date[0]/date[1];break;/ /0xfd除号在1602液晶中的代码 case'^':resultdate=pow(date[0],date[1]);break; //pow()函数 x^y case'%':resultdate=fmod(date[0],date[1]);break; //fmod()函数求余数(双精度)} }sprintf(jieguo,"%g",resultdate);//结果实数->字符串,采用格式字符g,系统选择%f或%e输出格式,六位有效数字 if((jieguo[0]>'9'||jieguo[0]<'0')&&(jieguo[1]>'9'||jieguo[1]<'0')&&jieguo[1]!='\0'&&jieguo[1]!='.') {callerror();fuwei();return;} //错误处理,当组1或组2不合法时结果是几个英文字母提示 elsestrcpy(result,jieguo);//没错误,保存结果,结果立存M+键 for(j=0;jieguo[j]!='\0';j++)//显示结果write_date(jieguo[j]); for(;j<15;j++)write_date(''); //让光标出屏幕 eqsign=1; //按等号键标志置1} /*******************复位*****************/elseif(press_date==''){fuwei();} return;} /***********************时间设置程序*************************/voidsettime(void)//时间输入格式XX.XX.XX,X为0~9数字{uchartime1,time2=0,h1,m1,s1;init();//清屏 write_com(0xc0); write_str("inputxx.xx.xx="); write_com(0x0f);form=1; //光标闪烁 write_com(0x80);while(1){ if(choose==0){while(choose==0);write_com(0x01);return;}//按choose键退出设置time1=keyscan();if(((time1<='9'&&time1>='0')||time1=='.')&&time2<8)//输入时间处理{bdate[0][time2]=time1;write_date(time1);time2++;}if(time1=='=') //输入的时间检错{h1=(bdate[0][0]-0x30)*10+(bdate[0][1]-0x30);m1=(bdate[0][3]-0x30)*10+(bdate[0][4]-0x30);s1=(bdate[0][6]-0x30)*10+(bdate[0][7]-0x30);if(h1>23||m1>59||s1>59||bdate[0][2]!='.'||bdate[0][5]!='.'||time2!=8)//设置错误警报{callerror();return;}h=h1;m=m1;s=s1;write_com(0x01);return;}}}/*****************定时器溢出中断程序*************/voidTimer0(void)interrupt1//根据晶振频率调节th0th1ms50,实现时间校准{TH0=0x3c;//大概在50ms左(65536-X)=Yth0=(65536-X)/256tl0=(65536-X)%256 TL0=0xb7;//TL0=0xaf;加上给TO赋值和中断响应时的机器周期补偿8个机器周期ms50++;if(ms50==20){s++;ms50=0;}//秒加,1s=20ms50if(s==60){m++;s=0;}//分加,1m=60sif(m==60){h++;m=0;}//时加,1h=60mif(h==24)h=0;}/*********************时钟**********************/Voidtime(void){if(form==1){write_com(0x0c);form=0;}//显示方式切换光标不显示write_com(0x80);//time标志write_str("Time");write_com(0xc3);//h显示write_date(h/10+0x30);write_date(h%10+0x30);write

温馨提示

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

评论

0/150

提交评论