单片机原理及应用专周报告_第1页
单片机原理及应用专周报告_第2页
单片机原理及应用专周报告_第3页
单片机原理及应用专周报告_第4页
单片机原理及应用专周报告_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机原理及应用课程设计报告设计题目: D题 计算器 系 别 : 电子信息工程 学生姓名: 李 庆 班 级: 1202014 学 号: 29 成 绩: 指导教师: 李寿强、傅林 开课时间: 2014-2015 学年第 一 学期目录摘 要21.引言22.系统方案22.1方案论证与选择22.2单片机及其它器件选型22.3系统整体框图22.4主要技术指标33.硬件设计33.1整个单片机的接口电路33.2最小系统原理图33.3数码管接口电路43.4矩阵键盘接口电路64.软件设计74.1数码管显示程序设计74.2读键输入程序84.3主程序设计84.4Proteus仿真图:105.系统原理图:106.双层

2、PCB制版图117.C程序清单117.1主函数:117.2数码管显示函数:157.3键盘反转扫描函数178.总结体会199.参考文献20摘 要本文运用MCS51单片机系统设计的简易计算器,实现了通过检测不同数字键、功能键的按下,可以进行加减乘除运算。对应每一个数字键按下的同时,数码管显示按下键所对应的值,并显示最后的运算结果。 关键词:简易计算器, 89c51单片机,数码管1. 引言计算器因其功能强大而早已成为人们日常生活中必不可少的工具,最简单的计算器就能实现简单的加减乘除运算,这让人们免去了复杂的计算过程,大大提高了工作效率。随着社会科技的发展和进步,计算器的功能更加完善,不仅能实现简单的

3、运算,还能对复杂的数学问题进行求解。2. 系统方案2.1 方案论证与选择本设计是基于52系列单片机来进行的数字计算器系统设计,可以完成计算器的键盘输入,键盘电路采用4*4矩阵键盘电路,进行加、减、乘、除基本四则运算,并在4位共阴极数码管显示相应的结果;设计电路采用STC89C52单片机为主要控制芯片,利用软件方面使用C语言编程,并用Protues仿真。2.2 单片机及其它器件选型本系统选用以STC89C52C单片机为主控机。通过扩展必要的外围接口电路,实现对计算器的设计。系统模块图如下图2图2-2系统模块图2.3 系统整体框图图2-3 系统模块图2.4 主要技术指标本文利用MCS51单片机系统

4、设计的简易计算器,能够实现以下功能:1)、利用键盘及8位数码管作为计算器的输入及显示模块;2)、能进行加、减、乘、除的基本运算;3)、有清零、数据溢出错误处理3. 硬件设计单片机微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。单片机微型计算机简称单片机,特别适用于控制领域,故又称为微控制器。通常,单片机由单块集成电路芯片构成,内部包含有计算机的基本功能部件:中央处理器、存储器和I/O接口电路等。因此,单片机只需要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。通常,单片机由单个集成电路芯片构成,内部包含有计算机的基本功能部件,中央处理器,存储器和I/O接口电路等。因此,单

5、片机只需要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。随着社会的发展,科学的进步,人们的生活水平在逐步的提高,尤其是微电子技术的发展,犹如雨后春笋般的变化。单片机的应用已经越来越贴近生活,用单片机来实现一些电子设计也变得容易起来。计算器在人们的日常中是比较的常见的电子产品之一。可是它还在发展之中,以后必将出现功能更加强大的计算器,基于这样的理念,本次专周设计是用单片机来设计的计算器。3.1 整个单片机的接口电路P0口通过两个74LS573锁存器用于数码管显示输出以及数码管位选控制;P1口用于4*4矩阵键扫描输入;P22位定义锁存使能端口的段锁存;P23位定义锁存使能端口的位锁存。

6、3.2 最小系统原理图最小系统由震荡电路、复位电路、输入输出设备、电源和单片机芯片组成。图4 最小系统原理图n 复位电路单片机复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。单片机也一样,当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始。复位原理单片机复位时只要保持RST引脚接大于两个机器周期的高电平即可。在单片机启动0.1S后,电容C两端的电压持续充电为5V,这是时候10K电阻两端的电压接近于0V,RST处于低电平所以系统正常工作。当按键按下的时候,开关导通,这个时候电容两端形成了一个回路,电容被短路,所以

7、在按键按下的这个过程中,电容开始释放之前充的电量。随着时间的推移,电容的电压在0.1S内,从5V释放到变为了1.5V,甚至更小。根据串联电路电压为各处之和,这个时候10K电阻两端的电压为3.5V,甚至更大,所以RST引脚又接收到高电平。单片机系统自动复位。图3-2-1 单片机复位电路n 单片机振荡电路外接晶振引脚XTAL1和TXAL2接外部晶振和微调电容的一端。振荡电路的频率就是晶体的固有频率。晶振电路结合单片机内部电路产生单片机所需的时钟频率。晶振提高频率越高,单片机运行速度越快。单片机一切指令的执行都是建立在晶振提供的时钟频率上。图3-2-2 单片机振荡电路3.3 数码管接口电路数码管按段

8、数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(即多一个小数点显示);按能显示多少个“8”可分为1位、2位、4位等等数码管;按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段

9、就点亮。当某一字段的阳极为低电平时,相应字段就不亮。阴极数码管是把所有LED的阴极连接到共同接点com,而每个LED的阳极分别为a、b、c、d、e、f、g及dp(小数点),如下图所示。图中的8个LED分别和上面那个图中的ADP各段相对应,通过控制各个LED的亮灭来显示数字。当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。图3-3-1 共阴极数码管引脚接线l 数码管显示部分的实现:数码管通过PO口输入高低电平控制每个LED灯的亮灭,公共端接地线P0口接1K的上拉电阻。由于并未用到小数点显示,所以DP引脚悬空。图3-3-2 共阴极数码管原理l 数码

10、管与单片机连接图(通过两个74HC573锁存器扩展P0口并驱动数码管段码和位码):图3-3-3 数码管与单片机连接图3.4 矩阵键盘接口电路计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在 这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式。为此,我们引入了矩阵键盘的应用,采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为44个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵

11、的行线和列线分别通过两并行接口和CPU通信。键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。用户设计行列键盘接口,一般常采用3 种方法读取键值。一种是中断式,外两种是扫描法和反转法。中断式:在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地址读取数据线上的状态,判断哪个案件被按下。扫描法:对键盘上

12、的某一行送低电平,其他行为高电平,然后读取列值。若列值中有一位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。反转法:先将所有行扫描线输出低电平,读列值。若列值有一位是低,则表明有键按下,读列值;然后所有列扫描线输出低电平,再读行值。根据读到的值组合就可以查表得到的键码。本次专周我们利用了反转法来对电路进行设计,电路图设计如下:图3-4 4*4矩阵键盘电路图将LED数码管显示电路和键盘接口电路结合起来就是计算器逻辑电路,总体结构如下:51系列单片机系统4*4键盘LCD显示 晶振电路复位电路总体线路原理框图4. 软件设计4.1 数码管显示程序设计数码管由七段发光二极管组成,排列成8字

13、形状,因此也称为七段数码管。为了显示数字或符号,要为数码管提供代码,即字形代码。七段发光二极管,再加上一个小数点位,共计8段,因此提供的字形代码的长度正好是一个字节。简易计算器用到的数字09的共阴极字形代码如下表:图4-1 数字09的共阴极字形代码4.2 读键输入程序为了实现键盘的数据输入功能和命令处理功能,每个键都有其处理子程序,为此每个键都对应一个码键码。为了得到被按键的键码,现使用行列反转扫描法识别按键,扫描原理如下:1、列线输出全为0; 2、读入行线值; 3、行线输出上次读入的值;4、读入列线值; 5、组合 2 种读入值。优点:m*n个按键值需要一次反转(2 次输入输出)就可以检测到结

14、果不管键盘矩阵的规模大小,均进行两次读键,比逐行扫描法简单方便。将各特征编码按希望的顺序排成一张表,然后用当前读得的特征码来查表。当表中有该特征码时,它的位置就是对应的顺序编码;当表中没有该特征码时,说明这是一个没有定义的键码,与没有按键(0xff)同等看待。各按键返回值对应表如下所示: | 1 | 2 | 3 | + | 4 | 5 | 6 | - | 7 | 8 | 9 | * | 0 | C | = | / |4.3 主程序设计首先初始化参数,送LED第一位显示“0”,其他位不显示。然后扫描键盘看是否有键输入,若有,读取键码。判断键码是数字键、清零键还是功能键(“+”“-”“*”“/”“

15、=” ),是数值键则送LED显示并保存数值,是清零键则做清零处理,是功能键则又判断是“=”还是运算键,若是“=”则计算最后结果并送LED显示,若是运算键则保存相对运算程序的键值。运算主程序流程图如下所示:初始化参数清零键LED显示输入数值读取键值状态清零数值送显示缓存开始按键输入?分析键值数字键等待数值输入结果送显示缓存保存结果和功能键根据上次功能键和输入的数据计算结果功能键否是是数字键是清零键是功能键4.4 Proteus仿真图:5. 系统原理图:6. 双层PCB制板图7. C程序清单7.1 主函数:/*- 名称:数码管显示计算器-*/#include /包含头文件 #include#inc

16、ludedisplay.h#includedelay.h#includekeyboard.h/*- 主程序-*/main() unsigned char num,i=0,sign; unsigned char temp8; /最大输入8个 bit firstflag; long a=0,b=0; unsigned char s; TempData0=DuanMa0; Init_Timer0(); /初始化定时器0while (1) /主循环 num=KeyPro(); /扫描键盘 if(num!=0xff) /如果扫描是按键有效值则进行处理 if(i=0) /输入是第一个字符的时候需要把数码管

17、清空,方便观看 for(s=0;s8;s+) /赋值完成后把缓冲区清零,防止下次输入影响结果 TempDatas=0; if(num =C) sign=0;a=b=0; /所有数据清零firstflag=0; i=0; /计数器复位for(s=0;s8;s+) temps=0;TempDatas=0; TempData0=DuanMa0; else if(+=num)| (i=8) | (-=num) | (x=num)| (/=num) | (=num)/输入数字最大值8,输入符号表示输入结束 i=0; /计数器复位 if(firstflag=0) /如果是输入的第一个数据,赋值给a,并把标

18、志位置1,到下一个数据输入时可以跳转赋值给b sscanf(temp,%ld,&a);/从一个字符串输入到变量-格式化输入 /将变量temp的值以整型数格式写入到变量a中 / %d 是格式化符号,其他类似的还有 /%f 浮点数 %c 字符型 %s 字符串 firstflag=1; else sscanf(temp,%ld,&b); for(s=0;s=100000000|a=-10000000) /数据溢出错误处理 TempData0=0x79;TempData1=0x77;TempData2=0x77;TempData3=0x3f;TempData4=0x77; /显示“ERROR”Temp

19、Data5=0x40;TempData6=0x40;TempData7=0x71; /低位显示出“F” else sprintf(temp,%ld,a); /打印十进制到临时缓冲区for(s=0;s8;s+) /由于打印的是ASCII码值 if(temps=0) /所以需要转换,如果为0表示null 数码管上则不能显示,所以赋值0TempDatas=0;else if(temps=0x2d)/表示负号,数码管显示负号 0x40TempDatas=0x40;else TempDatas=DuanMatemps-0;/其他0-9负号则进行ASCII 到 数字处理,如当前是3,用3-0=3 /3的1

20、6进制是0x33,0的16进制是0x30 sign=0;a=b=0; /用完后所有数据清零 for(s=0;s8;s+) temps=0; elseif(i16) tempi=num+0; TempDatai=DuanManum;/输出数据 i+; /输入数值累加 7.2 数码管显示函数:#includedisplay.h#includedelay.h#define DataPort P0 /定义数据端口 程序中遇到DataPort 则用P0 替换/sbit LATCH1=P22;/定义锁存使能端口 段锁存/sbit LATCH2=P23;/ 位锁存unsigned char code Dua

21、nMa20=0x3F,0x6,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF; / 显示段码值09 和 带小数点的段码值09 unsigned char code WeiMa=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/分别对应相应的数码管点亮,即位码unsigned char TempData8; /存储显示值的全局变量/*- 显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三

22、个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该值输入2-*/void Display(unsigned char FirstBit,unsigned char Num) static unsigned char i=0; DataPort=0; /清空数据,防止有交替重影 LATCH1=1; /段锁存 LATCH1=0; DataPort=WeiMai+FirstBit; /取位码 LATCH2=1; /位锁存 LATCH2=0; DataPort=TempDatai; /取显示数据,段码 LATCH1=1; /段锁存 LATCH1=0; i

23、+; if(i=Num) i=0;/*- 定时器初始化子程序-*/void Init_Timer0(void) TMOD |= 0x01; /使用模式1,16位定时器,使用|符号可以在使用多个定时器时不受影响 /TH0=0x00; /给定初值 /TL0=0x00; EA=1; /总中断打开 ET0=1; /定时器中断打开 TR0=1; /定时器开关打开/*- 定时器中断子程序-*/void Timer0_isr(void) interrupt 1 TH0=(65536-2000)/256; /重新赋值 2ms TL0=(65536-2000)%256; Display(0,8);7.3 键盘反

24、转扫描函数/*- 名称:矩阵键盘-*/#include /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#includekeyboard.h#includedelay.h#define KeyPort P1/*-按键扫描函数,返回扫描键值-*/unsigned char KeyScan(void) /键盘扫描函数,使用行列反转扫描法 unsigned char cord_h,cord_l;/行列值中间变量 KeyPort=0x0f; /行线输出全为0 cord_h=KeyPort&0x0f; /读入列线值 &0xf0;/与,将低四位屏蔽 if(cord_h!=0x0f) /先检

25、测有无按键按下 DelayMs(10); /去抖 if(KeyPort&0x0f)!=0x0f) cord_h=KeyPort&0x0f; /读入列线值 KeyPort=cord_h|0xf0; /输出当前列线值 cord_l=KeyPort&0xf0; /读入行线值 while(KeyPort&0xf0)!=0xf0);/等待松开并输出 return(cord_h+cord_l);/键盘最后组合码值 return(0xff); /返回该值/*- 按键值处理函数,返回扫键值 可以根据需要改变返回值 | 1 | 2 | 3 | + | | 4 | 5 | 6 | - | | 7 | 8 | 9

26、| * | | 0 | C | = | / | -*/unsigned char KeyPro(void) switch(KeyScan() case 0x7e:return +;break;/0 按下相应的键显示相对应的码值 case 0x7d:return -;break;/1 case 0x7b:return x;break;/2 case 0x77:return /;break;/3 case 0xbe:return 3 ;break;/4 case 0xbd:return 6 ;break;/5 case 0xbb:return 9 ;break;/6 case 0xb7:retur

27、n =;break;/7 case 0xde:return 2 ;break;/8 case 0xdd:return 5 ;break;/9 case 0xdb:return 8 ;break;/a case 0xd7:return C;break;/b . C case 0xee:return 1 ;break;/c case 0xed:return 4 ;break;/d case 0xeb:return 7 ;break;/e case 0xe7:return 0 ;break;/f default:return 0xff;break; 8. 总结体会为期一周多的单片机课程设计终于结束了

28、,通过紧张的工作,完成了我们的设计任务-51单片机计算器。总的来说,这次课程设计是比较成功的。当然,这其中也经历了许多坎坷,但是在我们小组的坚持不懈下,在老师的细心指导下,在同学们的热情帮助下,最终克服了种种困难,取得了成功。刚开始接到这个计算器的课程设计任务时,因为以前做过类似的题目,于是在脑海中初步构建了编写程序的一些控制程序。但是由于缺乏编写大量程序的经验,不能如行云流水般的将全部的各部分代码写出,于是去网上查找相关资料,了解计算器的输入控制原理、运算处理以及显示的原理。了解之后自己尝试编写程序,在此过程中,其中键盘扫描和动态扫描显示扫描程序困扰了我很久,经过两三天的辛苦工作,终于初步把

29、所需要的程序编好了,于是就用Keil uversion4进行仿真,在仿真期间也发现了许多错误,基本上都是平日容易犯的错误,比如忘记了子程序标号、死循环程序、标点符号的漏写等。经过反复的编译差错,仿真编译通过后,于是开始在Proteus中连接电路,全部接完电路之后将Keil生成的.Hex文件导入进行仿真,发现软件与硬件不能够对应协调工作,于是分别对软件和硬件进行检查,经过反复的仿真调试,并且在同学的帮助和自己对每个子程序进行仿真观察下,终于把初步的程序调试出来了。这就是我调试的经过,看似简单,过程却曲折艰辛:编写软件时我用的是数字和字符串之间的转换来实现数码管各位的分别显示,即把按键扫描到的键值

30、numt加0放到tempi中:tempi=num+0,当数字录入完毕就把字符串将变量temp的值以整型数格式写入到变量a和变量b中:sscanf(temp,%d,&a);sscanf(temp,%d,&b);进行计算后(如:a=a+b),再把十进制数a打印到临时缓冲区: sprintf(temp,%d,a); 方便存储显示值的全局变量TempDatai进行赋值:for(s=0;s8;s+)TempDatas=DuanMatemps-0; /进行ASCII 到 数字 处理但是我们的数码管是8位的,当数据大于65536时,计算结果就会显示不正常,我把a和b的数据类型从int改为long长整型还是不行,最后我把所有的%d

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论