单片机原理及应用课程设计报告简易计算器.docx
《单片机原理及应用课程设计报告简易计算器.docx》由会员分享,可在线阅读,更多相关《单片机原理及应用课程设计报告简易计算器.docx(28页珍藏版)》请在冰豆网上搜索。
单片机原理及应用课程设计报告简易计算器
《单片机原理》课程课程设计
题目简易计算器
院(系)信息工程学院
专业班级计算机科学与技术2班
学生姓名
学号
设计地点计算机应用实验室
指导教师
起止时间:
2014年6月3日至2013年6月14日
简易计算器
摘要
当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活还是学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且比较容易出错。
计算器作为一种快速通用的计算工具方便了用户的使用。
计算器可谓是我们最亲密的电子伙伴之一。
本设计是由单片机的最小系统、外接蜂鸣器进行发生控制、4*4的矩阵键盘作为输入设备、LCD显示器作为输出设备。
本系统就是实现+、-、*、/、清屏的2位数的基本运算,运算结果用液晶进行显示。
关键词:
单片机;LCD显示器;矩阵键盘
Simplecalculator
Abstract
Today'ssociety,withthecontinuousimprovementofpeople'smateriallife,electronicproductshasenteredeveryhousehold,whetherlifeorlearning,orentertainmentandrecreationalmosteverythingisinseparablefromelectronicproducts,large,complexcalculationabilityisnotuptothehumanbrain,andrelativelyeasytogetwrong.Calculatorasaquickgeneralcomputingtoolsmakeiteasytousefortheuser.Thecalculatorisoneofourmostintimateelectronicpartner.Thisdesignistheminimumsystembysinglechipmicrocomputerandexternalbuzzercontrol,4*4matrixkeyboardasaninputdevice,LCDdisplayastheoutputdevice.
Thissystemistoimplementthe+,-,*,/,thebasicoperationofclearscreen,operationresultwithLCDdisplay.
KeyWords:
Matrixkeyboard;Singlechipmicrocomputer;LCDdisplay;
1绪论
1.1设计目的
通过本次项目设计,应用所学相关知识资料,来完成简易计算器的设计,以达到理论与实际更好相结合进一步提高综合运用所学知识和设计能力的目的。
通过本次设计的训练,可以使我在基本思路和基本方法上对基于51单片机的嵌入式系统有一个比较感性的认识,并具备一定程度的设计能力。
1.2设计任务
在本次的项目设计中,主要完成如下的设计任务:
1、简要阐述单片机技术发展的国内外现状及LCD动态显示和矩阵键盘基本原理。
2、掌握51单片机系列某种产品的最小电路及外围扩展电路的设计方法。
3、完成主要功能模块的硬件电路设计及必要的参数确定;
4、用软件完成原理电路图的绘制;
5、实现+、-、*、%的基本运算,运算结果用液晶进行显示。
2方案设计及工作原理
2.1总体设计方案
根据功能和指示要求,本系统选用51单片机为主控机。
通过扩展必要的外围电路接口实现计算的设计。
具体如下:
1、由于要设计的是简单的计算器,可以进行四则运算,为了得到较好的显示效果,采用LCD显示数据和结果。
2、另外键盘包括数字键(0~9)、符号键(+、-、*、/)、清除键和等号键,故采用4*4按键。
3、执行程序:
开机显示字符串,等待键入数值,当键入数值,通过LCD显示,当键入+、-、*、/时计算器在内部执行数值转换和存储,并等待再次键入数值并等待执行等号程序。
整个系统可分为三个主要的功能模块:
一、实时键盘扫描;二、数据转换成显示器显示;三、显示器的动态显示。
其系统结构框图如下图2.1所示。
图2.1系统结构框图
3硬件设计
3.1按键模块
键盘是单片机系统中最常用的人机对话输入设备,用户通过按键向单片机输入指令和数据。
键盘控制程序需完成的任务有:
检查是否有按键按下,有键按下时,如无硬件去抖动电路时,应用软件延时方法消除按键抖动;当有多个按键按下时,只响应一个按键,不管持续多长时间,仅执行一次按键功能程序。
现用矩阵按键用作计算器的键盘,其结构图如3.1所示。
图3.1矩阵按键结构图
3.2LCD显示模块
本电路采用的是LCD液晶显示输出数据。
液晶显示器LM016L液晶显示器如下图3.2所示。
图3.2液晶显示图
1602字符型LCM有16个引脚,具体功能如下。
①VSS为电源负极,VCC接5V电源正极。
②V0为液晶显示器对比度调整端,接电源正极时对比度最弱,接电源负极时对比度最高。
③RS为寄存器选择,“1”选择数据寄存器;“0”选择命令/状态寄存器。
④RW为读写操作选择,“1”进行读操作,“0”进行写操作。
⑤E端为使能端,高电平时读取信息,负跳变时执行指令。
⑥D0~D7为8位双向数据端。
向LCD传输数据或指令。
⑦A为背光接正极,K为背光接负极。
3.3蜂鸣器发生模块
当有键按下时单片机就会发声,其利用的是蜂鸣器发生原理,如下图3.3所示。
图3.3蜂鸣器发生图
蜂鸣器的三要素:
频率、周期和方波。
首先通过声音的频率f,求出对应的周期T,然后知道对应的方波。
具体发生操作如下:
给端口高电平;延时半个周期。
给端口低电平;延时半个周期。
此四句话是蜂鸣器保持发声的充要条件,如果缺少一句或是两句,即打破上述平衡,蜂鸣器就不能正常工作。
因此,可以利用这一原理使蜂鸣器间断发声。
3.4总设计图
根据对以上各部分的描述,把他们连接在一起,形成总设计图,如下图3.4所示。
图3.4总设计图
该总设计图主要包括最小系统。
LED显示模块,它主要作用是D0~D7是传输数据,将要显示的数据传输给LCD;RS、RW、E是控制传输的是指令还是数据;VDD、A、VSS、VEE、K则是给LCD提供电力和使其具有背光。
按键模块,它主要作用是按下数字和符号键为显示器提供数据和符号的。
蜂鸣器发生模块,它的主要作用是蜂鸣器的作用是在倒计时结束时响起一段音乐来提醒倒计时已结束。
4软件设计
4.1软件流程图
软件设计和硬件设计一样也由三部分组成,其中包括:
键盘模块、显示模块、计算模块,现分别对这三部分分别介绍。
4.1.1按键模块设计流程图
矩阵键盘需要初始化,并且分别对其行、列进行扫描,在扫描过程中判断是否有键按下,根据以上要求,键盘模块设计的流程图如图3.1所示。
图4.1按键模块设计流程图
4.1.2显示模块流程图
本电路采用的是LCD液晶显示输出数据,在流程图中应包括对LCD液晶显示器初始化,取要显示的数据,要是有两位数据需要显示,则在显示完第一位数据后需要进行延迟来显示第二位数据,则根据以上要求,显示模块的流程图4.2
所示。
图4.2显示模块流程图
4.1.3计算模块程序流程
在计算模块中,必须保证按键按下的数和LCD液晶显示的数保持一致,则需要把+、-、*、/等字符转换成数据,根据以上要求,计算模块的程序流程图如图4.3所示。
附:
A代表按下运算符号前的数,B代表按下运算符后的数。
图4.3计算模块流程图
5实验环境和测试
下面用Keil与porteus仿真软件介绍数字计算器的仿真与调试。
5.1C51单片机软件开发系统Keil
采用KEIL开发的89c51单片机应用程序步骤:
(1)在keil集成开发环境中创建新项目(Project),扩展文件名为.UV2,并为该项目选定合适的单片机CPU器件(本设计采用ATMEL公司下的AT89C51)
(2)用keil的文本编辑器编写源文件,可以是汇编文件(.c),并将该文件添加到项目中去。
一个项目文件可以包含多个文件,除了源程序文件外,还可以是库文件、头文件或文本说明文件。
(3)通过keil的相关选择项,配置编译环境、连接定位器以及Debug调试器的功能。
(4)对项目中的源文件进行编译连接,生成绝对目标代码和可选的HEX文件,如果出现编译连接错误则返回到第2步,修改源文件中的错误后重构整个项目。
(5)对没有语法错误的程序进行仿真调试,调试成功后将HEX文件写入到单片机应用系统的ROM中。
5.2proteus的操作
1.硬件电路图的接法操作:
(1).放置选择(删除)元器件
(2).移动元器件(3).缩放视图(4).连接导线(5).仿真,调试
2.单片机系统PROTEUS设计与仿真过程.Proteus强大的单片机系统设计与仿真功能,使它可成为单片机系统应用开发和改进手段之一。
全部过程都是在计算机上通过Proteus来完成的。
其过程一般也可分为三步:
(1)在ISIS平台上进行单片机系统电路设计、选择元器件、接插件、连接电路和电气检测等。
简称Proteus电路设计。
(2)在Keil平台上进行单片机系统程序设计、编辑、汇编编译、代码级调试,最后生成目标代码文件(*.hex)。
简称Proteus源程序设计和生成目标代码文件。
(3)在ISIS平台上将目标代码文件加载到单片机系统中,并实现单片机系统的实时交互、协同仿真。
它在相当程度上反映了实际单片机系统的运行情况。
简称Proteus仿真。
5.3实物焊接过程中出现的问题
我们在焊接这一过程中花费了不少的精力,这也是因为我们是第一次焊接。
刚开始我们的液晶显示是焊上去的,导致线路密密麻麻,焊接成功后,液晶无显示,蜂鸣器一直发声。
尽管我们问了很多人,但是也无法解决这个问题。
于是我们决定液晶显示器不直接焊上去,而是通过接线连接上去,几次下来,我们最终完成了作品。
虽然显示器能显示,但是只能显示下面的一排,还是无法实现我们想要的功能。
我们才真正意识到实践与理论的还是有很大差距的。
我们需要努力锻炼自己的动手能力。
尽管我们没有焊接成功,但是我们却从中获取了很多经验,这才是本次课程设计的目的所在。
5.4仿真测试结果
两位数的乘法运算如图5.1所示。
图5.1乘法运算图
两位数的加法运算如图5.2所示。
图5.2加法运算图
结论
基于单片机的设计至今为止已经进入了令人鼓舞的阶段,在进行了两周时间的摸索与设计,使我不仅仅对于单片机软件与硬件的常用设计与功能有所认识,如AT89C51单片机包含中央处理器、程序存储器、数据存储器、定时/计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线,。
键盘控制程序需完成的任务有:
检查是否有按键按下,有键按下时,如无硬件去抖动电路时,应用软件延时方法消除按键抖动;当有多个按键按下时,只响应一个按键,不管持续多长时间,仅执行一次按键功能程序。
还使我对于一项设计研究的制作过程所需要的详细步骤和具体实现方法有了进一步的掌握。
由于我们的初步尝试,当中的缺点是无可非议地存在着。
当然在这次宝贵的设计活动中,经验才是对于我们最大的收获,而且还增强了自身对未知问题以及对知识的深化认识的能力,但是,仅仅是完成了作品还是不可以自我满足的,我们要认真的思考设计过程中遇到的问题,多查资料,将理论与实际相结合思考,并在以后的学习中更要加倍注意犯过的错误。
总之,这次设计从软件编写调试到软硬件联机调试,发现了自己的许多不足,在以后的学习中,我一定会注意。
致谢
在这次课程设计的撰写过程中,我得到了许多人的帮助。
首先我要感谢我的老师在课程设计上给予我的指导、提供给我的支持和帮助,这是我能顺利完成这次报告的主要原因,在每次设计遇到问题时老师不辞辛苦的讲解才使得我的设计顺利的进行。
从设计的选题到资料的搜集直至最后设计的修改的整个过程中,花费了老师很多的宝贵时间和精力,在此向导师表示衷心地感谢!
导师严谨的治学态度,开拓进取的精神和高度的责任心都将使学生受益终生!
在此期间,我不仅学到了许多新的知识,而且也开阔了视野,提高了自己的设计能力。
其次,我要感谢帮助过我的同学,他们也为我解决了不少我不太明白的设计难题。
同时也感谢学院为我提供良好的做课程设计的环境。
最后再一次感谢所有在设计中曾经帮助过我的良师益友和同学。
参考文献
[1]张毅.自动化检测技术及仪表控制系统.[M].化学工业出版社,2005.
[2]侯志林.过程控制与自动化仪表.[M].机械工业出版社,2003.
[3]程德福.智能仪器.[M].机械工业出版社,2005.
[4]王俊杰.检测技术与仪表.[M].武汉理工大学出版社,2002.
[5]孟华.工业过程检测与控制.[M].北京航空航天大学出版社,2002.
[6]孙瑜.工业自动化仪表与过程控制.[M].西北工业大学出版社,2003.
[7]蔡萍.现代检测技术与系统.[M].高等教育出版社,2002.
[8]赵新民.智能仪器设计基础.[M].哈尔滨工业大学出版社,1999.
[9]CurtisD.Johnson.ProcseeControlInstrumentationTechnology.[M].科学出版社2002.
[10]周杏鹏.现代检测技术.[M].高等教育出版社,2004.
附录
#include//头文件
#defineuintunsignedint//定义无符号整形
#defineucharunsignedchar//无符号字符
sbitfmq=P1^2;
sbitlcden=P2^3;//定义引脚
sbitrs=P2^4;//数据或命令选择端
sbitrw=P2^0;//读或写
sbitbusy=P0^7;//忙或闲标志
uinttt;
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++);
}
voiddelay500us()
{ucharj;
for(j=0;j<57;j++);//500us基准延时程序
}
voidfmqx()
{
fmq=0;
delay500us();
fmq=1;
delay500us();
}
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执行
{
delay(15);
if(P3!
=0xfe)
{
for(tt=0;tt<220;tt++)
fmqx();
fmq=1;
delay(500);
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)
{
for(tt=0;tt<220;tt++)
fmqx();
fmq=1;
delay(500);
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)
{
for(tt=0;tt<220;tt++)
fmqx();
fmq=0;
delay(500);
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(P2!
=0xf7)
{
delay(5);
if(P3!
=0xf7)
{for(tt=0;tt<220;tt++)
fmqx();
fmq=1;
delay(500);
temp=P3&0xf0;//保留列按下的值并判断按键位置