矩阵键盘简易计算器._第1页
矩阵键盘简易计算器._第2页
矩阵键盘简易计算器._第3页
矩阵键盘简易计算器._第4页
矩阵键盘简易计算器._第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

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

文档简介

1、微处理器系统与接口技术课程实践报告计算器班 级: 学 号: 学生姓名: 指导老师: 日 期: 2014.7.5 *电子与信息工程学院目录1、设计题目:计算器32、设计目的33、计算器总体设计框图34、计算器详细设计过程44.1输入模块44.2键盘输入电路54.3主程序模块65、分析与调试67、运行结果88、结束语88、参考文献89、源程序附录99.1主程序99.2延时函数delay129.3显示函数display129.4键盘扫描函数149.5预定义函数15201、设计题目:计算器2、设计目的 此次课程实践题目是基于单片机简单计数器的设计,本此设计使用的是Intel公司MCS-51系列的805

2、1AH单片机。设计的计算器可以实现2位小数的加、减、乘、除运算以及整数的乘方运算,其中用4*4矩阵键盘来输入待参与运算的数据和运算符;八位数码管动态显示输入待参与运算的数据以及运算后产生的结果,每个硬件模块的调用过程中涉及到了函数入口及出口参数说明,函数调用关系描述等。3、计算器总体设计框图计算器以MCS-51系列的8051AH单片机作为整个系统的控制核心,应用其强大的I/O功能和计算速度,构成整个计算器。通过矩阵键盘输入运算数据和符号,送入单片机进行数据处理。经单片机运算后控制LED数码管的输出。整体框图如图1所示:图3 整体框图本系统硬件主要由矩阵键盘、独立键盘I/O输入输出、数码管显示等

3、主要部分组成。各模块的主要功能如下:(1)矩阵键盘将十六进制编码的数字送到单片机。(2) 单片机扫描键盘信号并接收,对输入的键盘信号进行处理(3) LED以动态扫描的方式移位显示每次输入的数据和最后的运算结果。实践设计的具体流程图如下图2所示:图3 整体流程图4、计算器详细设计过程(处理器型号型号:Intel MCS-51系列8051AH)计算器设计原理图4.1输入模块计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式。为此,我们引入了矩阵键盘的应用,采用四条I/O 线作为行线,四条I

4、/O 线作为列线组成键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4×4个。这种行列式键盘结构能有效地提高单片机系统中I/O 口的利用率,如图3所示:图3 键盘按键4.2键盘输入电路每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和

5、回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。当无按键闭合时,P1.0-P1.3 与P1.4-P1.7 之间开路;当有键闭合时,与闭合键相连的两条I/O 口线之间短路。判断有无按键按下的方法是:第一步,置行线P1.4-P1.7 为输入状态,从列线P1.0-P1.3 输出高电平,读入列线数据,若某一列线为高电平,则该列线上有键闭合。第二步,读入列线值,将该值输出到列线值,之后再读出列线值。综合一二两步的结果,最后键盘最后组合码值可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。4.3主程

6、序模块这次设计共涉及到了处理器、矩阵键盘、独立键盘、数码管显示等主要的模块,在软件主程序中,通过函数的调用实现相应的功能模块处理。通过num=KeyPro()函数的调用实现了将通过4*4矩阵行列反转扫描法得到的数据送入单片机,用于处理器进一步处理数据。因为该课程实践要求计数器具有2位小数的加减乘除运算,所以我们在读取矩阵键盘之后,使用语句sscanf(temp,"%f",&a),该语句的意思是将字符串数组temp中的字符以浮点数的形式输出到变量a,因此键盘输的的数据都被转换成了浮点数,所以可以很方便的实现带小数的加减乘除运算,运算所得结果也是浮点数的形式。在对输出结

7、果输出到数码管的过程中,使用语句sprintf(temp,"%f",a);,该语句的意思是把浮点数变量a输出到字符串数组temp中,此时就可以调用显示函数对字符形式的计算结果进行输出。5、分析与调试在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法。设计的中心思想是把一个复杂应用程序按整体功能划分成若干相对独立的程序模块,各模块可以单独设计、编程和调试,然后组合起来。这种方法便于设计和调试,容易实现多个程序共存,但各个模块之间的连接有一定的难度。根据需要我们可以采用自上而下的程序设计方法,此方法先从主程序开始设计,然后再编制各从属程序和子程序,层层细化逐步求

8、精,最终完成一个复杂程序的设计。这种方法比较符合人们的日常思维,缺点是一级的程序错误会对整个程序产生影响。本次课程设计的计算器主要完成了矩阵键盘的数据或符号输入、数码管动态显示输入值、单片机处理输入的数据、数码管动态显示计算结果。在整个的设计电路中,输入输出的数据均采用字符的形式(tempi=num+'0'(键盘输入)sprintf(temp,"%f",a)(数码管输出);使用在单片机进行数值运算的过程中,数据使用函数sscanf(temp,"%f",&a),即将数据缓冲区的字符型数据转换成浮点型并存到a变量所对应的地址,这样之后

9、在对变量进行加减乘除运算。因为是浮点数运算,所以结果也是浮点数,在输出的时候,小数点也能够输出,从而免去在运算结果中对小数的定位工作。按照上面的思想,在进行小数运算时,输入输出小数并不能正常显示。后来通过和组员一起仔细研究,发现数码管段码中并没有小数点,所以我们在输入数据时将每一个输入的与小数点的ASCII码进行比较(if(num='.')),一旦条件成立,将小数点存入数据缓冲temp8数组中,同时也将小数点的ASCII码存入显示缓冲区TempData8中(定义小数点的段码0x98)。这样之后关于小数点显示问解决题。本次实践所设计的计算器的操作数为浮点型,当两个数参与运算之后,

10、运算结果如果出现小数部分全为0的情况,根据实际应该只显示整数部分,但是实验结果是小数0全显示。但是由于时间关系我们没有调试成功。现提供一个思路:在显示小数点的时候,设置一个for循环,将小数点后的各位与'0'进行比较,如果该位等于0,设置一个新变量自加一次,之后依次比较,新变量记录小数点后0的个数。循环结束之后,将变量值与小数点后的总位数进行比较,如果相等说明小数点后全为0.之后设置一个for循环将小数点后的数据的ASCII全部赋值0。部分程序如下:sprintf(temp,"%f",a); /以字符的形式打印浮点数到临时缓冲区字符数组temp中for(s=

11、0;s<8;s+) /由于打印的是ASCII码值 if(temps=0x2d)/表示负号,数码管显示负号 0x40 TempDatas=0x40;else if(temps=0x2e)/表示小数点,数码管显示小数点 0x98for(j=s+1;j<8;j+)if(tempj=48)k+;if(k=7-s)for(;s<8;s+)TempDatas=0;break;else TempDatas=0x98; else TempDatas=dofly_DuanMatemps-'0'/其他0-9则进行ASCII到数字处理,如当前是'3',用'3

12、'-'0'=3 /'3'的16进制是0x33,'0'的16进制是0x30 7、运行结果 8、结束语经过近一周的努力,终于顺利完成了单片机课程实践-计数器的设计。刚开始,我们头绪不是很清楚,不知道从哪里入手,但通过老师的耐心指导并和同学认真研究设计课题,跑图书馆查资料、确定基本设计方案、对所用芯片功能进行查找、调试、上机仿真等,经历了一次次的困难,却积累了很多宝贵的经验。在整个设计的过程中遇到的问题主要有以下二点,第一:基础知识掌握的不牢固,主要表现在一些常用的电路的形式和功能不清楚,对书本上的内容理解不够透彻。第二:相关知识掌握的不够全面

13、,缺少系统设计的经验。这次设计进一步端了我的学习态度,学会了实事求是,严谨的作风,对自己要严格要求,不能够一知半解,要力求明明白白。急于求成是不好的,我有所感受。如果省略了那些必要的步骤,急于求成,不仅会浪费时间,还会适得其反。我觉得动手之前,头脑里必须清楚该怎么做,这一点是很重要的。就目前来说,我的动手能力虽然差一点,但我想,通过我的不懈努力,在这方面,我总会得到提高。8、参考文献1 C语言程序设计教程/张宗杰主编. -北京:电子工业出版社,2013.82 增强型51单片机与仿真技术/肖金球,冯骥编著. -北京:清华大学出版社,2011.103 49、源程序附录9.1主程序/*- 内容:整数

14、之间运算,含小数运算,有负号运算,-*/#include<reg52.h> /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<stdio.h>#include<math.h>#include"display.h"#include"delay.h"#include"keyboard.h"sbit CF=P25;/unsigned char TempData8; 存储显示值的全局变量/*- 主程序-*/main() unsigned char num,i=0,sign;

15、unsigned char temp8; /最大输入8个 bit firstflag; float a=0,b=0; unsigned char s,j,k=0;Init_Timer0(); /初始化定时器0while (1) /主循环 if(CF=0)num=0x5e; else num=KeyPro();/扫描键盘if(num!=0xff) /如果扫描是按键有效值则进行处理 if(i=0) /输入是第一个字符的时候需要把该行清空,方便观看 for(s=0;s<8;s+) /赋值完成后把缓冲区清零,防止下次输入影响结果TempDatas=0;if(num='+') |

16、(i=8) | (num='-') | (num='x') | (num='/') | (num='=') | (num='')/输入数字最大位数为8或输入符号表示输入结束i=0; /计数器复位if(firstflag=0) /如果是输入的第一个数据,赋值给a,并把标志位置1,到下一个数据输入时可以跳转赋值给b sscanf(temp,"%f",&a);/将字符串数组temp中的字符以浮点数的形式输出到变量a firstflag=1; elsesscanf(temp,"%f&q

17、uot;,&b);/b中存放temp字符数组的各自对应的ASCII码 for(s=0;s<8;s+) /赋值完成后把缓冲区清零,防止下次输入影响结果temps=0; if(num!='=') /判断当前符号位并做相应处理 sign=num; /如果不是等号记下标志位 else firstflag=0; /检测到输入=号,判断上次读入的符合 switch(sign) case '+':a=a+b;break;case '-':a=a-b;break;case 'x':a=a*b;break;case '/

18、9;:a=a/b;break;case '':a=pow(a,b);break;default:break; sprintf(temp,"%f",a); /以字符的形式打印浮点数到临时缓冲区字符数组temp中for(s=0;s<8;s+) /由于打印的是ASCII码值 if(temps=0x2d)/表示负号,数码管显示负号 0x40 TempDatas=0x40;else if(temps=0x2e)/表示小数点,数码管显示小数点 0x98for(j=s+1;j<8;j+)if(tempj=48)k+;if(k=7-s)for(;s<8;s

19、+)TempDatas=0;break;else TempDatas=0x98; else TempDatas=dofly_DuanMatemps-'0'/其他0-9则进行ASCII到数字处理,如当前是'3',用'3'-'0'=3 /'3'的16进制是0x33,'0'的16进制是0x30 sign=0;a=b=0; /用完后所有数据清零 for(s=0;s<8;s+) temps=0; else if(i<8)if(num='.')tempi=num; TempDatai

20、=0x98;i+;else tempi=num+'0'/ TempDatai=dofly_DuanManum;/输出数据 i+; /输入数值累加 9.2延时函数delay#include "delay.h"/*- uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS -*/void DelayUs2x(unsigned char t) while(-t);/*- mS延时函数,含有输入参数

21、 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0255 这里使用晶振12M,精确延时请使用汇编-*/void DelayMs(unsigned char t) while(t-) /大致延时1mS DelayUs2x(245); DelayUs2x(245); 9.3显示函数display#include"display.h"#include"delay.h"#define DataPort P0 /定义数据端口 程序中遇到DataPort 则用P0 替换unsigned char code

22、dofly_DuanMa10=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;/ 显示段码值09unsigned char code dofly_WeiMa=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/分别对应相应的数码管点亮,即位码unsigned char TempData8; /存储显示值的全局变量/*- 显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该

23、值输入2-*/void Display(unsigned char FirstBit,unsigned char Num) static unsigned char i=0; DataPort=0; /清空数据,防止有交替重影 LATCH1=1; /段锁存 LATCH1=0; DataPort=dofly_WeiMai+FirstBit; /取位码 LATCH2=1; /位锁存 LATCH2=0; DataPort=TempDatai; /取显示数据,段码 LATCH1=1; /段锁存 LATCH1=0; i+; if(i=Num) i=0;/*- 定时器初始化子程序-*/void Init_

24、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);9.4键盘扫描函数/*- 内容:矩阵键盘读入-*/#include<r

25、eg52.h> /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include"keyboard.h"#include"delay.h"#define KeyPort P1/*-按键扫描函数,返回扫描键值-*/unsigned char KeyScan(void) /键盘扫描函数,使用行列反转扫描法 unsigned char cord_h,cord_l;/行列值中间变量 KeyPort=0x0f; /行线输出全为0 cord_h=KeyPort&0x0f; /读入列线值 if(cord_h!=0x0f) /先检测有无按键

26、按下 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 | - | |

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

28、reak;/6 case 0xb7:return '-'break;/7 case 0xde:return 7 ;break;/8 case 0xdd:return 8 ;break;/9 case 0xdb:return 9 ;break;/a case 0xd7:return 'x'break;/b case 0xee:return 0 ;break;/c case 0xed:return '.'break;/d case 0xeb:return '='break;/e case 0xe7:return '/'

29、break;/f default:return 0xff;break; 9.5预定义函数#include<reg52.h>#ifndef _DISPLAY_H_#define _DISPLAY_H_#define DataPort P0 /定义数据端口 程序中遇到DataPort 则用P0 替换sbit LATCH1=P22;/定义锁存使能端口 段锁存sbit LATCH2=P23;/ 位锁存extern unsigned char TempData8; /存储显示值的全局变量extern unsigned char code dofly_DuanMa10;/*- 显示函数,用于动

30、态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该值输入2-*/void Display(unsigned char FirstBit,unsigned char Num);/*- 定时器初始化子程序-*/void Init_Timer0(void);#endif/*-REG52.HHeader file for generic 80C52 and 80C32 microcontroller.Copyright (c) 1988-2002 Keil Elektron

31、ik GmbH and Keil Software, Inc.All rights reserved.-*/#ifndef _REG52_H_#define _REG52_H_/* BYTE Registers */sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0;sfr ACC = 0xE0;sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82;sfr DPH = 0x83;sfr PCON = 0x87;sfr TCON = 0x88;sfr TMOD = 0x89;s

32、fr TL0 = 0x8A;sfr TL1 = 0x8B;sfr TH0 = 0x8C;sfr TH1 = 0x8D;sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98;sfr SBUF = 0x99;/* 8052 Extensions */sfr T2CON = 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sfr TL2 = 0xCC;sfr TH2 = 0xCD;/* BIT Registers */* PSW */sbit CY = PSW7;sbit AC = PSW6;sbit F0 = PSW5;sbit

33、RS1 = PSW4;sbit RS0 = PSW3;sbit OV = PSW2;sbit P = PSW0; /8052 only/* TCON */sbit TF1 = TCON7;sbit TR1 = TCON6;sbit TF0 = TCON5;sbit TR0 = TCON4;sbit IE1 = TCON3;sbit IT1 = TCON2;sbit IE0 = TCON1;sbit IT0 = TCON0;/* IE */sbit EA = IE7;sbit ET2 = IE5; /8052 onlysbit ES = IE4;sbit ET1 = IE3;sbit EX1 =

34、 IE2;sbit ET0 = IE1;sbit EX0 = IE0;/* IP */sbit PT2 = IP5;sbit PS = IP4;sbit PT1 = IP3;sbit PX1 = IP2;sbit PT0 = IP1;sbit PX0 = IP0;/* P3 */sbit RD = P37;sbit WR = P36;sbit T1 = P35;sbit T0 = P34;sbit INT1 = P33;sbit INT0 = P32;sbit TXD = P31;sbit RXD = P30;/* SCON */sbit SM0 = SCON7;sbit SM1 = SCON

35、6;sbit SM2 = SCON5;sbit REN = SCON4;sbit TB8 = SCON3;sbit RB8 = SCON2;sbit TI = SCON1;sbit RI = SCON0;/* P1 */sbit T2EX = P11; / 8052 onlysbit T2 = P10; / 8052 only /* T2CON */sbit TF2 = T2CON7;sbit EXF2 = T2CON6;sbit RCLK = T2CON5;sbit TCLK = T2CON4;sbit EXEN2 = T2CON3;sbit TR2 = T2CON2;sbit C_T2 =

36、 T2CON1;sbit CP_RL2 = T2CON0;#endif#ifndef _DELAY_H_#define _DELAY_H_/*- uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS -*/void DelayUs2x(unsigned char t);/*- mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0255 这里使

37、用晶振12M,精确延时请使用汇编-*/void DelayMs(unsigned char t);#endif/*- 名称:矩阵键盘头文件-*/#ifndef _KEYBOARD_H_#define _KEYBOARD_H_/*-按键扫描函数,返回扫描键值-*/unsigned char KeyScan(void); /键盘扫描函数,使用行列反转扫描法/*-按键值处理函数,返回扫键值-*/unsigned char KeyPro(void);#endif/*-MATH.HPrototypes for mathematic functions.Copyright (c) 1988-2002 Ke

38、il Elektronik GmbH and Keil Software, Inc.All rights reserved.-*/#ifndef _MATH_H_#define _MATH_H_#pragma SAVE#pragma REGPARMSextern char cabs (char val);extern int abs (int val);extern long labs (long val);extern float fabs (float val);extern float sqrt (float val);extern float exp (float val);extern float log (float val);extern float log10 (float val);extern float sin

温馨提示

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

评论

0/150

提交评论