基于51单片机计算器设计.docx
- 文档编号:16965608
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:26
- 大小:399.09KB
基于51单片机计算器设计.docx
《基于51单片机计算器设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机计算器设计.docx(26页珍藏版)》请在冰点文库上搜索。
基于51单片机计算器设计
单片机设计报告
设计题目:
计算器
学院:
班级:
学生姓名:
指导教师:
成绩:
目录
第1章绪论1
1.1课题简介1
1.2设计目的1
1.3设计任务1
第2章电路结构及工作原理3
2.1总体设计方案3
2.251系列单片机简介3
2.3矩阵按键4
2.4LCD显示5
2.5运算模块6
2.6总设计图6
第3章软件设计7
3.1软件流程图7
3.1.1键盘模块设计流程图7
3.1.2显示模块流程图8
3.1.3计算模块程序流程8
3.2程序设计9
第4章调试与仿真19
4.1C51单片机软件开发系统Keil19
4.2proteus的操作19
结论20
心得体会21
致谢22
参考文献23
第1章绪论
1.1课题简介
当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活还是学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且比较容易出错。
计算器作为一种快速通用的计算工具方便了用户的使用。
计算器可谓是我们最亲密的电子伙伴之一。
本设计着重在于分析计算器软件可开发过程中的环节和步骤,并从时间经验出发对计算器设计做了详细的分析和研究。
单片机由于其微小的体积和极低的成本,广泛的应用于家电、工业控制等领域中。
在工业生产中,单片微型计算机是微型计算机的一个重要的分支,也是颇具生命力的机种。
单片微型计算机简称单片机,特别适用于控制领域,故又称微控制器。
本系统就是充分利用了AT89C51芯片的I/O引脚。
系统以采用51单片机实现能根据实际输入值显示并存储的功能,计算程序是参照课件。
至于数和功能,如果需要可以通过设计扩充系统来实现。
1.2设计目的
通过本次项目设计,应用所学相关知识资料,来完成简易计算器的设计,以达到理论与实际更好相结合进一步提高综合运用所学知识和设计能力的目的。
通过本次设计的训练,可以使我在基本思路和基本方法上对基于51单片机的嵌入式系统有一个比较感性的认识,并具备一定程度的设计能力。
1.3设计任务
在本次的项目设计中,主要完成如下的设计任务:
1、简要阐述单片机技术发展的国内外现状及LCD动态显示和矩阵键盘基本原理。
2、掌握51单片机系列某种产品的最小电路及外围扩展电路的设计方法。
3、完成主要功能模块的硬件电路设计及必要的参数确定;
4、用软件完成原理电路图的绘制;
5、实现+、-、*、%的基本运算,运算结果用液晶进行显示。
第2章电路结构及工作原理
2.1总体设计方案
根据功能和指示要求,本系统选用51单片机为主控机。
通过扩展必要的外围电路接口实现计算的设计。
具体如下:
1、由于要设计的是简单的计算器,可以进行四则运算,为了得到较好的显示效果,采用LCD显示数据和结果。
2、另外键盘包括数字键(0~9)、符号键(+、-、*、/)、清除键和等号键,故采用4*4按键。
3、执行程序:
开机显示字符串,等待键入数值,当键入数值,通过LCD显示,当键入+、-、*、/时计算器在内部执行数值转换和存储,并等待再次键入数值并等待执行等号程序。
整个系统可分为三个主要的功能模块:
一、实时键盘扫描;二、数据转换成显示器显示;三、显示器的动态显示。
其系统结构框图如下:
图2-1系统结构框图
2.251系列单片机简介
AT89C51是51系列单片机的典型产品,以这一代表性的机型进行系统的讲解。
AT89C51单片机包含中央处理器、程序存储器、数据存储器、定时/计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线,其内部结构如图2-2所示:
图2-2AT89C51内部结构图
2.3矩阵按键
键盘是单片机系统中最常用的人机对话输入设备,用户通过按键向单片机输入指令和数据。
键盘控制程序需完成的任务有:
检查是否有按键按下,有键按下时,如无硬件去抖动电路时,应用软件延时方法消除按键抖动;当有多个按键按下时,只响应一个按键,不管持续多长时间,仅执行一次按键功能程序。
现用矩阵按键用作计算器的键盘,其结构图如2-3所示:
图2-3矩阵按键结构图
2.4LCD显示
本电路采用的是LCD液晶显示输出数据。
液晶显示器LM016L液晶显示器如下图所示:
图2-4液晶显示图
2.5运算模块
51单片机是一块芯片集成了CPU、RAM、ROM、定时/计数器和多功能的I/O口。
运算模块由键盘和显示屏组成。
单片机通过按键来实现输入数据和操作方式的控制,在运算过程中,对所设的数据进行四则运算时,首先确定选用的是哪一个运算,若是+或*,则要判断是否会溢出;若是/则要判断除数是否是零。
2.6总设计图
根据对以上各部分的描述,把他们连接在一起,形成如下图所示的总设计图:
图2-5总设计图
第3章软件设计
3.1软件流程图
软件设计和硬件设计一样也由三部分组成,其中包括:
键盘模块、显示模块、计算模块,现分别对这三部分分别介绍。
3.1.1键盘模块设计流程图
矩阵键盘需要初始化,并且分别对其行、列进行扫描,在扫描过程中判断是否有键按下,根据以上要求,键盘模块设计的流程图如图3-1所示:
图3-1键盘模块设计流程图
3.1.2显示模块流程图
本电路采用的是LCD液晶显示输出数据,在流程图中应包括对LCD液晶显示器初始化,取要显示的数据,要是有两位数据需要显示,则在显示完第一位数据后需要进行延迟来显示第二位数据,则根据以上要求,显示模块的流程图如图3-2所示:
图3-2显示模块流程图
3.1.3计算模块程序流程
在计算模块中,必须保证按键按下的数和LCD液晶显示的数保持一致,则需要把+、-、*、/等字符转换成数据,根据以上要求,计算模块的程序流程图如图3-3所示:
附:
A代表按下运算符号前的数,B代表按下运算符后的数。
图3-3计算模块流程图
3.2程序设计
根据3.1节的各部分的软件程序流程图,则编写的C语言程序如下:
#include
#defineuintunsignedint//定义无符号整形
#defineucharunsignedchar//无符号字符
sbitlcden=P2^3;//定义引脚
sbitrs=P2^4;//数据或命令选择端
sbitrw=P2^0;//读或写
sbitbusy=P0^7;//忙或闲标志
chari,j,temp,num,num_1;//定义5个字符标志位
longa,b,c;//a,第一个数b,第二个数c,得数
floata_c,b_c;
ucharflag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号
ucharcodetable[]={
7,8,9,0,
4,5,6,0,
1,2,3,0,
0,0,0,0};
ucharcodetable1[]={
7,8,9,0x2f-0x30,//按键标值0x2f-0x30是将字符转化为数字,与后面的0x30+i抵消,得i值
4,5,6,0x2a-0x30,
1,2,3,0x2d-0x30,
0x01-0x30,0,0x3d-0x30,0x2b-0x30};//0x01是清屏命令
voiddelay(ucharz)//延迟函数
{
uchary;
for(z;z>0;z--)//延时z*y
for(y=0;y<110;y++);
}
voidcheck()//判断忙或空闲就是是否有按键按下
{
do{
P0=0xFF;
rs=0;//指令
rw=1;//读rsrw值为01时,忙标志和地址计数器读出
lcden=0;//E=0,禁止读写
delay
(1);//等待,液晶显示器处理数据
lcden=1;//E=1,允许读写
}while(busy==1);//判断是否为空闲,1为忙,0为空闲
}
voidwrite_com(ucharcom)//写指令函数
{
P0=com;//com指令付给P0口
rs=0;//00写指令无输出
rw=0;
lcden=0;//关闭lcd使能
check();//检验按键
lcden=1;//开启lcd使能
}
voidwrite_date(uchardate)//写数据函数
{
P0=date;
rs=1;//10写数据无输出
rw=0;
lcden=0;//关使能
check();
lcden=1;//使能
}
voidinit()//初始化
{
num=-1;
lcden=1;//使能信号为高电平
write_com(0x38);//功能设置命令:
8位,2行DDRAM的地址
write_com(0x0c);//显示开,光标关,不闪烁
write_com(0x06);//增量方式不移位
write_com(0x80);//检测忙信号//设置访问地址
write_com(0x01);//显示开,光标关,不闪烁
num_1=0;
i=0;
j=0;
a=0;//第一个参与运算的数
b=0;//第二个参与运算的数
c=0;//结果值
flag=0;//flag表示是否有符号键按下,
fuhao=0;//fuhao表征按下的是哪个符号
}
voidkeyscan()//键盘扫描程序
{
P3=0xfe;//11111110
if(P3!
=0xfe)//p3口最低位非0执行
{
if(P3!
=0xfe)
{
temp=P3&0xf0;//保留高4位的按键值
switch(temp)
{
case0xe0:
num=0;//符号列
break;
case0xd0:
num=1;//369列
break;
case0xb0:
num=2;//258列
break;
case0x70:
num=3;//147列
break;
}
}
while(P3!
=0xfe);//下面为判断按键
if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
{
if(j!
=0)
{
write_com(0x01);//清屏命令
j=0;
}
if(flag==0)//没有按过符号键
{
a=a*10+table[num];//到table中取将要显示并参与运算a的值a的初值为'0',结果为输入a值
}
else//如果按过符号键
{
b=b*10+table[num];//b的初值为'0',结果为输入b值
}
}
else//如果按下的是'/'
{
flag=1;//有按键按下标志
fuhao=4;//4表示除号已按
}
i=table1[num];//送显示
write_date(0x30+i);//将数字转化为字符,对应前面的table1中的i-0x30
}
P3=0xfd;
if(P3!
=0xfd)//11111101上次11111110低位向高位移一位以后类似实现行扫描
{
delay(5);//去抖
if(P3!
=0xfd)
{
temp=P3&0xf0;
switch(temp)//判断按键位置下面是四种情况
{
case0xe0:
num=4;
break;
case0xd0:
num=5;
break;
case0xb0:
num=6;
break;
case0x70:
num=7;
break;
}
}
while(P3!
=0xfd);
if(num==4||num==5||num==6&&num!
=7)//如果按下的是'4','5'或'6'
{
if(j!
=0)
{
write_com(0x01);//清屏命令
j=0;
}
if(flag==0)//没有按过符号键
{
a=a*10+table[num];//输入a值
}
else//如果按过符号键
{
b=b*10+table[num];//输入b值
}
}
else//如果按下的是'/'
{
flag=1;
fuhao=3;//3表示乘号已按
}
i=table1[num];//显示找对应的码
write_date(0x30+i);
}
P3=0xfb;//11111011逐行扫描
if(P3!
=0xfb)
{
delay(5);
if(P3!
=0xfb)
{
temp=P3&0xf0;
switch(temp)//判断位置
{
case0xe0:
num=8;
break;
case0xd0:
num=9;
break;
case0xb0:
num=10;
break;
case0x70:
num=11;
break;
}
}
while(P3!
=0xfb);
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
{
if(j!
=0)
{
write_com(0x01);//清屏
j=0;
}
if(flag==0)//没有按过符号键
{
a=a*10+table[num];//参与运算a的值显示
}
else//如果按过符号键
{
b=b*10+table[num];//在表中找对应按下b的值
}
}
elseif(num==11)//如果按下的是'-'
{
flag=1;
fuhao=2;//2表示减号已按
}
i=table1[num];//显示
write_date(0x30+i);//调用写数据函数
}
P3=0xf7;//11110111
if(P3!
=0xf7)
{
delay(5);
if(P3!
=0xf7)
{
temp=P3&0xf0;//保留列按下的值并判断按键位置
switch(temp)
{
case0xe0:
num=12;
break;
case0xd0:
num=13;
break;
case0xb0:
num=14;
break;
case0x70:
num=15;
break;
}
}
while(P3!
=0xf7);
switch(num)
{
case12:
{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
break;
case13:
{//按下的是"0"
if(flag==0)//没有按过符号键
{
a=a*10;
write_date(0x30);
P1=0;
}
elseif(flag==1)//如果按过符号键
{
b=b*10;
write_date(0x30);
}
}
break;
case14:
{j=1;
if(fuhao==1){write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
write_com(0x04);//设置从后住前写数据,每写完一个数据,光标后退一格
c=a+b;//加法
while(c!
=0)
{
write_date(0x30+c%10);//余数放低位
c=c/10;//商放高位
}
write_date(0x3d);//再写"="
a=0;b=0;flag=0;fuhao=0;//标志位清0
}
elseif(fuhao==2){write_com(0x80+0x4f);//光标前进至第二行最后一个显示处
write_com(0x04);//设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
if(a-b>0)
c=a-b;//减法ab大小处理以下
else
c=b-a;
while(c!
=0)
{
write_date(0x30+c%10);
c=c/10;
}
if(a-b<0)
write_date(0x2d);//写“-”
write_date(0x3d);//再写"="
a=0;b=0;flag=0;fuhao=0;
}
elseif(fuhao==3){write_com(0x80+0x4f);
write_com(0x04);
c=a*b;//乘法
while(c!
=0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
elseif(fuhao==4){write_com(0x80+0x4f);
write_com(0x04);
i=0;
c=(long)(((float)a/b)*1000);//除法强制类型转换
while(c!
=0)
{
write_date(0x30+c%10);
c=c/10;
i++;
if(i==3)//设置小数点位数
write_date(0x2e);
}
if(a/b<=0)//结果位小数
write_date(0x30);//先写“0”再“.”
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
}
break;
case15:
{write_date(0x30+table1[num]);flag=1;fuhao=1;}
break;
}
}
}
main()
{
init();
while
(1)
{
keyscan();
}
}
第4章调试与仿真
下面用Keil与porteus仿真软件介绍数字计算器的仿真与调试。
4.1C51单片机软件开发系统Keil
采用KEIL开发的89c51单片机应用程序步骤:
(1)在keil集成开发环境中创建新项目(Project),扩展文件名为.UV2,并为该项目选定合适的单片机CPU器件(本设计采用ATMEL公司下的AT89C51)
(2)用keil的文本编辑器编写源文件,可以是汇编文件(.c),并将该文件添加到项目中去。
一个项目文件可以包含多个文件,除了源程序文件外,还可以是库文件、头文件或文本说明文件。
(3)通过keil的相关选择项,配置编译环境、连接定位器以及Debug调试器的功能。
(4)对项目中的源文件进行编译连接,生成绝对目标代码和可选的HEX文件,如果出现编译连接错误则返回到第2步,修改源文件中的错误后重构整个项目。
(5)对没有语法错误的程序进行仿真调试,调试成功后将HEX文件写入到单片机应用系统的ROM中。
4.2proteus的操作
1.硬件电路图的接法操作
(1).放置选择(删除)元器件
(2).移动元器件(3).缩放视图(4).连接导线(5).仿真,调试
2.单片机系统PROTEUS设计与仿真过程.Proteus强大的单片机系统设计与仿真功能,使它可成为单片机系统应用开发和改进手段之一。
全部过程都是在计算机上通过Proteus来完成的。
其过程一般也可分为三步:
(1)在ISIS平台上进行单片机系统电路设计、选择元器件、接插件、连接电路和电气检测等。
简称Proteus电路设计。
(2)在Keil平台上进行单片机系统程序设计、编辑、汇编编译、代码级调试,最后生成目标代码文件(*.hex)。
简称Proteus源程序设计和生成目标代码文件。
(3)在ISIS平台上将目标代码文件加载到单片机系统中,并实现单片机系统的实时交互、协同仿真。
它在相当程度上反映了实际单片机系统的运行情况。
简称Proteus仿真。
结论
基于单片机的设计至今为止已经进入了令人鼓舞的阶段,在进行了长时间的摸索与设计,使我不仅仅对于单片机软件与硬件的常用设计与功能有所认识,如AT89C51单片机包含中央处理器、程序存储器、数据存储器、定时/计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线,。
键盘控制程序需完成的任务有:
检查是否有按键按下,有键按下时,如无硬件去抖动电路时,应用软件延时方法消除按键抖动;当有多个按键按下时,只响应一个按键,不管持续多长时间,仅执行一次按键功能程序。
还使我对于一项设计研究的制作过程所需要的详细步骤和具体实现方法有了进一步的掌握。
由于我们的初步尝试,当中的缺点是无可非议地存在着。
当然在这次宝贵的设计活动中,经验才是对于我们最大的收获,而且还增强了自身对未知问题以及对知识的深化认识的能力,但是,仅仅是完成了作品还是不可以自我满足的,我们要认真的思考设计过程中遇到的问题,多查资料,将理论与实际相结合思考,并在以后的学习中更要加倍注意犯过的错误。
总之,这次设计从软件编写调试到软硬件联机调试,发现了自己的许多不足,在以后的学习中,我一定会注意。
心得体会
课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为自动化专业的学生来说掌握单片机的开发技术是十分重要的。
我的题目是简易计算器硬软件的设计,对于我们这些工科学生来说,这是一次考验。
怎么才能找到课堂所学与实际应用的最佳结合点?
怎样让自己的业余更接近专业?
怎样让自己的计划更具有序性,而不会忙无一用?
这都是我们所要考虑和努力的。
这次课程设计我学到很多很多的东西,学会了怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。
不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识,掌握了一种系统的研究方法,可以进行一些简单的编程。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,对单片机汇编语言掌握得不够好。
这次课程设计通过自己的努力,同学的帮助,网络资料的收集,最终顺利完成了。
致谢
在这次课程设计的撰写过程中,我得到了许多人的帮助。
首先我要感谢我的老师和同学在课程设计上给予我的指导、提供给我的支持和帮助,这是我能顺利完成这次报告的主要原因,在每次设计遇到问题时老师不辞辛苦的讲解才使得我的设计顺利的进行。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 51 单片机 计算器 设计