科学计算器设计报告51单片机.docx
- 文档编号:29955886
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:17
- 大小:63.65KB
科学计算器设计报告51单片机.docx
《科学计算器设计报告51单片机.docx》由会员分享,可在线阅读,更多相关《科学计算器设计报告51单片机.docx(17页珍藏版)》请在冰豆网上搜索。
科学计算器设计报告51单片机
单片机课程设计报告
(多功能计算器)
班级:
姓名:
学号:
指导老师:
1、内容摘要
利用89c51作为主控器设计一个四则运算的计算器。
首先通过在图书馆和网上查找有关设计计算器的资料,大概了解设计计算器需要哪几个模块,熟悉Keil和Proteus两个软件的用法,以及它们的联调,完成计算器的程序设计和仿真,然后就是进实验室进行计算器电路板的焊接,最后就是将程序下载到单片机芯片中,系统联调,直到得出结果。
2、设计内容及要求
用单片机设计计算器,要求可以进行加、减、乘、除运算。
3、系统方案设计,画出系统框图
四、画出完整的电路图,并说明电路的工作原理
电路图说明:
(1)键盘的列扫描接单片机P2口的低4位,行扫描接单片机P1口的低4位;
(2)数码管的段选通过单片机的P0口接74LS244来驱动,数码管的位选接单片机的P2口;
(3)发光二极管电路用来说明电路是否上电;
(4)晶振电路为单片机提供时钟频率;
(5)复位电路为单片机提供复位信号。
计算器的功能实现:
(1)此计算器适应于不大于八位整数的四则混合运算,若单个数大于八位或者结果大于八位(溢出)则显示“Chucuo”。
(2)如果在还没有按数字之前按了一个符号键或者等号则显示“Chucuo”。
(3)若接连按了几个运算符键,实际上进行的运算是最后一次按的运算键。
(4)可以显示负数、小数。
(5)此计算器不可实现连乘、连加、连减、连除。
4、软件仿真,根据系统硬件图编写系统程序并调试
#include
#include
#defineucharunsignedchar
#defineulongunsignedlong
uchararray[8]={0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
uchararray1[8]={0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
uchara;
ulongnum1=0,num2=0;
sbitP10=P1^0;
sbitP11=P1^1;
sbitP12=P1^2;
sbitP13=P1^3;
sbitF1=PSW^1;//定义一个标志位,F0在头文件里已定义
voiddisplayljy(void);//声明"显示"子函数
voidinkeylove(void);//声明"判断按下的是什么键"子函数
voidiskeyyou(void);//声明"判断是否有键按下"子函数
voidbian1(void);//声明"将uchar型变量转化为ulong型变量"子函数
voidbian2(void);//声明"将ulong型变量转化为uchar型变量"子函数
voidjia(void);//声明"加运算"子函数
voidjian(void);//声明"减运算"子函数
voidcheng(void);//声明"乘运算"子函数
voidchu(void);//声明"除运算"子函数
voiderror(void);//声明"出错显示"子函数
voidmain()
{ucharr7=0x00,i;
while
(1)
{displayljy();
inkeylove();
if(a!
=0xff)//如果有键输入,继续往下执行,否则从新开始
{if(a==0x0f)//如果输入的是"清除"键,将显示器清屏,同时清存放运算符号的单元
{r7=0x00;
for(i=0;i<8;i++)
{array[i]=0x10;
array1[i]=0x10;
}
}
elseif(a==0x0e)//如果输入的是"=",继续往下执行,否则从新开始
{if(r7==0x0d)//如果r7中存放的是"+",则执行加运算
{bian1();
jia();
bian2();
}
elseif(r7==0x0c)//如果r7中存放的是"-",则执行减运算
{bian1();
jian();
}
elseif(r7==0x0b)//如果r7中存放的是"*",则执行乘运算
{bian1();
cheng();
bian2();
}
elseif(r7==0x0a)//如果r7中存放的是"÷",则执行除运算
{bian1();
chu();
}
else
error();//如果r7没有存进运算符,则转出错处理
}
else
{if(r7!
=0x00)//如果已按过运算键,往下执行,否则转else
{if(a>0x09&&a<0x0e)//如果还按下运算键,则后按的取代前面按的
r7=a;
elseif(array1[0]==0x10)//判断是不是输入加数(减数...)的第一个数
{for(i=0;i<8;i++)//是的话,将被加数(被减数...)存入array1中
array1[i]=array[i];
for(i=0;i<8;i++)
array[i]=0x10;
for(i=7;i>0;i--)//array中存入加数(减数...)
array[i]=array[i-1];
array[0]=a;
}
else//不是输入加数(减数...)的第一个数
{if(array[7]!
=0x10)//如果加数(减数...)已是八位整数,则转出错处理
error();
else
{for(i=7;i>0;i--)//否则将加数左移
array[i]=array[i-1];
array[0]=a;
}
}
}
else//之前还没有运算键按下
{if(a>0x09)//有运算键按下
{if(array[0]==0x10)//但是在运算键按下之前没有输入被加数,则转出错
error();
else
r7=a;//否则将运算键输入r7中保存
}
elseif(array[7]!
=0x10)//如果被加数已是八位整数,则转出错
error();
else//否则将被加数左移
{for(i=7;i>0;i--)
array[i]=array[i-1];
array[0]=a;
}
}
}
}
}
}
voidbian1(void)//"将uchar型变量转化为ulong型变量"子函数
{uchari;
for(i=7;i>0;i--)
{if(array[i]==0x10)
array[i]=0x00;
if(array1[i]==0x10)
array1[i]=0x00;
}
num1=(ulong)array1[7]*10000000;
num1+=(ulong)array1[6]*1000000;
num1+=(ulong)array1[5]*100000;
num1+=(ulong)array1[4]*10000;
num1+=(ulong)array1[3]*1000;
num1+=(ulong)array1[2]*100;
num1+=(ulong)array1[1]*10;
num1+=(ulong)array1[0];
num2=(ulong)array[7]*10000000;
num2+=(ulong)array[6]*1000000;
num2+=(ulong)array[5]*100000;
num2+=(ulong)array[4]*10000;
num2+=(ulong)array[3]*1000;
num2+=(ulong)array[2]*100;
num2+=(ulong)array[1]*10;
num2+=(ulong)array[0];
}
voidbian2(void)//声明"将ulong型变量转化为uchar型变量"子函数
{uchari=7,F0=1;
if(num1>99999999)
error();
else
{array[7]=(uchar)(num1/10000000);
array[6]=(uchar)(num1%10000000/1000000);
array[5]=(uchar)(num1%1000000/100000);
array[4]=(uchar)(num1%100000/10000);
array[3]=(uchar)(num1%10000/1000);
array[2]=(uchar)(num1%1000/100);
array[1]=(uchar)(num1%100/10);
array[0]=(uchar)(num1%10);
while(i>0&&F0)
{if(array[i]==0x00)
{array[i]=0x10;
i--;
}
else
F0=0;
}
}
}
voidjia(void)//"加运算"子函数
{num1+=num2;
}
voidjian(void)//"减运算"子函数
{uchari;
if(num1>num2)
{num1-=num2;
bian2();
}
elseif(num1==num2)
{for(i=1;i<8;i++)
array[i]=0x10;
array[0]=0x00;
}
else
{num1=num2-num1;
bian2();
if(array[7]!
=0x10)
error();
else
array[7]=0x11;
}
}
voidcheng(void)////声明"乘运算"子函数
{num1*=num2;
}
voidchu(void)//"除运算"子函数
{uchari,j=0x00,k;
doublenum3;
num3=(double)(num1)/(double)(num2);
num1=(ulong)(num3);
num3-=num1;
if(num3==0||num1>9999999)
bian2();
else
{bian2();
while(array[7]==0x10)
{j++;
for(i=7;i>0;i--)
array[i]=array[i-1];
array[0]=0x10;
}
array[j]+=0x12;
k=j-1;
while(k>0)
{num3*=10;
num2=(ulong)(num3);
num3-=num2;
array[k]=(uchar)(num2);
k--;
}
array[0]=(uchar)(num3*10);
while(array[0]==0x00)
{for(i=0;i<7;i++)
array[i]=array[i+1];
array[7]=0x10;
}
}
}
voiderror(void)//"出错显示"子函数(出错显示"Chucuo.")
{array[7]=0x0c;
array[6]=0x1d;
array[5]=0x1f;
array[4]=0x10;
array[3]=0x10;
array[2]=0x1c;
array[1]=0x1f;
array[0]=0x1e;
}
voiddisplayljy(void)//"显示"子函数
{uchararray3[32]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
0x79,0x71,0x00,0x40,0xbf,0x86,0xdb,
0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
0x58,0x74,0xdc,0x1c};
uchar*p=array,count=0x80,i,time;
F0=1;
while(F0)
{i=*(p+7);
P2=count;
P0=array3[i];
for(time=0xff;time>0x00;time--);
p--;
count=_cror_(count,1);
if(count==0x80)
F0=0;
}
}
voidiskeyyou(void)//"判断是否有键按下"子函数
{P2=0x00;
P1|=0x0f;
a=P1;
a|=0xf0;
}
voidinkeylove(void)//"判断按下的是什么键"子函数
{ucharb=0xfe,c=0x00,d;
uchararray4[16]={0x07,0x08,0x04,0x05,0x01,0x02,0x0f,0x00,
0x09,0x0a,0x06,0x0b,0x03,0x0c,0x0e,0x0d};
F1=0;
iskeyyou();
if(a!
=0xff)
{displayljy();
displayljy();
iskeyyou();
if(a!
=0xff)
{F0=1;
while(F0)
{P2=b;
P1|=0x0f;
if(P10==0)
{a=0x00;
F1=1;
}
elseif(P11==0)
{a=0x02;
F1=1;
}
elseif(P12==0)
{a=0x04;
F1=1;
}
elseif(P13==0)
{a=0x06;
F1=1;
}
else
{a=c;
a%=4;
if(a==0x01)
{a=0x07;
c+=a;
}
else
c++;
b=_crol_(b,1);
if(b&0x10==0)
{F0=0;
a=0xff;
}
}
while(F1)
{a+=c;
a=array4[a];
d=a;
while(a!
=0xff)
{displayljy();
iskeyyou();
}
a=d;
F1=0;
F0=0;
}
}
}
}
}
5、系统联调
在我将计算器的电路板焊接好以后,我将程序下载到单片机芯片上面,再接上电源测试发现键盘上面只有几个按键有显示,开始我就怀疑是自己的焊接键盘的线时,出现了虚焊或者是焊错了的错误,我就写了一个程序让数码管上面显示“4321”这四个数字,下载进去后,发现没有错误,这就证明我的数码管那一块没有出现错误,由此推论,最有可能出现错误的就是键盘,由于自己当时并不清楚键盘的行列线,所以没有自己测量了,我去问老师,老师就说“实验室的键盘可能也有点问题”,于是他就给我们拿了几个他自己借来的键盘,然后手把手的教我们怎么测试行列线,我也很快就测出了其对应的行列线,但是一接上电源测试,还是有一行不能显示,最后在老师的提点下,是发现P1.0口始终接了高电平,从而导致无法显示,在老师的帮助下,最终我做出了结果。
6、收获和体会
通过本次的课程设计,我收获了很多的东西。
主要让我们掌握了数码管移位动态扫描显示的编程方法,掌握了矩阵扫描的编程方法,掌握了数据在内部运算的编程方法,这也是编程必须掌握的知识。
同样学会了怎么使用keil和proteus软件,在Keil环境下创建项目,编辑源程序(C或ASM)并编译产生hex文件,然后使用Proteus和Keil联合调试,将生产的HEX文件加载给89C51,进行电路图的仿真,也是我自己第一次用单片机进行设计,更是深刻的体会到了单片机的用途之大。
在做课程设计的过程中,学会了怎么样对已焊接好的系统进行测试,检查错误的所在,对单片机的理论知识得到了巩固,同时也提高自身的动手能力。
在老师的帮助下,我知道了怎么样测试键盘的行列线,正确的连接它们,将自己在书本上学习到的知识运用到了实际的设计中,深切的体会到了知识的有用。
虽然在此次的课程设计过程中,我遇到了很多的困难,其中几次都想放弃,但是在老师和同学的帮助,我最终完成了自己的设计,在那一刻我觉得自己的努力是没有白费的,都是值得的。
同时通过本次的课程设计,我也看到了自己的不足,对知识掌握得不够牢固,做事情过于毛躁,不能沉下心来,这些在以后的生活中都是不可取的,在以后的课程设计乃至生活中,我要努力克服这些不足,认真的对待每一次的实验和课程设计。
八、附录
(1)参考文献:
单片机原理及应用,人民邮电出版社,杨辉先,黄辉先主编
单片机原理及应用实验教程,湘潭大学出版社,胡洪波主编
上网查资料
(2)元器件清单:
51单片机
一块
74LS244芯片
1个
共阴极四连七段数码管
2个
集成键盘
1个
发光二极管
1个
电阻
100(2个),10K(1个)
瓷片电容
20pF(2个)
电解电容
10uF(1个)
按键
1个
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 科学 计算器 设计 报告 51 单片机