基于STC89C52计算器设计程序已验证.docx
《基于STC89C52计算器设计程序已验证.docx》由会员分享,可在线阅读,更多相关《基于STC89C52计算器设计程序已验证.docx(23页珍藏版)》请在冰点文库上搜索。
基于STC89C52计算器设计程序已验证
目录
1.引言…………………………………………………………….…………….…………….….1
1.1本设计的意义……………………………………………………………..…………...…...1
1.2本设计任务和主要内容…………………………….…………..…………..…………..…….2
2.硬件设计……………………………………………………………………..…………...…...2
2.1系统框图…………………………………….…………...……………………………..3
2.2最小系统…………………………………….……………………………………………..4
2.3矩阵键盘………………………………….….…...………………………………...5
2.4LCD1602硬件设计……………………….…………….………………………………........6
3.软件设计……………………….……..……..…………………………………...7
3.1矩阵键盘扫描原理……………….……..……..…………………………………...8
3.2LCD1602引脚功能时序图……..……..…………………………………...9
3.3计算器流程图……………………….……..……..…………………………………..10
4设计小结………….……..……..…………………………………………………………12
参考文献…………………………………………………..……………………………….……14
附录:
课程设计程序清单…………………………………..………………………………..….15
1.引言
随着社会的发展,科学的进步,人们的生活水平在逐步地提高,尤其是微电子技术的发展犹如雨后春笋般的变化。
电子产品的更新速度快就不足惊奇了。
计算器在人们的日常中是比较常见的电子产品之一,如何使计算器技术更加的成熟,充分利用已有的软件和硬件条件,设计出更出色的计算器,使其更好地为各个行业服务,成了如今电子领域重要的研究课题。
现如今,人们的日常生活中已经离不开计算器了,社会的各个角落都有它的身影,比如商店、办公室、学校……因此设计一款简单实用的计算器会有很大的实际意义。
本设计旨在进一步掌握单片机理论知识,理解嵌入式单片机系统的硬软件设计,加强对实际应用系统设计的能力。
通过本设计的学习,使我掌握单片机程序设计和微机接口应用的基本方法,并能综合运用本科阶段所学软、硬件知识分析实际问题,提高解决毕业设计实际问题的能力,为单片机应用和开发打下良好的基础。
1.1本设计的意义
计算器在人们的日常中是比较常见的电子产品之一,如何使计算器技术更加的成熟,充分利用已有的软件和硬件条件,设计出更出色的计算器,使其更好地为各个行业服务,成了如今电子领域重要的研究课题。
现如今,人们的日常生活中已经离不开计算器了,社会的各个角落都有它的身影,比如商店、办公室、学校……因此设计一款简单实用的计算器会有很大的实际意义。
本设计旨在进一步掌握单片机理论知识,理解嵌入式单片机系统的硬软件设计,加强对实际应用系统设计的能力。
通过本设计的学习,使我掌握单片机程序设计和微机接口应用的基本方法,并能综合运用本科阶段所学软、硬件知识分析实际问题,提高解决毕业设计实际问题的能力,为单片机应用和开发打下良好的基础。
如今可编程控制器是应用面最广、功能强大、使用方便的通用工业控制装置。
人机界面的应用,实现了人机界面与现场互动,降低了集成难度,提高了系统的可靠性。
1.2本设计任务和主要内容
采用LCD1602液晶显示,其特点是:
可以调节其背光亮度,这种显示方式接口,编程虽然有些麻烦,但管理较方便,占用的I/O口资源线也不多。
在计算器运算中,需显示的数字、符号较多,按很据个方面的特点,而后可以发现LCD液晶显示,虽然在价格上的确是稍贵于LED数码管;但数码管在硬件设计电路中,会因线太多、线路复杂而过于繁琐,则舍弃LED数码管,选择LCD1602液晶显示。
本设计旨在进一步掌握单片机理论知识,理解嵌入式单片机系统的硬软件设计,加强对实际应用系统设计的能力。
通过本设计的学习,使我掌握单片机程序设计和微机接口应用的基本方法,并能综合运用本科阶段所学软、硬件知识分析实际问题,提高解决毕业设计实际问题的能力,为单片机应用和开发打下良好的基础。
对字符液晶显示模块的工作原理,如初始化、清屏、显示、调用及外特性有较清楚的认识,并会使用LCD(液晶显示模块)实现计算结果的显示;掌握液晶显示模块的驱动和编程,设计LCD和单片机的接口电路,以及利用单片机对液晶显示模块的驱动和操作;在充分分析内部逻辑的概念,进行软件和调试,学会使用,并能够以其为平台设计出具有四则运算能力简易计算器的硬件电路和软件程。
2.硬件设计
2.1系统框图
如图2.1.1所示,在该设计中采用STC89C52单片机作为核心处理器,因此在电路中首先需要设计的是STC89C52的最小系统。
AT89S52单片机的最小系统电路包含以下几个部分。
单片机供电电路:
STC89C52需要5V供电,在电路图中的VCC和GNG为供电网络标识符;晶振电路电路:
STC89C52需要一个稳定的振荡电路才能正常工作,在该电路中采用24MHZ的晶振作为STC89C52的时钟源;复位电路:
复位电路是单片机正常运行的一个必要部分,复位电路应该保证单片机在上电瞬间进行一次有效的复位,在单片机正常工作时将RST引脚置低。
此外通过一个按键进行手动复位,在单片机运行不正常时使用。
图2.1.1系统框图
2.2最小系统
如图2.2.1所示STC89C52单片机概述:
STC89C52是一个低功耗,高性能CMOS8位单片机,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
STC89C52具有如下特点:
40个引脚,8k的flash存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统。
对51系列单片机来说,最小系统一般应该包括:
单片机、晶振电路、复位电路。
图2.2.1最小系统
2.3矩阵键盘
2.3.1独立按键与矩阵键盘区别
计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会比较简单,但是会占用大量的IO口资源,因此在很多情况下都不采用这种方式。
矩阵键盘扫描程序的优点在于,不用专门的按键延时程序,提高了CPU效率,也不用中断来扫描键盘,节省了硬件资源。
此外,本键盘扫描程序每次扫描占用CPU时最短,不论有键按下或者无键按下都可以在很短的时间完成一次扫描。
因为单片机上面的I/O口有限,所以本设计选用矩阵键盘节省I/O口最为合适。
。
2.3.2矩阵按键电路接口
将矩阵键盘的接口接到单片机所对应的引脚(这里就是根据你的程序来接线了)。
然后就是通过按下按键,松开。
让所按得值显示在LCD1602液晶上面。
在程序的里面输入计算器的头文件,还有一些必要的程序。
则再通过矩阵键盘的按键就可以在LCD1602液晶上面显示简单的(两位数)加减乘除。
2.4LCD1602硬件设计
2.4.1LCD1602简介
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。
液晶显示器有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式计算机、数字摄像机、PDA移动通信工具等众多领域。
LCD1602液晶显示器采用HD44780及其兼容芯片作为点阵式LCD的控制器驱动器,还采用HD44100进行LCD的时分割驱动。
HD44780的内部结构主要包括显示数据RAM(DDRAM)、字符发生器ROM(CGROM)、字符发生器RAM(CGRAM)、指令寄存器IR、数据寄存器DR、地址计数器AC(AddressCounter)和忙标志BF(BusyFlag)等逻辑电路。
1602液晶模块内部的控制器共有11条控制指令,丰富的指令可以完成液晶的时序控制、工作方式设置和数据显示等。
2.4.2LCD1602与单片机接口
根据LCD1602的引脚介绍,把LCD1602上的口对应的引脚接到单片机上面,然后把自己写好的程序烧到单片机里面,进行调试。
(根据3.2的时序图来接线)我自己接线时候是将LCD1602焊接在一个电路板上,在上面添加个调节光度的可调电阻,让LCD1602的背光度随之发生变化。
这里做一些补充下LCD1602可以显示一些数字,字母及温度等符号。
图2.4.2LCD1602引脚图
3.软件设计
3.1矩阵键盘扫描原理
图3.1.1矩阵键盘
输入P1.0P1.1P1.2P1.3=0,扫描P1.4P1.5P1.6P1.7判断高低平。
逐行扫描P1.0=0P1.1P1.2P1.3=1扫描。
逐行扫描P1.1=0P1.0P1.2P1.3=1扫描。
逐行扫描P1.2=0P1.0P1.1P1.3=1扫描。
逐行扫描P1.3=0P1.0P1.1P1.2=1扫描。
依此类推如果扫出低电平,则读出按键。
先复位使行线输出口全为0,给高四位低电平,使其处于列线读取状态。
然后判断低四位电平状况,如果没有键被按下,则表示没有键被按下,如果有键按下的话,行线和列线的交点处就会被导通,就会出现电平变化。
“0c/n”相当于计算器的复位键(清零),“+”就相当计算器的加,“-”就相当计算器的减,“*”就相当计算器的乘,“/”就相当计算器的除,“=”就相当计算器的结果。
3.2LCD1602时序图
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明图3.2.1所示:
第1脚:
VSS为地电源第2脚:
VDD接5V正电源
第3脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极
编号
符号
引脚说明
编号
符号
引脚说明
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
背光源负极
表3.2.1引脚接口说明表
3.3计算器设计
将程序烧到单片机之后,通过Keil进行调试,当然不是一烧到单片机就可以在LCD1602上面显示了,我自己之前也遇到过一些麻烦,不烦与大家分享下。
首先,是你所写的内容是不是显示在LCD1602上面,如果没有显示出来,则可能是你所写的程序是不是所指定的地址错了。
(一般是第一行是0x80,第二行是0xc0)还有计算器的输出的结果会跑到第一行去,这是因为你在主函数前没有先定义下,这样就行了。
以下是本人自己对计算器制作的流程图。
3.4计算器流程图
如图所示3.4.1所示,是制作计算器大概的流程图,首先是判断是否有按键按下,如果有的话,则执行下一步,如果没有的没有的话则退到初始化。
然后输入第一个数值,接着输入运算符,跟着就是输入第二数值,得出结果显示在LCD1602液晶上面。
接着就是清零,为下一次的运算做好准备。
图3.4.1计算器流程图
4.设计小结
经过了三个星期的课程设计,在设计中我们遇到了很多编程问题,最后我们大家齐心合力的攻克一个个难关,我们组做得是计算器的设计,内容包括很多。
运用的函数也很复杂。
测试阶段中发现了几处错误导致程序不能编译,去图书馆查找相关的资料,又同学一起讨论。
通过耐心的分析源代码终于编好了一个完整无误的程序。
在这次的c语言程序设计实习中遇到了现实编程中必然见到的问题通过这些问题的解决积累了编程的实践经验。
在实际的编程操作中发现自己c语言知识的不足,加深了对c语言的理解。
在学习之余体验到收获的感觉.
善于总结,也是学习能力的一种体现,每次完成一个编程任务,完成一段代码,都应当有目的的跟踪该程序的应用状况,随时总结,找到自己的不足,这样所编写的程序才能逐步提高.课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新月异,当今计算机应用在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握计算机开发技术是十分重要的。
通过这次课程设计,我拓宽了知识面,锻炼了能力,综合素质得到较大提高。
安排课程设计的基本目的,在于通过理论与实际的结合、人与人的沟通,进一步提高思想觉悟。
尤其是观察、分析和解决问题的实际工作能力,以便培养成为能够主动适应社会主义现代化建设需要的高素质的复合型人才。
作为整个学习体系的有机组成部分,课程设计虽然安排在一周进行,但并不具有绝对独立的意义。
它的一个重要功能,在于运用学习成果,检验学习成果。
运用学习成果,把课堂上学到的系统化的理论知识,尝试性地应用于实际设计工作,并从理论的高度对设计工作的现代化提出一些有针对性的建议和设想。
检验学习成果,看一看课堂学习与实际工作到底有多大距离,并通过综合分析,找出学习中存在的不足,以便为完善学习计划,改变学习内容与方法提供实践依据。
而这种实际能力的培养单靠课堂教学是远远不够的,必须从课堂走向实践。
这也是一次预演和准备毕业设计工作。
通过课程设计,让我们找出自身状况与实际需要的差距,并在以后的学习期间及时补充相关知识,为求职与正式工作做好充分的知识、能力准备,从而缩短从校园走向社会的心理转型期。
课程设计促进了我系人才培养计划的完善和课程设置的调整。
参考文献
[1]李明.物理学[M].北京:
科学出版社,1977:
58-62.
[2]王健.建筑物防火系统可靠性分析[D].天津:
天津大学,1997.
[3]姚光起.一种痒化锆材料的制备方法[P].中国专利:
891056088,1980-07-03.
[4]王传昌.高分子化工的研究对象[J].天津大学学报,1997,53(3):
1-7.
程序
#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','+','-','*',/,'.','='};//
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)!
=