基于单片机的计算器设计.docx
《基于单片机的计算器设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的计算器设计.docx(20页珍藏版)》请在冰豆网上搜索。
![基于单片机的计算器设计.docx](https://file1.bdocx.com/fileroot1/2023-2/9/9668e927-ab4e-4556-afc3-aecadda9a676/9668e927-ab4e-4556-afc3-aecadda9a6761.gif)
基于单片机的计算器设计
2.4矩阵按键
键盘是单片机系统中最常用的人机对话输入设备,用户通过键盘向单片机输入数据或指令。
键盘控制程序需完成的任务有:
监测是否有键按下,有键按下时,若无硬件去抖动电路时,应用软件延时方法消除按键抖动影响;当有多个键同时按下时,只处理一个按键,不管一次按键持续多长时间,仅执行一次按键功能程序。
矩阵按键扫描程序是一种节省I/O口的方法,按键数目越多节省I/O口就越可观,思路:
先判断某一列(行)是否有按键按下,再判断该行(列)是哪一只键按下。
但是,在程序的写法上,采用了最简单的方法,使得程序效率最高。
本程序中,如果检测到某键按下了,就不再检测其它的按键,这完全能满足绝大多数需要,又能节省大量的CPU时间。
2.5计算器设计总体思想
根据功能和指示要求,本系统选用以MCS-51单片机为主控机。
通过扩展必要的外围接口电路,实现对计算器的设计。
具体设计如下:
1、由于要设计的是简单的计算器,可以进行四则运算,为了得到教好的显示效果,采用LCD显示数据和结果。
2、另外键盘包括数字键(0-9)、符号键(+、-、*、/)、清除键和等号键,故只需要16个按键即可,设计中采用集成的计算机键盘。
3、执行程序:
开机显示零,等待键入数值,当键入数字,通过LCD显示出来,当键入+、-、*、/运算符,计算器在内部执行数值转换和存储,并等待再次键入数值后将显示键入的数值,按等号就会在LCD上输出运算结果。
4、错误提示:
当单片机执行程序中有错误时,会在LCD上显示相应的提示,如:
当输入的数值或计算器得到的结果大于计算器的显示范围时,计算器会在LCD上提示溢出;当除数为0时,计算器会在LCD上提示错误。
第三章硬件系统设计
硬件系统是指构成微机系统的实体和装置,通常由运算器、控制器、存储器、输入接口电路和输入设备、输出接口电路和输出设备等组成。
单片机实质上是一个硬件的芯片,在实际应用中,通常很难直接和被控对象进行电气连接,必须外加各种扩展接口电路、外部设备、被控对象等硬件和软件,才能构成一个单片机应用系统。
本设计选用以AT89S51单片机为主控单元。
显示部分:
采用LCD静态显示。
按键部分,采用4*4键盘。
硬件电路原理图如图3.1所示:
图3.1硬件电路原理图
3.1键盘接口电路
计算机输入数字和其他功能按键时要用到很多按键,在这种情况下,编程会很简单,但是会占用大量的I/O口资源,因此在很多情况下都不采用这样的方式,而是采用矩阵键盘的方式。
矩阵键盘采用四条I/O线作为行线,四条I/O线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键。
这样键盘上按键的数量就为4*4个。
这样行列式键盘结构能有效的提高单片机系统中I/O口的利用率。
计算器的键盘布局如图3.2所示:
一般有16个键组成,在单片机中正好有一个P端口实现16个按键功能,这种形式在单片机系统中最常用。
图3.2矩阵键盘内部电路
3.2LCD显示模块
本设计采用LCD液晶显示器来显示输出数据。
LCD的特性有:
1、+5V电压,对比可调度;2、内含复位电路;3、提供各种控制命令,如:
清屏、字符闪烁、光标闪烁、显示移位等多种功能;4、有80字节显示数据存储器DDRAM;5、内建有160个5X7点阵的字型的字符发生器CGROM;6、8个可由用户自定义的5X7的字符发生器CGRAM。
本设计通过D0-D7引脚向LCD写指令字或写数据以使LCD实现不同的功能或显示相应的数据。
其接口电路如图3.3所示。
图3.3LCD接口电路
LCD的引脚说明如表3.1所示:
表3.1LCD的引脚说明
符号
引脚说明
符号
引脚说明
VSS
电源地
DB4
DataI/O
VDD
电源正极(+5V)
DB5
DataI/O
V0
液晶显示偏压输入
DB6
DataI/O
RS
数据/命令选择端(H/L)
DB7
DataI/O
R/W
读写控制信号(H/L)
CS1
片选IC1信号
E
使能信号
CS2
片选IC2信号
DB0
DataI/O
RST
复位端(H:
正常工作,L:
复位)
DB1
DataI/O
VEE
负电源输出(-10V)
DB2
DataI/O
BLA
背光源正极(+4.2)
DB3
DataI/O
BLK
背光源正极
3.3运算模块
MCS-51单片机是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器和多功能I/O等计算机所需要的基本功能部件。
如果按功能划分,它由以下功能部件组成,即微处理器(CPU),数据存储器(RAM),程序存储器(ROM/EPROM),并行I/O口,串行口,定时器/计数器,中断系统及特殊功能寄存器(SFR)。
单片机是靠程序运行的,并且可以修改。
通过不同的程序实现不同的功能,尤其是特殊的一些功能,通过使用单片机编写的程序可以实现高智能、高效率以及高可靠性,因此采用单片机作为计算器的主要功能部件,可以很快的实现运算功能。
运算模块由键盘和显示屏组成。
单片机通过按键来实现输入数据和操作方式的控制,在运算过程中,对所设的数据进行四则运算时,要先确定选用的是哪一个运算符,若是+或*,则要判断结果是否会溢出,溢出则显示错误提示,没有溢出则显示运算结果,若是/,则要判断除数是否为零,为零时显示错误提示,不为零显示运算结果。
第四章软件设计
4.1汇编语言和C语言的特点及选择
本设计是硬件电路和软件编程相结合的设计方案,选择合适的编程语言是一个重要的环节。
在单片机的应用系统程序设计时,常用的是汇编语言和C语言。
机硬件,程序可读性和可移植性比较差。
而C语言虽然执行效率没有汇编语言高,但语言简洁,使用方便,灵活,运算丰富,表达化类型多样化,数据结构类型丰富,具有结构化的控制语句,程序设计自由度大,有很好的可重用性,可移植性等特点。
由于现在单片机的发展已经达到了很高的水平,内部的各种资源相当的丰富,CPU的处理速度非常的快。
用C语言来控制单片机无疑是一个理想的选择。
所以在本设计中采用C语言编写软件程序。
主程序的设计详见附录三。
4.2键扫程序设计
键扫程序的过程为:
开始时,先判断是否有键闭合,无键闭合时,返回继续判断,有键闭合时,先去抖动,然后确定是否有键按下,若无键按下,则返回继续判断是否有键闭合,若有键按下,则判断键号,然后释放,若释放按键完毕,则返回,若没有释放按键,则返回继续释放。
其流程图如图4.1所示。
图4.1键扫程序流程图
4.3算术运算程序设计
算术运算程序的过程为:
先判断输入的运算符是+、-、*、/中的哪一个,若是+或-,则要判断运算结果是否溢出,溢出则显示错误信息,没溢出就显示运算结果,若是/,则要先判断除数是否为零,为零就显示错误信息,不为零则显示运算结果,若是-,则直接显示运算结果。
其流程图如图4.2所示。
图4.2算术运算程序设计流程图
4.4显示程序设计
显示程序的过程为:
显示开始时,先进行LCD的初始化,判断是否显示汉字或ACSII码或图形,若不显示,则返回,若显示的是汉字或ACSII码,则进行相应功能的设置,然后送地址和数据,再判断是否显示完,显示完则返回,没有显示完则继续送地址,若显示的是图形,则先进行相应功能的设置,再送行地址和列地址,然后送数据,最后判断是否显示完,显示完则返回,没有显示完则继续送行地址和列地址。
其流程图如图4.3所示。
图4.3显示程序流程图
第五章系统调试与存在的问题
5.1硬件调试
常见故障:
1、逻辑错误:
它是由设计错误或加工过程中的工艺性错误所造成的。
这类错误包括错线、开路、短路等。
2、元器件失效:
有两方面的原因:
一是器件本身已损坏或性能不符合要求;二是组装错误造成元件失效,如电解电容、集成电路安装方向错误等。
3、可靠性差:
因其可靠性差的原因很多,如金属化孔、接插件接触不良会造成系统时好时坏,经不起振动;走线和布局不合理也会引起系统可靠性差。
4、电源故障:
若样机由电源故障,则加电后很容易造成器件损坏。
电源故障包括电压值不符合设计要求,电源引线和插座不对,功率不足,负载能力差等。
调试方法:
包括多级调试和联机调试。
在调试过程中要针对可能出现的故障认真分析,直至检查出原因并排除。
本次硬件调试过程中,对所出现的问题进行了认真的分析和改正,最后能够很好的达到设计要求的效果。
5.2软件调试
软件调试一般分为以下四个阶段:
1、编写程序并查错;2、在C语言的编译系统中编译源程序3、对程序进行编译连接,并及时发现程序中存在的错误;4、改正错误。
在本次调试中出现的问题有:
1、在程序中有的函数名未定义;
2、在抄录程序时,少录入一些字符,如:
“;”、“{”、“-”等符号,而出现错误;
3、有一些函数名录入时少写一个字母或顺序颠倒;
4、没有注意函数名的调用及定义;
5、芯片引脚定义出错而导致没有实验现象。
在软件调试过程中,对出现的错误进行了认真的分析和修改,多次调试成功后,能够很好的达到既定的设计效果。
总结
我的题目是简易计算器的设计,对于我们这些实践中的新手来说,这是一次考验。
怎样才能找到课堂所学与实际应用的最佳结合点?
怎样让自己的业余更接近专业?
怎样让自己的计划更具有序性,而不会忙无一用?
这都是我们所要考虑和努力的。
这次课程设计我学到很多很多的东西,学会了怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。
不仅巩固了以前所学过的知识,而且学到了很多在书本上没有学到过的知识,掌握了一种系统的研究方法,可以进行一些简单的编程。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
同时在设计的过程中发现了自己的不足之处,例如对以前所学过的知识理解得不够深刻,掌握得不够牢固,对C语言掌握得不够好等。
这次毕业设计的完成要特别感谢我的导师马磊娟老师,在教学繁忙、事务缠身的情况下,马老师多次抽出时间,对我的论文进行悉心的指导,从论文的选题到论文的总体框架,再到论文撰写过程中的语言组织,她都进行了细致的批阅,使得我的论文越来越规整,更加符合标准。
在这里真诚地对所有关心我、帮助我、鼓励我的老师、同学、朋友道声:
“谢谢!
”
参考文献
[1]徐爱钧.智能化测量控制仪表原理与设计(第二版).北京航天航空大学出版社,2004.9
[2]孙育才等.MCS-51系列单片微型计算机及其应用(第4版).东南大学出版社,2004.3
[3]李萍等.智能仪器实验指导书.大连交通大学,2007.9
[4]单片机应用技术(C语言).中国劳动社会保障出版社,2006.6
[5]武庆生,仇梅等著.单片机原理与应用.电子科技大学出版,1998.12
[6]朱定华著.单片机原理与接口技术.电子工业出版社,2001.4[7]王宜怀,刘晓升等著.嵌入式应用技术基础教程.北京清华大学出版社,2005.7
[8]王威著.HCS12微控制器原理及应用.北京航空航天大学出版社,2007.10
[9]龚运新著.单片机C语言开发技术.北京清华大学出版社,2006.10
[10]周立功.单片机实验与实践.北京航空航天大学出版社,2004.3
附录
附录一:
计算器硬件连线图
附录二:
元器件清单
8051芯片
1个
LCD显示屏
1个
三极管
7个
1K电阻
20个
电容
3个
晶振
1个
按键
20个
排插及排线
5对
开关
1个
电源接口
1个
附录三:
源程序
str[6]=str[5]=str[4]=str[3]=str[2]=str[1]=10;
str1[6]=str1[5]=str1[4]=str1[3]=str1[2]=str1#include//51
单片机基本定义头文件
#include
#include//循环位移头文件
#defineucharunsignedchar//宏定义
#defineuintunsignedint
sbitP1_4=P1^4;//I/O端口定义(矩阵扫描后4位端口)
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
uchari,nums;
ucharwei,wei2,ss,ss1,ss2,str[]={0,0,0,0,0,0,0};
longtemp,temp1,str[]={10,10,10,10,10,10,10};
ucharcodedutable[]={//段位编码
0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
ucharcodewetable[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
voidinit();//函数声明
voidpanduan();
voiddisplay();
voiddelay(uintz);
voidshaomiao();
voidmain()//主函数
{
init();//调用变量初始化函数
while
(1)//大循环
{
shaomiao();//调用矩阵扫描加处理函数
diaplay();//调用显示函数
}
}
voidinit()
{
ss2=0;
wei2=1;
temp1=0;
ss=0;
ss1=0;
temp=0;
wei=0;
num=0;
}
voiddelay(uintz)//延时函数(单位ms)
{
uchari;
uintj;
for(j=z;j>0;j--)
for(i=114;i>0;i--);
}
voidshaomiao()//扫描加处理函数
{
for(i=0,s=0xfe;i<4;i++)//低四位端口依次赋值1
{
P1=s;//对P1口赋值
panduan();//调用判断处理函数
s=_crol_(s,1);//s循环位左移
s=sl0xf0;//进行位或运算(使高4位复原)
}
}
voidpanduan()
{
ucharn;
if(P1_4==0||P1_5==0||P1_6==0||P1_7==0)
{
delay(10);
P1=sl0xf0;
if(P1_4==0||P1_5==0||P1_6==0||P1_7==0)
{
if(P1_4==0)
{n=1;num=i*4+n-1;}
elseif(P1_5==0)
{n=2;num=i*4+n-1;}
elseif(P1_6==0)
{n=3;num=i*4+n-1;}
elseif(P1_7==0)
{n=4;num=i*4+n-1;}
if(num<10&&wei!
=7)
{
wei++;
if(ss1==1)
{
temp=0;
str[6]=str[5]=str[4]=str[3]=str[2]=str[1]=10;
str1[6]=str1[5]=str1[4]=str1[3]=str1[2]=str1[1]=0;
ss1=0;
}
str[wei]=num;
if(str[1]!
=10)temp=str[1];
if(str[2]!
=10)temp=str[1]*10+str[2];
if(str[3]!
=10)temp=str[1]*100+str[2]*10+str[3];
if(str[4]!
=10)temp=str[1]*1000+str[2]*100+str[3]*10+str[4];
if(str[5]!
=10)temp=str[1]*10000+str[2]*1000+str[3]*100+str[4]*10+str[5];
if(str[6]!
=10)temp=str[1]*100000+str[2]*10000+str[3]*1000+str[4]*100+str[5]*10+str[6];
}
if(num>=10)
{
wei=0;
if(num==10)
{
temp=0;
l[1]=0;
wei=0;
temp1=0;
ss=0;
wei2=1;
}
if(ss1==0&&num==11||(ss1==0&&ss2!
=0&&num>>11&&num<16))
{
if(num==11)
ss2=0;
switch(ss)
{
case0:
break;
case1:
temp=temp1;break;
case2:
temp=temp1-temp;break;
case3:
temp=temp*temp1;break;
case4:
temp=temp1/temp;break;
}
if(temp>999999)
temp=0;
ss1=1;
}
if(num==12)
{
temp1=temp;
ss=1;ss1=1;ss2=1;
}
if(num==13)
{
temp1=temp;
ss=2;ss1=1;ss2=1;
}
if(num==14)
{
temp1=temp;
ss=3;ss1=1;ss2=1;
}
if(num==15)
{
ss=4;ss1=1;ss2=1;
}
}
}
str1[6]=temp/100000;
str1[5]=temp%100000/10000;
str1[4]=temp%10000/1000;
str1[3]=temp%1000/100;
str1[2]=temp%100/10;
str1[1]=temp%10/1;
if(str1[1]!
=0)
wei2=1;
if(str1[2]!
=0)
wei2=2;
if(str1[3]!
=0)
wei2=3;
if(str1[4]!
=0)
wei2=4;
if(str1[5]!
=0)
wei2=5;
if(str1[6]!
=0)
wei2=6;
}
while(P1_4==0||P1_5==0||P1_6==0||P1_7==0);
}
voiddisplay()
{
chari1;
for(i1=1;i1{
P2=wetable[0];
P3=dutable[14];
}
else
{
P2=wetable[i1-1];
P3=dutable[str1[i1]];
delay(10);
P3=0xff;
}
}