单片机计算器的课程设计报告Word格式.docx
- 文档编号:17779309
- 上传时间:2022-12-10
- 格式:DOCX
- 页数:29
- 大小:547.79KB
单片机计算器的课程设计报告Word格式.docx
《单片机计算器的课程设计报告Word格式.docx》由会员分享,可在线阅读,更多相关《单片机计算器的课程设计报告Word格式.docx(29页珍藏版)》请在冰豆网上搜索。
单片机最小系统硬件电路
3.2键盘接口电路
计算器所需按键有:
数字键:
’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’
功能键:
’+’,’-‘,’*’,’/’,’=’,’C(清零)’
扩展键:
“log”,“ln”,“x^2”“小数点”,“开方”
共计25个按键,采用4*4矩阵键盘,键盘的行和列之间都有公共端相连,四行和四列的8个公共端分别接P1.0~P1.7,这样扫描P1口就可以完成对矩阵键盘的扫描,通过对16个按键进行编码,从而得到键盘的口地址,对比P1口德扫描结果和各按键的地址,我们就可以得到是哪个键按下,从而完成键盘的功能。
以下为键盘接口电路的硬件电路图
键盘接口电路
实物图:
扩展键接口电路:
3.3数码管显示电路
采用8位数码管对计算数据和结果的显示(实验时只用到了4位),这里选取共阴数码管,利用74LS244N对数码管进行驱动,为了节省I/O资源,采取动态显示的方法来显示计算数据及结果。
P0口输出显示值,
P2.0~P2.7(实际操作用到P2.0-P2.3)用来作为位选端,控制哪几位数码管进行显示。
以下为数码显示电路的硬件电路图
74LS244N接口电路:
3.4按键监视电路
按键监视电路就是在按键时,发出声音提醒,以确保输入数字有效。
这里就采用5V蜂鸣器作为示音设备(实际操作用发光二极管代替)。
用p3.7口输出信号。
以下为报警电路硬件电路图
按键监视电路图
系统整体硬件电路图见附录一
四、系统软件设计
4.1键盘扫描子程序设计
要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。
以下为键盘扫描子程序的程序清单。
ucharKeyscan(void)
{
uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};
for(j=0;
j<
4;
j++)
{
P1=Buffer[j];
/*以下三个_nop_();
作用为让P1口的状态稳定*/
delay();
temp=0x01;
for(i=0;
i<
i++)
{
if(!
(P1&
temp))
{
return(i+j*4);
}
temp<
<
=1;
}
}
}
4.2移位程序及结果计算代码设计
输入数据要存储在一四位数组内,而我们键入的值是数据的高位,后键入的值是低位,这样我们就需要在输入低位数值时将高位数值从数组的低位移向数组的高位,这就是编写移位子程序的目的。
对于结果计算子程序,包含加、减、乘、除四种运算。
以加法运算为例,各种运算各有其标志位来代表计算类型,当加法标志位add=1是,就将输入的两个数据按照加法进行计算。
首先将数组内的数按照对应的位关系,将其转化为一个十进制数,这样我们就得到了加速和被加数这样俩个十进制数,从而我们就可以简单的将两个数进行相加,结果就是我们所求的数值。
但这个数值不能直接显示到数码管上,我们还要对其进行处理,使其变为对应进位的四个数存入数组内,以便显示。
既通过对结果数值分别除以1000、100、10和对10取余,得到我们想要的四个数,送显示子程序显示。
其余减、乘、除的计算方法与加法的计算方法一样,这里不再累述。
以下为移位子程序和结果计算子程序的程序清单。
这部分嵌入到了主函数中。
调用输入数据函数:
4.3显示子程序设计
从始至终无论是输入的计算数据,还是计算后的结果值。
都存储在同一数组dat[]中,这样我们只要在显示时一直调用dat[]中的值,就能正确的显示数据。
以下为显示子程序的程序清单。
voiddiaplay(void)interrupt1
ucharlen;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
P2=Disbuf[dcounter];
len=dcounter;
P0=xx[len];
dcounter+=1;
if(dcounter==8)
dcounter=0;
延时程序:
voidDelay_1ms(uinti)//1ms延时
ucharx,j;
j<
i;
j++)
for(x=0;
x<
=148;
x++);
voiddelay()
inti,j;
for(i=0;
=10;
=2;
;
4.4主程序设计
主程序既把以上各子程序串连成一个整体,使整个程序循环运行。
而在以上程序中也已经加入了个程序之间的连接点,首先进入程序后就立即进入显示子程序,而显示子程序内又调用键盘扫描子程序,若有键按下,则会跳转到移位子程序和结果计算子程序进行相应的处理。
通过计算或移位后,数组内的值发生改变,显示的值也会同时发生改变。
之后再进行键盘扫描,如此反复运行,就构成了程序的整体。
整体程序清单如下:
#include<
reg52.h>
intrins.h>
math.h>
typedefunsignedcharuchar;
typedefunsignedintuint;
voiddelay();
ucharKeyscan(void);
voidresult_a(void);
voiddiaplay(void);
voidDelay_1ms(uinti);
ucharvie_a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
ucharexchg_a[16]={7,8,9,13,4,5,6,12,1,2,3,11,14,0,15,10};
ucharxx[8];
ucharxxu[8];
voidSpeak_a(void);
sbitspp=P3^7;
//响铃
sbitcl3=P3^6;
//小数点
sbitcl=P3^1;
//求ln
sbitcl0=P3^2;
//开方
sbitcl1=P3^3;
//求log
sbitcl2=P3^4;
//求e的x次幂
ucharflo[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xef,0xef};
ucharzz[8]={0x77,0x3f,0x77,0x77,0x79};
ucharDisbuf[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
ucharyy[8]={0x3f,0,0};
floata=0,b=0,c;
ucharL=1;
ucharcal_a=0,dcounter=0;
voidmain(void)
ucharsinglp_a=1,n=1;
ucharkey=18;
ucharall_m=0,ent_a=0,att=1;
signedlongs,r;
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
spp=0;
while
(1)
if(singlp_a==1)
singlp_a=0;
P3=0x7f;
if(P3!
=0x7f)
Delay_1ms
(2);
if(cl==0)
Speak_a();
cal_a=14;
//求以㏑x
key=15;
if(cl0==0)
cal_a=15;
if(cl1==0)
cal_a=16;
//求以十为底对数
if(cl2==0)
cal_a=17;
if(cl3==0)
att=0;
xx[0]=xx[0]+0x80;
P1=0x0f;
if(P1!
=0x0f)
Delay_1ms
(2);
if(P1!
key=exchg_a[Keyscan()];
Speak_a();
P1=0x0f;
P3=0x7f;
if(P1==0x0f&
&
P3==0x7f)
singlp_a=1;
if(key<
=9&
key>
=0)
if(all_m==0)
if(ent_a==0)
uchari;
ent_a=1;
for(i=0;
i<
=7;
i++)
{
xx[i]=0;
}
else
{}
if(att==1)
uchari;
a=a*10+key;
for(i=7;
i>
0;
i--)
xx[i]=xx[i-1];
xx[0]=vie_a[key];
key=18;
}
else
doublem;
m=key;
for(i=1;
=n;
m=m/10;
a=m+a;
n++;
key=28;
else
b=b*10+key;
b=m+b;
if(key>
=10&
key<
=13)
uchari;
cal_a=key;
xx[i]=xxu[i];
all_m=1;
key=18;
att=1;
n=1;
if(key==14)
ent_a=0;
xx[i]=yy[i];
a=0;
b=0;
c=0;
all_m=0;
L=1;
cal_a=0;
if(key==15)
key=28;
xx[i]=0;
result_a();
//调用求计算结果
if(L==1)
{
if(c==0)
xx[0]=0x3f;
if(c>
=0.0001)
r=c;
s=10000*(c-r);
n=0;
xx[n]=vie_a[s%10];
if(s%10!
n++;
=0.001)
s=1000*(c-r);
if(n==0&
s%10==0)
{}
else
n++;
=0.01)
s=100*(c-r);
=0.1)
s=10*(c-r);
=1)
s=c;
xx[n]=flo[s%10];
=10)
s=c/10;
=100)
s=c/100;
if(n>
=8)
uchari;
xx[i]=xx[i+1];
xx[n-1]=vie_a[s%10];
xx[n]=vie_a[s%10];
=1000)
s=c/1000;
=10000)
s=c/10000;
=100000)
s=c/100000;
=1000000)
s=c/1000000;
=10000000)
s=c/10000000;
=100000000)
xx[i]=zz[i];
xx[n]=0xbf;
voidresult_a(void)
switch(cal_a)
case0:
c=a;
break;
case10:
c=a+b;
case11:
if(a<
b)
L=0;
c=a-b;
break;
case12:
c=a*b;
case13:
c=a/b;
case14:
c=log(a);
a=c;
case15:
c=sqrt(a);
case16:
c=log10(a);
case17:
c=exp(a);
default:
c=0;
ucharKeyscan(void)
voiddiaplay(void)interrupt1
voidSpeak_a(void)
=20;
spp=1;
spp=0;
五、调试及性能分析
5.1调试步骤
在焊接好器件后,先不要将芯片插在芯片座上,要先验证先板上电源是否好用,有无短路等。
接上电源,用万用表测量个芯片座对应电源和地之间的电压值,观察电压值是否正常。
一切正常后方可将芯片插入芯片座,以继续测试其他功能。
将芯片插上后,对各个模块进行调试,按键是否工作正常,数码管是否显示正常等。
编写相关部分的测试程序对其进行测试。
各部分硬件检测无误后,下载程序进行整体调试,一切正常后,结束调试过程。
在具体调试时首先遇到的问题是程序无法下载进入单片机,通过将电路板接线与原理电路图接线的对比发现,串口芯片与单片机连接的输入,输出接反,重新用铜线连接后,依然无法下载程序。
后找到原因是由于下载串口与设计封装不符,用相对应的下载线可以下载。
成功下载程序后,发现数码管显示不正确,查看后发现有先没有连接,可能是制板时漏印,连接后显示正常。
5.2性能分析
对于计算器的性能,主要的衡量指标就在于计算的精度,本次制作的计算器性能情况如下:
加法运算:
四位加法运算,和值不超过9999,若超过上限,则显示错误提示ERROR。
减法运算:
四位减法运算,若结果为负,对其取绝对值。
乘法运算:
积不超过9999的乘法运算,若超出上限,显示错误提示Error。
除法运算:
整数除法,既计算结果为整数,若除数为零,则显示错误提示Error。
通过对实际性能的分析,可以得到本次设计满足设计的要求。
六、心得体会
通过本次课程设计我真正的自己完成了对给定要求系统的硬件设计、电路设计、电路板设计、软件设计以及对成品的调试过程。
从整个过程中学习到了很多方面的知识,了解到以往学习中自己知识在某方面的不足之处,是对以往学习科目的一种贯穿和承接,从而能更好的认识和学习,也对将来从事工作大有裨益。
本次实验过程中,我切实体验到了,认真对待每一个细小零件的重要性。
对于实验室提供的零件要具有检错能力。
我做的是
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 计算器 课程设计 报告