基于STC89C52的简易计算器设计.docx
- 文档编号:11096323
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:25
- 大小:130.89KB
基于STC89C52的简易计算器设计.docx
《基于STC89C52的简易计算器设计.docx》由会员分享,可在线阅读,更多相关《基于STC89C52的简易计算器设计.docx(25页珍藏版)》请在冰点文库上搜索。
基于STC89C52的简易计算器设计
福建电力职业技术学院
课程设计
课程名称:
《智能仪器》
题目:
基于STC89C52的简易计算器设计
专业班次:
姓名:
学号:
指导教师:
学期:
2011-2012学年第2学期
日期:
2012.2
1.引言
随着社会的发展,人们生活水平的提高,单片机的应用越来越贴近生活了,人们常用单片机来实现一些简单的电子设计。
计算器在人们的日常生活中是不可或缺的电子产品之一,目前市场上的计算器基本可以满足我们的日常需求,但它还在发展之中,我们要继续研究出更加强大的计算器。
基于这样的理念,本设计采用单片机来设计简易计算器。
本设计是以STC89C52为单片机,LCD为显示器设计的简易计算器,所设计的计算器将完成两位数的加、减、乘、除等功能。
1.1设计意义
通过本次课程设计,进一步掌握单片机知识,知道AT89S52单片机的原理、编程和各种功能的应用,了解简易计算器的工作原理,初步掌握计算器的硬软件设计、编写、调试和仿真,充分提高动手能力和排除故障的能力,同时通过课程设计加深我们对单片机的认识和兴趣,发挥我们的创新能力和动手能力。
1.2设计任务和主要内容
本设计要制作的就是单片机于生活中最为常见的一种应用——简易计算器,以STC89C52单片机作为核心来进行的数字计算器模拟系统设计,可以完成计算器的键盘输入,进行加、减、乘、除两位数范围内的基本四则运算,并在LCD上显示相应的结果。
设计电路采用AT89C51单片机为主要控制电路,显示采用LCD静态显示,软件方面使用C语言编程,并用PROTUES仿真。
①查阅相关文献资料,了解简易计算器程序的原理,能够运用C语言进行简易计算器的设计与制作。
②设计基于C语言的计算器的控制系统硬件部分,画出控制系统硬件框图,设计简易计算器的控制系统的软件部分,首先根据简易计算器所需的具体功能设计好程序流程图,包括控制流程图、控制时序图、梯形图程序设计;根据设计的程序流程图写出代码,并进行代码编译的调试。
③把设计好的软件代码烧入硬件中,然后进行总体调试,直至原先预定要实现的功能完全实现为止。
④设计出系统方框图、单元图、原理总图;画出控制程序流程图,以及编写完整的程序
2.硬件设计
2.1系统框图
本文所设计的简易计算器显示系统由STC89C52单片机及其最小系统、LCD1602液晶显示和矩阵键盘等部分组成。
其系统框图如图2.1所示。
图2.1简易计算器系统框图
2.2最小系统
单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统。
对51系列单片机来说,最小系统一般应该包括:
单片机、晶振电路、复位电路。
如图2.2为单片机的最小系统。
图2.2STC89C52最小系统
STC89C52单片机概述:
STC89C52是一个低功耗,高性能CMOS8位单片机,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
STC89C52具有如下特点:
40个引脚,8k的flash存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(IO)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
2.3矩阵键盘
键盘是单片机系统中最常用的人机对话输入设备,用户通过键盘向单片机输入数据或指令。
目前市场上键盘有独立键盘和矩阵键盘,经过多方考量,本设计采用矩阵键盘。
在键盘中按键数量较多时,为了减少IO口的占用,通常将按键排列成矩阵形式。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口就可以构成4*4=16个按键,比直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显。
所以,在需要的键数比较多时,采用矩阵法来做键盘较为合理。
2.3.1独立键盘与矩阵键盘的区别
计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会比较简单,但是会占用大量的IO口资源,因此在很多情况下都不采用这种方式。
矩阵键盘扫描程序的优点在于,不用专门的按键延时程序,提高了CPU效率,也不用中断来扫描键盘,节省了硬件资源。
此外,本键盘扫描程序每次扫描占用CPU时最短,不论有键按下或者无键按下都可以在很短的时间完成一次扫描。
2.3.2矩阵键盘与单片机的接口电路
下图为矩阵键盘与单片机的接口电路图,由图可知,当无按键闭合时,P10~P13与P14~P17之间开路;当有键闭合时,与闭合键相连的两条IO口线之间短路。
图2.3矩阵键盘接口电路
2.4LCD1602
2.4.1LCD1602液晶简介
本设计使用LCD1602液晶显示器来显示。
液晶是介于固态和液态间的有机化合物,将其加热会变成透明液态,冷却后变成结晶的混作固态。
在点击的作用下,产生冷热变化,从而影响它的透光性,来达到显示的目的。
1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,它有若干个5*7或者5*11等点阵字符位组成,每个点阵字符位都可以显示一个字符。
每位之间有一个点距的间隔,每行之间也有也有间隔,起到了字符间距和行间距的作用,所以它不能显示图形。
LCD1602液晶显示器具有以下几个优点:
低压、微功耗、显示信息量大、寿命长、无辐射、无污染。
2.4.2LCD1602与单片机的接口电路
1602液晶模块内部的控制器共有11条控制指令,丰富的指令可以完成液晶的时序控制、工作方式设置和数据显示等。
本设计采用的是LCD1602液晶模块,是标准的16针插座,接口电路如下图所示:
图2.4LCD1602接口电路
知道接口图后,还要了解每个引脚接口的说明,引脚接口说明如下表所示:
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
数据
3
VL
液晶显示偏压
11
D4
数据
4
RS
数据/命令选择
12
D5
数据
5
R/W
读/写选择
13
D6
数据
6
E
使能信号
14
D7
数据
7
D0
数据
15
BLA
背光源正极
8
D1
数据
16
BLK
背光源负极
表2.4引脚接口说明表
3.软件设计
3.1矩阵键盘扫描原理
如图2.3所示,初始化时,将P1.4置为低电平,通过与0x0f相与来判断所按下的键,此次为扫描位于P1.4那一行的键,若相与结果为0x0e时说明P1.0所检测出的为低电平,闭合的键应为P1.4行与P1.0列的交叉处的键。
若相与结果为0x0d则P1.1所检测为低电平,闭合的键应为P1.4行与P1.1列的交叉处的键。
若相与结果为0x0b则P1.2所检测为低电平,闭合的键应为P1.4行与P1.2列的交叉处的键。
若相与结果为0x07则P1.3所检测为低电平,闭合的键应为P1.4行与P1.3列的交叉处的键。
要把16个键盘全部扫描完需要进行4次这样的逐行扫描,所用方法相同程序类似分别另P1.5,P1.6,P1.7为低电平执行相同操作。
判断有无按键按下的方法:
第一步,置列线P14~P17为输入状态,从行线P10~P13输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。
第二步,行线轮流输出低电平,从列线P14~P17读入数据,若有某一列为低电平,则对应行线上有键按下。
综合一二两步的结果,可确定按键编号。
但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。
图2.3矩阵键盘接口电路
3.2LCD1602的软件设计
3.2.1LCD1602的指令说明
1602液晶模块内部的控制器共有11条控制指令,如表3.2所示。
表3.2控制命令表
序号
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清显示
0
0
0
0
0
0
0
0
0
1
2
光标返回
0
0
0
0
0
0
0
0
1
*
3
置输入模式
0
0
0
0
0
0
0
1
I/D
S
4
显示开/关控制
0
0
0
0
0
0
1
D
C
B
5
光标或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符发生存贮器地址
0
0
0
1
字符发生存贮器地址
8
置数据存贮器地址
0
0
1
显示数据存贮器地址
9
读忙标志或地址
0
1
BF
计数器地址
10
写数到CGRAM或DDRAM)
1
0
要写的数据内容
11
从CGRAM或DDRAM读数
1
1
读出的数据内容
如上表所示,1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(1为高电平、0为低电平)
3.2.2LCD1602的时序图
LCD1602与HD44780相兼容的芯片时序表如下:
表3.3基本操作时序表
读状态
输入
RS=L,R/W=H,E=H
输出
D0—D7=状态字
写指令
输入
RS=L,R/W=L,D0—D7=指令码,E=高脉冲
输出
无
读数据
输入
RS=H,R/W=H,E=H
输出
D0—D7=数据
写数据
输入
RS=H,R/W=L,D0—D7=数据,E=高脉冲
输出
无
读写操作时序图如下:
图3.2读操作时序图
图3.3写操作时序图
3.3主程序设计
在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法。
设计的中心思想是把一个复杂应用程序按整体功能划分成若干相对独立的程序模块,各模块可以单独设计,编程和调试,然后组合起来。
这种方法便于设计和调试,容易实现多个程序共存,但各个模块之间的连接有一定的难度根据需要我们可以采用自上而下的程序设计方法,此方法先从主程序开始设计,然后再制作各从属程序和子程序,层层细化逐步求精,最终完成一个复杂程序的设计。
这种方法比较符合人们的日常思维,缺点是一级的程序错误会对整个程序产生影响。
程序流程图如图3.3
图3.4主程序流程图
3.4源程序
见附录
3.5调试结果
在查找了相关书籍后编写出程序,并根据程序焊接所需要的元器件,将各类元器件及管脚座焊接完毕后,插入单片机、LCD显示屏、矩阵键盘等各类芯片。
随后进行功能验证。
加、减、乘、除运算和LCD液晶显示。
1)上电后,屏幕初始化。
2)计算。
按下数字键,屏幕显示按下的数字,再按下加、减、乘、除符号键,然后再按下数字键,最后按下“﹦”号键,屏幕即显示出计算结果。
本次计算器可实现两位数间的计算。
3)如果要再次计算,可以按下清零键清零,或者按下单片机的复位键,重新初始化。
经过以上步骤验证可知,实验目标功能基本实现,设计成功。
4.设计小结
为期3周的课程设计在紧锣密鼓的实验中接近尾声了,这次的课题是基于STC89C52的简易计算器设计,本设计采用了STC89C52芯片,基本上实现了利用单片机进行了一个简单的计算器设计,允许对输入数据进行加、减、乘、除运算以及液晶1602进行显示。
在实验前我们组先是在网上和图书馆找了一些前辈所设计的计算器方案进行学习参考,一开始认为简易计算器制作起来结构相对简单,涉及的知识也有文献可查询,除了程序繁琐一些,其他都还好。
但在实际制作过程中并不是这么简单,我们遇到了许多问题,不仅仅是专业知识上的问题,还存在组员之间的意见不同等。
最后在老师的指导和组员之间的磨合,都克服了困难,完成了设计。
总的来说,一次课程设计我们不仅将专业知识融会贯通,还提高了动手能力和分工合作,通过课程设计,我们对单片机的认识也有所提升。
参考文献
[1]徐志保,基于工程导向的单片机实战教程.2011
[2]郭天祥,新概念51单片机c语言教程.北京:
电子工业出版社,2009
[3]马忠梅,单片机的C语言应用程序设计.北京:
北京航空航天大学出版社,1997
[4]张毅刚,《单片机原理及应用》.北京,高等教育出版社,2008
[5]谭浩强,C程序设计(第二版)[M].北京:
清华大学出版社,2003
[6]余锡存,曹国华,单片机原理及接口技术.西安:
西安电子科技大学出版社,2000
附录
#include
#include
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharkey,sym,sumsz[13],adders=0;//定义变量
floatsum,number1=0,number2=0;//定义变量
bitflag=0;//定义位变量标志位
sbitlcdrs=P2^0;//定义液晶的读IO口
sbitlcdwr=P2^1;//定义液晶的写IO口
sbitlcden=P2^2;//定义液晶的使能IO口
ucharlcd_s[]={'0','1','2','3','4','5','6','7','8','9','+','-','*',0xfd,'.','='};//
ucharcurpos=0xc0;
voidkeyscan();//函数声明
voiddelayms(ucharz);
voidwrite_com(ucharcom);
voidwrite_data(uchardat);
voidinit();
voiddelay(intz);
bitbuzz();
voidyuans();
voidclear();
/*******主函数******/
voidmain()
{
init();//液晶初始化
while
(1)//循环函数
{
write_com(0x80);
write_data('');
write_data('');
write_data('');
write_data('C');
write_data('a');
write_data('l');
write_data('c');
write_data('u');
write_data('l');
write_data('a');
write_data('t');
write_data('e');
write_data('r');
keyscan();//调用键盘扫描函数
}
}
/******键盘扫面******/
voidkeyscan()
{
uchartemp=0;
P1=0xfe;//第1次判断函数
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(15);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{temp=P1;
adders++;//确定按键按下,执行if函数
switch(temp)
{
case0xee:
key=1;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符1,并记入相加的变量
case0xde:
key=2;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符2,并记入相加的变量
case0xbe:
key=3;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符3,并记入相加的变量
case0x7e:
key=10;write_com(curpos);curpos++;write_data(lcd_s[key]);sym='+';flag=1;break;//显示'+'号,并将sym付'+'
}
while((P1&0xf0)!
=0xf0);//等待按键释放
}
}
P1=0xfd;//第2次判断
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(15);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P1;adders++;//确定按键按下,执行if函数
switch(temp)
{
case0xed:
key=4;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符4,并记入相加的变量
case0xdd:
key=5;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符5,并记入相加的变量
case0xbd:
key=6;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符6,并记入相加的变量
case0x7d:
key=11;write_com(curpos);curpos++;write_data(lcd_s[key]);sym='-';flag=1;break;//显示'-'号,并将sym付'-'
}
while((P1&0xf0)!
=0xf0);
}
}
P1=0xfb;//第3次判断
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(15);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{temp=P1;adders++;//确定按键按下,执行if函数
switch(temp)
{
case0xeb:
key=7;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符7,并记入相加的变量
case0xdb:
key=8;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符8,并记入相加的变量
case0xbb:
key=9;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符9,并记入相加的变量
case0x7b:
key=12;write_com(curpos);curpos++;write_data(lcd_s[key]);sym='*';flag=1;break;//显示'*'号,并将sym付'*'
}
while((P1&0xf0)!
=0xf0);//等待按键释放
}
}
P1=0xf7;//第4次判断
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(15);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{temp=P1;adders++;//确定按键按下,执行if函数
switch(temp)
{
case0xe7:
key=0;write_com(curpos);curpos++;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;}elsenumber2=number2*10+key;break;//显示字符0,并记入相加的变量
case0xd7:
key=14;clear();break;//调用清零函数
case0xb7:
key=15;yuans();flag=1;adders--;break;//调用运算函数
case0x77:
key=13;write_com(curpos);curpos++;write_data(lcd_s[key]);sym='/';flag=1;break;//显示'/'号,并将sym付'/'
}
while((P1&0xf0)!
=0xf0);//等待按键释放
}
}
}
/******液晶******/
voidwrite_com(ucharcom)//液晶写指令程序
{while(buzz());
lcdrs=0;//
lcdwr=0;//
lcden=0;
P0=com;//
_nop_();
_nop_();
_nop_();
_nop_();
lcden=1;//
_nop_();
_nop_();
_nop_();
_nop_();
lcden=0;//
}
voidwrite_data(uchardat)//液晶写数据程序
{
while(buzz());
lcdrs=1;
lcdwr=0;
lcd
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STC89C52 简易 计算器 设计