单片机课程设计 计算器

  • 格式:doc
  • 大小:377.50 KB
  • 文档页数:17

福州大学至诚学院《单片机原理及应用》课程设计题目:计算器系别:电气工程及其自动化专业:电气工程与自动化班级:姓名:学号:起止日期: 2009.12.28 ~2010.1.8指导教师:职称:课程设计任务书目录1.设计概述 (2)2.硬件电路图 (3)3.软件设计 (4)3.1 设计流图 (4)3.2程序 (5)4.结论 (13)4.1测试结果 (13)4.2遇到问题 (13)4.3如何解决 (13)5.参考文献 (15)附录:键盘内部原理图 (15)1、设计概述1.1实现功能1、通过键盘实现6位数的加减乘除,并由数码管显示结果。

2、能实现连续的加减乘除。

3、实现十进制转十六进制,并显示结果。

1.2硬件连接P3口接4*4键盘,P2口接锁存器,锁存器与数码管相连,P1口接锁存器允许端,P0.0接16进制转换开关。

具体参看电路图。

1.3设计思路1、通过键盘扫描获取键值2、判断键值进行处理3、显示结果1.4程序模块1、主程序2、十六进制显示3、四则运算4、键盘扫描程序5、显示程序2、硬件电路图3、软件设计3.1设计流程图:主要程序流程说明:主程序首先进行初始化,设定一些变量及其意义,扫描键盘,当输入有0~9数字时,通过键盘的扫描程序,将数值赋给second并在显示器上来,当输入的是加减符号的时候,通过键盘的扫面程序,赋予OP相应值,并跳到运算部分,通过判断preop的值,执行相应的运算部分,将OP的值赋给preop并把second的值赋给first。

再一次通过输入0~9的数字,再一次经过键盘的扫描程序,输出second的值,最后通过输入键盘上的等号,右键盘扫描得出相应的OP,跳到运算部分,根据程序的流程,将第一个数的跟第二个数进行简单的加、减、乘、除运算,并将结果通过显示器输出。

同理,当需要进行进制之间的转换时,输入相应的数字,通过键盘的扫描不显示在显示器上,再通过控制,进制转换开关,如果进制转换开关置0 按下,就实现了进制之间的相互转换。

3.2程序#include <reg51.h>int zixing[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77, 0x7c,0x39,0x5e,0x79,0x71};//十六进制对应字符int op=0;//用来存储+、-、*、/操作符int key=20;//按键初值int biaoji=0;//是否已计算并显示标记int pn=0;//当前按键是否为数字long result=0;//存入初值long b=0;//暂存数初值int kbscan(void); //声明键盘扫描程序void display(long temp); //声明显示程序void sljzxs(int temp); //十六进制显示程void yunsuan(void); //声明运算程序void dlms(void); //声明延时程序////////主程序////////////void main(void){int i,j=0;P0=0x01; //进制转换开关置0P1=0X00;//送数口P2=0X00;//片选口while(1){key=kbscan();//获取键值if(key==16&&biaoji==0) //如果进制转换开关置0 按下if(op==0&&pn==1){sljzxs(result);result=0;}//显示16进制数,传送值清0if(key>=0&&key<=9) //如果KEY在0到9之间,证明键盘按下的是数值 {if(result<100000)//不超过范围{result=result*10+key;}display(result);//显示数字biaoji=0;pn=1;//当前按键为数字}if(key>=10&&key<=13) //如果KEY在10到13之间,证明键盘按下的是操作符键{if(biaoji==1) op=key;//标记为1,已显示结果,只改变运算符else if(op==0&&pn==0) ;//之前无按键else if(op==0&&pn==1)//之前只按过数字键{op=key;b=result;result=0;}//记录符号,将当前数存入b中else if(op!=0&&pn==0) op=key;//之前按过数字和符号else //之前按过数字和符号及数字{yunsuan();op=key;b=result;result=0;}//输出结果,再记录符号,将当前数存入b中pn=0;}if(key==14) //如果KEY位14时,证明键盘按下的是C/ON键{P2=0xff;//清空P1=0x00;P2=0x20;//显示0P1=0x3f;op=0;//初始化result=0;b=0;biaoji=0;pn=0;}if(key==15) //如果KEY位为15时,证明键盘按下的是=键{if(biaoji==0)//如果未显示过结果if(op!=0&&pn==1)//之前按过数字和符号及数字{yunsuan();b=result;result=0;op=0;}//输出结果,将当前数存入b中,符号位及结果清0pn=0;}for(i=0;i<2000;i++);key=20;}}///////十六进制显示////////void sljzxs(int temp){int k,n,r;k=temp;//传入数值r=P2=0x20;//选定最低位dlms();if(P0==0x00)//按键{while(k>0)//直到k=0停止循环{n=k%16;//取最低位P1=zixing[n];//显示低位k=k/16;//去掉最低位r=P2=(r>>1);//左移一位P1=0x00;//移位后会再送数,所以要置0 }while(P0==0x00);//等待按键放开}biaoji=1;}//////////四则运算////////void yunsuan(void){switch(op){case 10:result=b+result;display(result);break;case 11:result=b-result;display(result);break;case 12:result=b*result;display(result);break;case 13:result=b/result;display(result);break;default:break;}biaoji=1;}/////////延时程序/////////void dlms(void){int i;for(i=0;i<250;i++){}}///////键盘扫描程序////////int kbscan(void){int p,a,n;P3=0xf0;//高4位置高,低4位置低while((P3&0xf0)!=0xf0||P0==0x00) //有按键则高位不全为1 {dlms();//延时以防干扰if((P3&0xf0)!=0xf0||P0==0x00)//确实有按键{ if(P0==0x00) return(16);p=0xfe; // p= 1111 1110从第1行开始扫描while((p&0x10)!=0)//当第5位为0时停止循环扫描,此时已扫描4行 {P3=p; //装入行扫描值if((P3&0xf0)!=0xf0)//如果此行有按键,接下去获取键值{a=P3; //P口值送置a//键码对应的数值if(a==0xd7)n=0; //4行2列为0if(a==0xeb)n=1; //3行1列为1if(a==0xdb)n=2; //3行2列为2if(a==0xbb)n=3; //3行3列为3if(a==0xed)n=4; //2行1列为4if(a==0xdd)n=5; //2行2列为5if(a==0xbd)n=6; //2行3列为6if(a==0xee)n=7; //1行1列为7if(a==0xde)n=8; //1行2列为8if(a==0xbe)n=9; //1行3列为9if(a==0x77)n=10; //4行4列为+if(a==0x7b)n=11; //3行4列为-if(a==0x7d)n=12; //2行4列为*if(a==0x7e)n=13; //1行4列为/if(a==0xe7)n=14; //4行1列为onif(a==0xb7)n=15; //4行3列为=while((P3&0xf0)!=0xf0);//等待按键放开return(n);//返回键值}else //不在第1行,左移继续扫描p=(p<<1)|0x01;//左移后低位为0,所以将其置1 }}}}///////显示程序////////void display(long temp){int r=0x20;long n,k=temp;//传入数P2=0x20;if(k>=1000000||k<-99999) //最高位大于10,显示错误E0001 {P2=0x01;r=0x01;P1=0x79;r=(r<<1);P2=r;P1=0X3f;r=(r<<1);P2=r;P1=0X3f;r=(r<<1);P2=r;P1=0X3f;r=(r<<1);P2=r;P1=0x06;}else if(k<0&&k>=-99999)//显示负数{P2=0xff;P1=0x00;//清空P2=0x01;P1=0x40;//显示负号P2=0x20;//选定第一位k=-k;//取反while(k>0)//同正数显示{n=k%10;P1=zixing[n];k=k/10;r=(r>>1);P2=r;P1=0x00;}}else//显示正数{P2=0xff;P1=0x00;//清空P2=0x20;//选定第一位if(k==0) P1=0x3f;//如果是0显示0while(k>0) //由个位开始显示数值{n=k%10;//取最低位P1=zixing[n];//显示低位k=k/10;//去掉最低位r=(r>>1);//左移一位P2=r;P1=0x00;//移位后会再送数,所以要置0}}}4、结论4.1、测试结果用Keil uV ision3编写程序,经检查成功后,通过编译链接产生*.hex文件,并用Proteus 7.5设计绘制电路图,并将生成的*.hex文件导入芯片中,进行仿真。