目录
第1章 绪 论 ....................................................................................................................... 2
§1.1 设计的意义 .......................................................................................................... 2
§1.2 要解决的问题 ....................................................................................................... 2 §1.3 计算器发展概况 ................................................................................................... 2 第2章 需求分析 ................................................................................................................... 3
§2.1 计算器设计要求 ................................................................................................... 3
§2.2 程序开发环境 ....................................................................................................... 3 §2.3 计算器原理图 ....................................................................................................... 3
§2.3.1 键盘系统分析 ............................................................................................ 4 §2.3.2 LED显示灯系统分析................................................................................... 5
第3章 计算器程序设计......................................................................................................... 7
§3.1 总体设计 .............................................................................................................. 7 §3.2 硬件设计 .............................................................................................................. 7 §3.3 软件设计................................................................................................................ 8
§3.3.1 软件模块划分 ............................................................................................ 8 §3.3.2 软件流程设计 ............................................................................................ 9
第4章 测试分析 ..................................................................................................................10 第5章 总结 .........................................................................................................................12 参考文献 ................................................................................................................................13 附录 .......................................................................................................................................14
第1章 绪 论
§1.1 设计的意义
随着科学技术的飞速发展,单片机具有集成度高、功能强、结构简单、易于掌握、应用灵活、可靠性高、价格低廉等优点,在工业控制、机电一体化、通信终端、智能仪表、家用电器等诸多领域得到了广泛的应用,已成为传统机电设备向智能化机电设备转变的重要手段。单片机的应用正在不断加深,同时带动传统控制检测技术日益跟新。在实时检测和自动控制的单片机系统中,单片机往往作为一个核心部件来使用,仅单片机方面的知识是不够的,还应根据具体硬件结构软硬结合,加以完善。本任务是简易的一位数的四则运算,程序是根据教材内容参考编写而成的,在功能上还不完善,限制也比较多。 §1.2 要解决的问题
计算器以AT89S52单片机为核心芯片,通过扫描键盘来得到数据,将得到数据按要求进行运算并将结果送到显示电路进行显示。 §1.3 计算器发展概况
提起计算器,值得我们骄傲的是最早的计算工具诞生在中国。中国古代最早采用的一种计算工具叫筹策,又叫做算筹,这种算筹多用竹子制成,也有用木头、兽骨充当材料的,约270,枚一束,放在布袋里克随身携带。17世纪初,西方国家的计算工具有了较大的发展,英国数学家纳皮尔发明的“纳皮尔算筹”,英国牧师奥却德法发明了圆柱形对数计算尺,这种计算尺不仅能做加减乘除、乘方、开方运算,甚至可以计算三角函数、指数函数和对数函数,这些计算工具不仅带动了计算机的发展,也为现代计算器的发展奠定了良好的基础,计算器已经成为现代社会应用广泛的计算工具。
第2章 需求分析
§2.1 计算器设计要求
基于AT89S52单片机的简易计算器,采用22.1184MHZ晶振。设计要求如下: (1)计算器能正常显示输入数据和得到的结果
(2)计算器能对1位整数进行简单的加、减、乘、除四则运算,在做除法时能自动舍去小数部分。 §2.2 程序开发环境
1. 硬件:PC 机一台,实验开发板CS-1。
2. 软件 Windows98/XP系统,KEIL集成开发环境,ISP 下载软件。 §2.3 计算器原理图
基于AT89S52单片机的简易计算器由电源电路、单片机主控电路、按键电路、显示电路和复位电路几部分组成,框图组成如图2-1所示。
图2-1 基于AT89S52单片机的简易计算器系统框图
由实验板CS-1电路原理图可知AT89S52的P0端口连接的数码管显示,P2端口连接的是键盘,于是在计算器程序的设计中,我们可以通过定时器调用中断,不断的向P0端口输出电平,来显示我们所要显示的数字。然后通过P2端口来获得键盘的输入。
图2-2 基于AT89S52单片机简易计算器电路原理图
§2.3.1 键盘系统分析
图 3.3.1 键盘结构图
实验板上是一个4*4的键盘矩阵,可以采用逐行扫描或全扫描的方式实现按键的读取,行线和列线加驱动后空载时为高电平,逐行扫描的方法为逐行使行线的每位为低,再判断列线的返回信号,如果没有键按下,返回的信号全为高;如果返回的信号中有列线为低,那么肯定是有按键按下,根据列线和行线的交点可以判断按键的具体位置。
全扫描的方法为先行线全为低,判断列线,如果列线有为低的,则可以判断有键按下,此时还不能判断某列的具体的键和行,还需反过来将列线全为低,再判断具体
的行,根据行列即确定具体的按键。 §2.3.2 LED显示灯系统分析
LED数码管也称半导体数码管,是目前数字电路中最常用的显示器件。它是以发光二极管作笔段并按共阴极方式或共阳极方式连接后封装而成的。图5-41所示是两种LED数码管的外形与内部结构,+、-分别表示公共阳极和公共阴极,a~g是7个笔段电极,DP为小数点。LED数码管型号较多,规格尺寸也各异,显示颜色有红、
绿、橙等。
从上图可以看出,要使数码管显示数字,有两个条件:1、是要在VT端(3.8脚)加正电源;2、要使(a,b,c,d,e,f,g,dp)端接高电平或“1”电平,这样才能显示的。
数码管内部为8个发光二极管,并排列为8字形,同时加一个位表示小数点,通过这8个发光二极管的合理组合,可以构成不同的数字字型和简单的字母字型,同时
数码管还有一个位选信号。即8个数码管的公共端,数码管分为共阳和共阴两种,也就是说高电平选中或低电平选中。
每个数码管都有a、b、c、d、e、f、g七个笔划和一个小数点dp,这八个点对应二极管阳极,阴极都联在一起(称共阴极)。以四位数码管矩阵为例,四个数码管的a、b、c、d、e、f、g七个笔划和一个小数点DP电极分别并联在一起。当c行高电平,3列低电平,其他行列都为高阻态时,第三个数码管的c笔划亮,通过扫描方式在短时间内八个数码管的笔划该亮的都亮一次,由于视觉暂留,就会看到结果。
第3章 计算器程序设计
§3.1 总体设计
主要用到的硬件:AT89S52 LED数码管显示器 编码键盘 硬件分配:
1、 P0、P1口:作为输出口,控制LED数码管显示数据的结果。 2、 P2口:作为输入口,与键盘连接,实现数据的输入。 §3.2 硬件设计 LED数码管显示模块:
图3.2-1实验板LED灯模块
单片机AT89S52P1口接LED的位码,P0口段码,通过计数器0调用中断来显示当前数据,计数时间为20ms。
LED显示器由七段发光二极管组成,排列成8字形状,因此也成为七段显示器。为了显示数字或符号,要为LED显示器提供代码,即字形代码。七段发光二极管,再加上一个小数点位,共计8段,因此提供的字形代码的长度正好是一个字节。简易计算器用到的数字0~9的共阴极字形代码如下表: 显示字型 0 1 2 3 4 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 7EH BEH DEH EEH 7DH h g f e d c b a 段码
5 6 7 8 9 键盘模块设计:
1 1 0 0 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 BDH DDH EDH 7BH BBH 表3.2-1 0~9共阳极字形代码表
图3.2-1键盘模块
单片机P2口连接键盘,通过P2口读取键盘信息。首先利用P2口低字节读取键盘行信息,判断是否有按键被按下,若有则利用P2继续读取高字节信息,然后和低字节的信息相异或得到按键码。获取按键码的程序由单片机主程序循环调用。 §3.3 软件设计
由于本设计主要是算法问题,所以程序采用汇编语言编写。主函数对单片机进行初始化,并不断调用扫描函数和运算函数。显示函数采用20ms定时中断来对显示数据进行实时跟新。 §3.3.1 软件模块划分
程序主要分成显示模块、按键扫描模块、计算模块。基于AT89S52单片机简易计算器程序模块划分及简要流程图如3-3所示。
开始开始中断开始数值转换初始化送显示数据判断计算法则键盘扫描定时器赋初值计算调用运算程序 中断结束显示模块返回数据结束扫描程序模块计算模块
图3.3-1程序模块划分
§3.3.2 软件流程设计
开始选通数码管判断运算符为加否是两数相加,并显示结果扫描键盘否判断运算符为减否判断运算符为乘是两数相乘,并显示结果是两数相减,并显示结果是否有键按下是改变显示数字的值是判断按键是否为数字否否判断按键是否为等号存储操作运算符的信息是否判断运算符为除否按键值存入内存是两数相除,并显示结果
图3.3.2-1 计算器程序流程图
第4章 测试分析
一、对一位数加减乘除四则运算法则的测试: 测试发现问题:
测试1:
输入运算符时,LED数码管没有显示出输入的运算符,而是出现的乱码。 错误代码如下:
cjne a,#0x79,next2 ;判断控制键类型
mov a,buffer ;如果是等号键,将两数相加 add a,buffer_num
mov buffer,#0x00 ;清楚第一个操作数
mov dptr,#dis_number ;查找当前运算结果对应的字符码 movc a,@a+dptr
mov buffer_dis,a ;将当前运算结果的字符码送显示缓冲区
分析源代码后可知,代码中没有判断运算符号的部分,此时也没有有将输入的运算符号送入显示缓存区。于是我们对代码进行修改,加入运算符判断类型的代码,判断之后对执行相应的运算操作。
测试2:
计算器无法实现连加现象。例如:顺序输入1+2= 之后会显示结果为4,然后继续输入+1,结果并不为5。
错误原因分析,在获得结果4之后没有将数据4放入操作数缓存。于是我在等号运算执行后的代码下面加上将计算机结果放入操作书缓存的代码,以此来实现计算器连加的功能。
测试3:
无法识别按键9。 错误代码如下:
;在数码管上显示按下的键
search:
mov temp,r5 ;保存扫描码 mov dptr,#key ;取键盘码数组的地址 mov r6,#0x00 nextone:
clr a
movc a,@a+dptr ;取键盘码
inc dptr inc r6
cjne r6,#0x0A,num_key ;判断是数字还是控制键
分析代码可知,在判断按键是控制键还是数字键的时候,我对按键进行匹配时,将r6会小于0X0A的数字认为是数字键,但是r6的初始值并不为0。所以,应该是r6小
于0x0B的都为数字键。这里将#0x0A改为#0x0B即可
测试4:
对正常一位数的加、减、乘、除进行测试。
若除数为0则出现错误结果,错用一个小数区减大数,仍会出错误结果。除以上两种情况外,其余测试均正常通过。
第5章 总结
课程设计是培养学生运用综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实际能力的重要环节,是对我们实际工作能力的具体训练和考察过程。随着科学技术发展的日新月异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中无处在。作为计算机专业的学生来说单片机的开发技术十分重要。
我做的题目是基于AT89S52单片机的简易计算器设计,对于我们这些实践中的新手来说,这是一次考验。怎样才能找到课堂所学与实践运用的最佳结合点。这都是我们要考虑和努力的。在此次课程设计中,通过老师的精心指导和在网上找的资料,主要掌握了数码管显示的编程,数据在内部运算的编程方法。调试也是此次的重点,这其中最重要的就是软件的调试了,也是我此次问题出现最多的地方。这要求我们对每个模块在整个程序中的作用的了如指掌。通过此次课程设计,我发现我对程序的掌握还不够 ,尤其是单片机汇编语言掌握的不牢固。这次课程设计使我懂得实践的重要性,只有理论知识远远不够,只有把所学的理论知识与实践相结合才能算是掌握了所学的知识。随着就业形势的日趋严峻,大学生的动手能力、实际能力和综合素质越来越受到学校和用人单位的重视。
此次设计单片机十分简易,只实现1位数的加减乘除,并且还有结果不能得到负数和除数不能为0的Bug,所以这次我们设计的计算器是并不实用的,但是同过本次课程设计,使我了解到了如何使用单片机来进行计算器的设计,学会了如何对LED灯进行控制,也学会了如何使用键盘来获得输入的数据,同时提高了我的编码能力。在设计计算器的过程中运动了很多问题,解决了这些问题之后,提高了我们自己动手解决问题的能力。
这次单片机设计中使我对步进机有了更深的了解,对单片机也有了更高层次的了解。单片机编程需要对电路进行认真的分析,然后画出流程图,善于查阅相关资料才能编出好的程序。这次单片机应用系统设计中遇到到很大的困难,主要原因是平时的知识掌握的不够,通过查阅很多资料和类似的论文,才做成的。由于时间仓促,经验少,知识局限,设计有一定的不足。但通过此次设计自己的能力提高了不少,我会认真总结设计中的经验教训,为以后更多的设计做好铺垫。
参考文献
[1] 冯育长主编.单片机系统设计与实例分析.西安:西安电子科技大学出版社,2007 [2] 谢维成,杨加国主编.单片机原理与应用及C51程序设计.北京:清华大学出版社,2006.
[3] 王思明,张金敏主编.单片机原理及应用.兰州大学出版社,2001年
[4] 宋晖,余张国主编。单片机原理与应用。电子科技大学出版社,2008年
附录
程序清单如下:
temp equ 0x10 ; 自定义变量temp,指向片内ram 的10h 地址 buffer_dis equ 0x11 ;显示字符缓冲区 buffer_con equ 0x12 ;控制键缓冲区 buffer_num equ 0x13 ;按键值缓冲区
buffer equ 0x14 ;首个操作数 16 进制值 buffer_opr equ 0x15 ;记录操作运算符 org 0x00 ;程序入口
sjmp start ;跳到主程序执行
org 0x000b ;定时器/计数器0 中断入口 ljmp timer0_over
org 0x30 ;程序代码部分
/******************************************************* 名称: 主程序
功能: 应用程序入口
*******************************************************/ start:
mov sp,#0x30 ;初始化堆栈
mov TL0,#0xD8 ;置定时器初值(中断时间为25ms) mov TH0,#0xF0
mov TMOD,#0x01 ;设定定时器/计数器0 工作方式为 1 setb EA ;允许中断
setb ET0 ;允许定时器/计数器0 溢出中断 setb TR0 ;启动定时器/计数器0 mov buffer_dis,#0x00
mov P1,#0xDF ;打开开?65 个数码管 214365 loop:
acall sea_key
sjmp loop 、
/******************************************************* 名称: 字形码扫描模块
功能: 判断当前按键是数字还是字符,如果是字符;将当前按 键的字形码存入buffer_dis,并且当前按键的十六进制值 存入buffer_num,如果是控制键,将控制键存入buffer_con 如果控制键为不为等号,则将运算符存入buffer_opr 入口: sea_key
*******************************************************/ sea_key:
acall scan ;调用键盘扫描子程序 acall delay
cjne r5,#0xFF,search ;有键按下转到 search sjmp sea_key ;无键按下继续扫描
;在数码管上显示按下的键
search:
mov temp,r5 ;保存扫描码 mov dptr,#key ;取键盘码数组的地址 mov r6,#0x00
nextone: clr a
movc a,@a+dptr ;取键盘码 inc dptr inc r6
cjne r6,#0x0B,num_key ;判断是数字还是控制键 ;控制键处理 con_key:
cjne a,temp,nextone ;与扫描码比较,不等取下一个键盘码 mov a,#0Fh
movc a,@a+dptr ;取对应的数码 mov buffer_con,a ;控制键存入缓冲区
cjne a, #0x71,noequl jmp equl noequl:
mov buffer_opr,a equl:
acall control ;调用控制键处理模块 ret ;数字键处理程序 num_key:
jnc con_key
cjne a,temp,nextone ;与扫描码比较,不等取下一个键盘码 ;相等
mov a,#0Fh
movc a,@a+dptr ;取对应的数码 mov buffer_dis,a ;送显示缓冲区 dec r6
mov buffer_num,r6 ;当前按键的 16 进制值送缓冲区 ret
/******************************************************* 名称: 键盘码扫描模块 功能: 获取当前的按键 入口: scan
返回值:r5:返回当前按键的键值,若无键按下,返回0xFF *******************************************************/ scan:
mov P2,#0xF0 ;扫描低字节
mov a,P2 ;读出当前P2 口值
cjne a,#0xF0,next_key ;不等于输出状态,跳至有键按下状态 sjmp no_down ;扫描结束,跳到无键按下状态 next_key:
mov P2,#0x0F ;扫描高字节
mov r5,P2 ;读出当前P2 口值
xrl a,r5 ;两次读取的值相异或得当前按键的键值 mov r5,a ;当前键值送r5 保存 ret
no_down:
mov r5,#0xFF ;返回无键按下状态 ret
/******************************************************* 名称: 基本延时模块
功能: 利用软件的方法实现延时
入口: delay 返回值:无
*******************************************************/ delay:
mov r3,#0xFF ;传送数据,1t dl2:
mov r4,#0xFF ;传送数据,1t dl1:
nop ;空指令,1t nop ;空指令,1t
djnz r4,dl1 ;不为0 转,为0 顺执,需要2t djnz r3,dl2 ;不为0 转,为0 顺执,需要2t ret ;返回需2t
/******************************************************* 名称: 控制键处理模块
功能: 根据运算符实现两数的加减乘除 入口: control 返回值:无
*******************************************************/ control:
mov buffer_dis,buffer_con ;当前控制键送显示缓冲区 mov a,buffer_con
cjne a,#0x77,next1 ;判断控制键类型,加号 77 A+ 7C B- 39 C* 5E D/ 71 F= mov buffer_dis,#0x77 next1:
cjne a,#0x7C,next2 mov buffer_dis,#0x7C next2:
cjne a,#0x39,next3 mov buffer_dis,#0x39 next3:
cjne a,#0x5E,next4 mov buffer_dis,#0x5E next4:
;mov buffer_dis, cjne a,#0x71,ending mov a, buffer_opr cjne a,#0x77,subex
mov a,buffer add a,buffer_num
mov buffer_num,a
mov buffer,#0x00 mov dptr,#dis_number movc a,@a+dptr
mov buffer_dis,a subex:
mov a, buffer_opr cjne a,#0x7C,mulex
mov a,buffer subb a,buffer_num
mov buffer_num,a
mov buffer,#0x00 mov dptr,#dis_number movc a,@a+dptr
mov buffer_dis,a mulex:
mov a, buffer_opr cjne a,#0x39,divex
mov a,buffer mov b, buffer_num mul ab
mov buffer_num,a
;如果是等号键,将两数相加 ;清楚第一个操作数
;查找当前运算结果对应的字符码 ;将当前运算结果的字符码送显示缓冲区;如果是等号键,将两数相加 ;清楚第一个操作数
;查找当前运算结果对应的字符码 ;将当前运算结果的字符码送显示缓冲区;如果是等号键,将两数相加
mov buffer,#0x00 ;清楚第一个操作数
mov dptr,#dis_number ;查找当前运算结果对应的字符码 movc a,@a+dptr
mov buffer_dis,a ;将当前运算结果的字符码送显示缓冲区 divex:
mov a, buffer_opr
cjne a,#0x5E,ending
mov a,buffer ;如果是等号键,将两数相加 mov b, buffer_num div ab
mov buffer_num,a
mov buffer,#0x00 ;清楚第一个操作数
mov dptr,#dis_number ;查找当前运算结果对应的字符码 movc a,@a+dptr
mov buffer_dis,a ;将当前运算结果的字符码送显示缓冲区
ending:
mov buffer,buffer_num ;如果不是等号键,保存当前输入的数字的十六进制值
ret
/******************************************************* 名称: 定时器0 中断服务程序 功能: 显示显示缓冲区中的字符码 入口: 无 返回值:无
*******************************************************/ timer0_over:
mov P0,buffer_dis
mov TL0,#0xD8 ;重新设定时器/计数器0 初值 mov TH0,#0xF0
reti ;中断服务返回
;********************************************************** ; 预定义数组
;********************************************************* ;键盘扫描码 key: ;按键数码
; 0 1 2 3 4 5 6 7 db 0x7E,0xBE,0xDE,0xEE,0x7D,0xBD,0xDD,0xED
; 8 9 A B C D E F db 0x7B,0xBB,0xDB,0xEB,0x77,0xB7,0xD7,0xE7
dis_number:
db 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F ;十六进制字形数据
; 0 1 2 3 4 5 6 7 8 9 ----- 十进制数 db 0x77,0x7C,0x39,0x5E,0x79,0x71 ;十六进制字形数据 ; A B C D E F ------------------------ 十进制数 end
因篇幅问题不能全部显示,请点此查看更多更全内容