单片机课程设计计算器.docx
《单片机课程设计计算器.docx》由会员分享,可在线阅读,更多相关《单片机课程设计计算器.docx(35页珍藏版)》请在冰豆网上搜索。
单片机课程设计计算器
课程设计说明书
课程设计名称:
单片机课程设计
课程设计题目:
四位数加法计算器的设计
学院名称:
电气信息学院
专业班级:
学生学号:
学生姓名:
学生成绩:
指导教师:
课程设计时间:
2017.10.30至2017.11.5
格式说明(打印版格式,手写版不做要求)
(1)任务书三项的容用小四号宋体,1.5倍行距。
(2)目录(黑体,四号,居中,中间空四格),容自动生成,宋体小四号。
(3)章的标题用四号黑体加粗(居中排)。
(4)章以下的标题用小四号宋体加粗(顶格排)。
(5)正文用小四号宋体,1.5倍行距;段落两端对齐,每个段落首行缩进两个字。
(6)图和表中文字用五号宋体,图名和表名分别置于图的下方和表的上方,用五号宋体(居中排)。
(7)页眉中的文字采用五号宋体,居中排。
页眉统一为:
工程大学本科课程设计。
(8)页码:
封面、扉页不占页码;目录采用希腊字母Ⅰ、Ⅱ、Ⅲ…排列,正文采用阿拉伯数字1、2、3…排列;页码位于页脚,居中位置。
(9)标题编号应统一,如:
第一章,1,1.1,……;论文中的表、图和公式按章编号,如:
表1.1、表1.2……;图1.2、图1.2……;公式(1.1)、公式(1.2)。
课程设计任务书
一、课程设计的任务和基本要求
(一)设计任务(从“单片机课程设计题目”汇总文档中任选1题,根据所选课题的具体设计要求来填写此栏)
1.系统通过4x4的矩阵键盘输入数字及运算符。
2.可以进行4位十进制数以的加法运算,如果计算结果超过4位十进制数,则屏幕显示E。
3.可以进行加法以外的计算(乘、除、减)。
4.创新部分:
使用LCD1602液晶显示屏进行显示,有开机欢迎界面,计算数据与结果分两行显示,支持小数运算。
(二)基本要求
1.有硬件结构图、电路图及文字说明;
2.有程序设计的分析、思路说明;
3.有程序流程框图、程序代码及注释说明;
4.完成系统调试(硬件系统可以借助实验装置实现,也可在Proteus软件中仿真模拟);
5.有程序运行结果的截屏图片。
二、进度安排
第9周,10.30~11.5
1)10.30题目分析,文献查阅
2)10.31方案比较,确定设计方案
3)10.31~11.1硬件电路设计
4)11.2~11.4程序设计,程序调试,系统联调,系统改进
5)11.5课程设计说明书撰写
三、参考资料或参考文献
1.林立,俊亮.单片机原理及应用——基于Proteus和KeilC[M].:
电子工业,2013
2.毅刚,喜元.单片机原理与应用设计[M].:
电子工业,2008
3.马忠梅.单片机的C语言应用程序设计(第5版)[M].:
航空航天大学,2013
4.楼然苗、光飞.51系列单片机设计实例[M].:
航空航天大学,2003
本科生课程设计成绩评定表
专业班级
学号
课程设计题目:
课程设计答辩记录:
(手写)
成绩评定依据:
项目
得分
比例
考勤记录
设计结果
报告撰写
答辩成绩
备注:
成绩评定依据的项目容和项目分值比例可以由老师按指导的专业进行调整,但成绩评定依据的项目数不得少于3项。
最终评定成绩:
指导教师签名:
年月日
第一章设计论证
1.1设计分析
在方案设计过程中,我列出了两种不同的设计方案,分别对应于显示模块和单片机部运算。
显示模块在我的设计中有两种不同的显示方式,分别为数码管显示以及液晶屏显示。
对于数码管显示来说,优点是使用简单,反应速度更快,由于LCD有众多的接口,以及指令,因此在软件上要比数码管复杂。
数码管显示的缺点也比较明显,就是需要占用过多的单片机输出接口,同时,LCD的显示功能更多,也更直观,对于现实生活中的使用也更加舒适。
在综合了以上几点的考虑后,我最终选择了LCD1602液晶显示芯片作为显示模块。
在单片机部运算方面,我的设想也有两种,即支持浮点数运算或只支持整数运算,若只支持整数运算,程序设计势必更加简单易懂,但是出于实用性的考虑,我最终决定了使计算器支持浮点数运算功能。
同时,这也能更好地锻炼我的编程思维能力。
1.2设计方案
按照系统设计的功能的要求,初步确定设计系统由主控模块、显示模块、键盘扫描接口电路共四个模块组成。
主控芯片使用8051系列的AT89C52单片机,其中带有非易失性Flash程序存储器,它是一种高性能、低功耗的8位CMOS微处理芯片,市场应用最多。
显示模块采用LCD1602液晶显示器为主体构成。
键盘电路采用4x4矩阵键盘电路。
整个单片机的接口电路:
P0用于显示输出或LCD1602信号输入,P1口用于键盘扫描输入,P2口用于LCD1602的控制信号输出。
为了驱动系统的各个模块正常协调工作,在软件方面我设计了四大模块,分别为显示、键盘、运算、综合模块,通过综合模块的协调来使其它三大模块正常运行,使计算器能正确运算得出正确结果。
第二章硬件设计
2.1硬件结构与工作原理
AT89C52
显示模块(LCD1602)
键盘扫描输入模块(4*4矩阵键盘)
图2.1硬件结构框图
系统的主体部分由输入、运算、输出模块所组成,对应于图2.1中有,输入模块为键盘扫描输入,输出模块为LCD1602显示,运算模块为单片机。
在系统上电后,单片机初始化,开始运行部程序,在程序运行过程中,通过软件功能来实现按下键盘上特定按键后,执行不同的功能,例如加减乘除,并将数据输出至显示模块(LCD1602)显示。
在运算过程中显示运算数据及符号,运算完成后显示运算结果。
2.2单元电路设计
2.2.1单片机最小系统
单片机最小系统就是支持主芯片正常工作的最小电路部分,包括主控芯片、复位电路和晶振电路。
主控芯片选取AT89C52芯片,因其具有良好的性能及稳定性,价格便宜应用方便。
晶振选取11.0592MHz,晶振旁电容选取20pF。
采用按键复位电路,电阻分别选取100Ω和10K,电容选取10μF。
以下为单片机最小系统硬件电路原理图(图2.2),仿真接线图(图2.3)。
图2.2单片机最小系统硬件电路原理图
图2.3单片机最小系统仿真接线图
2.2.2键盘接口电路
计算器所需按键有:
数字键:
’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’。
功能键:
’+’,’-‘,’*’,’/’,’=’,’C(清零、小数点)’共计16个按键,采用4*4矩阵键盘,键盘的行和列之间都有公共端相连,四行和四列的8个公共端分别接P1.0~P1.7,这样扫描P1口就可以完成对矩阵键盘的扫描,通过对16个按键进行编码,从而得到键盘的口地址,对比P1口的扫描结果和各按键的地址,我们就可以得到是哪个键按下,从而完成键盘的功能。
在Proteus仿真中,我直接使用元件库所有的KEYPAD-SMALLCALC键盘,这种键盘直接实现了4*4键盘的功能,方便使用。
如下图2.4所示。
在按下其中一个键时,其对应的行与列将都会变成低电平,此时,即可通过判断P1口的值来确定输入的是哪一个按键,然后将所取得的按键通过软件来进行接下来的处理、运算等工作。
图2.44*4矩阵键盘
2.2.3LCD1602显示电路
LCD1602简介:
如图2.5所示,1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD是指显示的容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
1602采用标准的16脚接口,其中:
第1引脚:
GND为电源地
第2引脚:
VCC接5V电源正极
第3引脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4引脚:
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5引脚:
RW为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作。
第6引脚:
E(或EN)端为使能(enable)端,高电平
(1)时读取信息,负跳变时执行指令。
第7~14引脚:
D0~D7为8位双向数据端。
第15~16脚:
空脚或背灯电源。
第15引脚背光正极,第16引脚背光负极。
特性
3.3V或5V工作电压,对比度可调
含复位电路
提供各种控制命令,如:
清屏、字符闪烁、光标闪烁、显示移位等多种功能
有80字节显示数据存储器DDRAM
建有192个5X7点阵的字型的字符发生器CGROM
8个可由用户自定义的5X7的字符发生器CGRAM
特征应用
微功耗、体积小、显示容丰富、超薄轻巧,常用在袖珍式仪表和低功耗应用系统中。
操作控制
注:
关于E=H脉冲——开始时初始化E为0,然后置E为1。
图2.5LCD1602硬件原理图
采用LCD1602显示器对计算过程、结果以及提示信息进行显示,在仿真电路中,由于Proteus中并没有LCD1602显示芯片,故采用功能相似的LM016L进行替代,其中LM016L的D0~D7三个输入输出端口接至单片机的P0.0~P0.7口,用来对显示屏输出显示、输出控制指令以及获取状态信息。
单片机的P2.5~P2.7分别与LM016L的RS、RW、E端口相连,用来对显示芯片进行控制。
以下为LCD显示电路的仿真接线图(图2.6)。
图2.6LCD1602(LM016L)仿真接线图
第三章软件设计
3.1系统软件结构
计算结果并显示
开始
初始化参数LCD显示
有键输入?
读取按键
处理
显示
显示操作符,标记操作数1结束
等待按键
显示小数点
是否操作符?
是否数字?
是否第一次按下?
ON/C键
是否为=号?
/
如图3.1所示,系统启动后,执行LCD初始化程序,然后调用LCD显示程序,在屏幕上输出欢迎信息。
接下来调用键盘扫描处理程序,等待按键按下,按下任意键后执行LCD清屏程序,并再次调用键盘扫描处理程序,等待用户输入数据,若用户按下数字键(0~9),则在显示器上显示并且将输入数据保存至数据存储区。
Y
图3.1程序流程图
本次设计采用模块化设计思想,包括主程序和初始化子程序、延时子程序、输出数据子程序、检测是否有按键按下子程序、确定按键子程序、清第一行屏与显示“Welcome”子程序、换算第一个数子程序、运算子程序、显示结果子程序等子程序。
运行程序后,首先调用子程序清屏第一行并显示“Welcome”,清屏第二行并显示“ZCY’sCaculator!
”,然后检测是否有按键按下,如果没有,继续检测,如果按下,则判断是否是加减乘除键被按下,如果是加减乘除被按下,则显示相应的字符并换算出字符前输入的数据和字符后输入的数字,然后检测是否有等号按下,如果有则完成相应的运算并显示相应的结果,然后检测是否有清屏键按下,如果有则清屏,相应的流程图如图3.1所示。
对于数字键的程序段进行相应的设计,如果运算键(+、-,*,/)相应标志不为一,则将输入的数字送入第一个操作数缓存区,并且清空所有响应位。
否则送入第二个操作数缓存区。
其次对功能键的程序段进行相应的设计。
如果功能键(+、-,*,/)第一次被按下,则置相应的标志位为一,并且将运算键响应标志位置一,清空第二个操作数的缓存区,为输入操作数做准备,如果是第二次按下则先调用运算操作子程序,执行上次按下的运算键的运算,置相应的标志位为一,并且将运算键响应标志位置一,清空第二个操作数的缓存区,为输入操作数做准备。
程序上的具体实现:
在单片机上电后,执行两个函数LCD_dsp_string(4,0,"Welcome!
")以及LCD_dsp_string(1,1,"ZCY'sCaculator")输出欢迎信息初始化LCD。
然后执行keyscan()函数判断是否有按键输入,若有则读取按键,否则循环扫描,直到有按键按下。
在获取按键后,判断按键是否为数字,若是,则执行cacul(a)函数,将获取的数字保存为数,然后执行LCD单个字符显示函数LCD_dsp_char(x,y,dat)。
若按键不是数字,则判断是否为操作符,若是,则执行LCD_dsp_char(x,y,dat)显示操作符,然后将flag标志位置1,代表第一个操作数输入结束。
若不是操作符,则判断是否为‘=’,若是,则执行函数Caculator(x,y)函数,计算结果,然后执行LCD_dsp_string(x,y,string)函数,将计算结果显示在屏幕上,然后执行keyscan()函数,等待按下任意键,按下任意键后,再次执行LCD初始化程序。
若不是‘=’,则判断是否是第一次按下清零键,若是,则显示小数点,并再次调用keyscan()函数,获取下一个按键,若不是第一次按下,则再次执行LCD初始化程序。
3.2主要功能子程序设计
开始
3.2.1LCD显示子程序
输入待显示信息
设置LCD显示位置
输出字符串
LCD是否忙碌?
是否为单个字符
输出单个字符
返回
Y
N
YN
图3.2LCD显示子程序流程图
如图3.2所示,当主程序调用了LCD显示程序后,首先判断LCD是否处于忙碌状态,若是,则等待,若不是,则开始设置显示位置,然后判断显示的是单个字符还是字符串,分别实现对单个字符的输出以及对字符串的输出。
之所以对单字符和字符串设置不同的显示函数,是为了实现程序对单片机资源的最优利用,因为单字符只占据一个字节的存储区,而字符串则至少占用两个字节。
在显示完成后,返回主程序,继续执行下一步。
LCD的显示程序中主要的部份为LCD显示位置的设置以及LCD显示数据的输出。
为此,我编写了LCD显示位置设置函数,以及LCD显示函数,如下。
LCD显示位置设置函数:
voidLCD_set_xy(unsignedcharx,unsignedchary)//设置LCD显示的位置
{
unsignedcharaddress;
if(y==0)//y=0为第一行
address=0x80+x;//x=0为一行的第一个
else//第二行
address=0xc0+x;
write_(address);//设置数据指针位置,调用LCD写命令函数
}
LCD显示函数:
voidLCD_dsp_char(unsignedx,unsignedchary,unsignedchardat)
//单个字符显示函数
{
LCD_set_xy(x,y);//调用LCD显示位置设置函数,设置显示位置
write_data(dat);//写入待显示数据,调用LCD写数据函数
}
voidLCD_dsp_string(unsignedcharX,unsignedcharY,unsignedchar*s)
//字符串显示函数
{
LCD_set_xy(X,Y);//调用LCD显示位置设置函数
while(*s)//当字符串未到达结尾('\0')时,循环输出单个字符
{
write_data(*s);
s++;//指向下一个字符
}
}
3.2.2键盘扫描处理子程序
扫描P1口
返回按键值
是否检测到按键?
开始
N
Y
图3.3键盘扫描处理子程序流程图
如图3.3所示,当调用了键盘扫描处理子程序后,首先,为P1口赋值,然后等待,判断P1口的值是否变化,若变化,根据变化后的值,来判断按下的键值为多少;若P1口的值未发生变化,则循环扫描P1口的值,直到有按键按下导致P1口的值发生变化。
在扫描到按键值后,将按键值保存在全局变量n中,以便其他函数使用、处理该值。
在我编写的程序中,例如下列程序段,我定义了一个临时变量temp来比较该值与给定值,来判断是否有键按下从而导致P1口的值发生变化。
voidkey_scan(void)//键盘扫描处理子程序
{
unsignedchartemp;//定义临时变量temp保存P1的值
P1=0xfe;//为P1赋值,选中第一行
if(P1!
=0xfe)//P1发生变化
{
delay(200);//延时200us
if(P1!
=0xfe)//再次判断(消抖)
{
temp=P1&0xf0;//判断是哪一列
switch(temp)
{
case0xe0:
n='c';break;//第一列
case0xd0:
n='0';break;//第二列
case0xb0:
n='=';break;//第三列
case0x70:
n='+';break;//第四列
}
}
while(P1!
=0xfe);//等待,直到按键松掉
}
……
}
3.2.3运算子程序
接收操作数a,b,fh
a>9999?
fh=’*’?
fh=’-’?
fh=’+’?
a=a+b
a=a-b
a=a*b
a=a/b
fh=’/’?
输出错误提示信息
输出计算结果
返回
Y
图3.4运算子程序流程图
如图3.4所示,在取得操作数一、操作数二、运算符后,判断操作符的性质,然后根据操作符来进行加减乘除的计算,将计算结果保存在a中,并判断计算结果的值是否超过四位数,若超过,则在屏幕上输出错误提示信息,否则在屏幕上输出正确结果。
a中的值可以直接作为下次计算的第一个操作数,即下次输入的是运算符加减乘除的话,之后输入的就是第二个操作数,否则,需要清零再输入两个数进行下轮计算。
在我的程序中,我设置了较多的标志位,比如fuhao为负号标志,xsd为小数点标志,dh为等号标志,flag为操作数标志。
以下是我的计算子程序的节选。
switch(fuhao)//判断操作符是哪个
{
case'+':
a=a+b;break;//加
case'-':
a=a-b;break;//减
case'*':
a=a*b;break;//乘
case'/':
a=a/b;break;//除
}//计算
if(a>9999)//判断结果是否超过四位数
{
sprintf(temp,"%s","Error");
LCD_dsp_string(0,1,temp);//若结果超过四位数则输出错误信息
n=17;
do
{
key_scan();
}while(n==17);//等待按键
write_(0x01);//清屏
a=b=0;//操作数清零
fuhao=0;//操作符清空
flag=0;//第一个操作数
i=0;
j=0;
dh=0;//等号清空
xsd=0;//小数点清空
fh=0;//将各个标志位恢复初始化
}
……
}
第四章系统调试与分析
4.1调试过程与结果
本次课程设计中,我使用了Proteus作为硬件仿真软件,Keil作为软件编写编译软件,通过两者的协调,来实现仿真模拟。
在Keil中编写并编译好程序后,导入到Proteus中,然后开启仿真,使单片机运行,LCD上显示出提示信息,如图4.1所示。
按下任意键后LCD清屏,如图4.2所示。
图4.1欢迎界面图4.2清屏
在第一次计算中,我输入了9999+1的运算式,按照正常的要求,输出结果应为‘E’,然而,我的输出却是一个错误的计算结果,如图4.3所示,经过检查后,我发现了程序中的错误,是操作数的定义出现了问题,我定义的操作数是无符号字符型,所以导致在计算过程中发生了溢出,最后生成了错误的计算结果。
然后我修改了程序,将操作数的定义改为了单精度浮点型,然后再次运行。
图4.3错误输出图4.4正确输出警告信息
进行第二次运算。
在这次运算中,我再次输入了上次的运算式,结果不负所望,输出为‘E’,如图4.4所示。
经过修改,结果已经正确。
最后,我猜测,在我改进程序之前,由于操作数的数据类型弄错了,所以可能导致其他运算的结果可能也是错误的。
进行第三次运算。
输入第一个操作数,我输入的是1.25,如图4.5所示,同时,在我的设计中,将清零键与小数点键设置成了同一个键,以满足4*4键盘要求。
在同一个操作数中按下两次ON/C键的话,会使屏幕清屏,数据清零,如图4.2所示。
然后输入操作符,我输入的是乘号,如图4.5所示。
然后输入第二个操作数,我输入的是352.7,如图4.5所示,输入等号后,在LCD的第二行输出了计算结果,经过验算,发现结果正确。
图4.5正确运行结果
图4.64*4键盘图4.7上拉电阻
如图4.6所示,矩阵键盘的8个端口接至P1口,在按下按键后,按键对应的行列端口均变为低电平,由此即可判断出按下的是哪个按键。
如图4.7所示,为上拉电阻,在51单片机中,P0口开漏端口,因此需要外接上拉电阻来接负载,这样才能正常的进行输入输出的高低电平变化。
4.2结果分析
在输入计算表达式后,系统成功得出了正确的计算结果,并且由于溢出判断的存在,保证了计算结果不会超出四位数,满足了设计要求。
第五章设计小结
课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为电子信息工程专业的学生来说掌握单片机的开发技术是十分重要的。
我的题目是4位加法计算器,对于我们这些实践中的新手来说,这是一次考验。
怎么才能找到课堂所学与实际应用的最佳结合点?
怎样让自己的业余更接近专业?
怎样让自己的计划更具有序性,而不会忙无一用?
这都是我们所要考虑和努力的。
经过查找资料,编写程序,加深了对单片机的了解与认识。
经过本次的实验设计学习,又一次深刻感受到了51单片机虽然已经过去几十年,现在也不断地收到16位、32位低价单片机的冲击,但仍然是一款性能优越的单片机,在处理生活中常用的简单任务时,51单片机依然能够焕发出青春般