当前位置:文档之家› 模拟计算器

模拟计算器

智能仪器仪表课程设计报告摘要 (3)关键词 (3)说明 (3)一.设计功能及工具 (4)1.1设计功能 (4)1.2单片机AT89C51简介 (4)1.3 LED数码显示管简介 (7)1.4输入设备键盘 (7)二.电路设计 (8)2.1时钟电路 (8)2.2复位电路 (9)2.3显示驱动电路 (9)2.4蜂鸣器提示电路 (10)2.5总电路原理图 (10)三.C设计和运行 (12)3.1 C程序代码 (12)3.2 Keil C调试运行 (18)3.3 Proteus 操作运行 (19)四.Proteus 仿真演示 (20)4.1加法演示 (20)4.2减法演示 (21)4.3乘法演示 (22)4.4除法演示 (23)五.总结 (24)参考文献 (24)摘要本设计一简易的模拟计算器程序,实现基本的加减乘除的运算并将结果显示在相应的LED上,且在数字信息输入完毕时有声音提示。

此次设计利用proteus 7 professional 软件绘制电路原理图,在Keil C平台上实现C语言程序编制,最后联立proteus和Keil C实现仿真设计成果。

采用了4X4矩阵式键盘输入,8位LED动态显示,避免了I/O口扩展使程序简化。

利用的AT89C51单片机,八个引脚用来扫描键盘的输入,八个引脚用来驱动八位LED显示,八个引脚用作八位LED的位选信号。

当显示器输出大于八位时,可在剩下的I/O口中任意选一个用来使扬声器发出声音警报。

关键词:AT89C51 、计算器、proteus、Keil C说明本次模拟计算器程序小组共2人:耿莎莎(我)和黄洁雯。

其中,我主要负责Proteus 和Keil C软件的下载并学习用法;利用Proteus绘制电路原理图;成功无错误地运行C程序并联立Proteus仿真计算器成果。

鉴于程序运行无错误无警告,然而仿真徒有信号无法输入显示,遂求教于指导老师,以期发现并改正按键键盘输入程序来使仿真成果实现。

一.设计功能及工具1.1设计功能1.计算器最多只能显示8位数字,开机运行时,只有数码管最低位显示为“0”,其余位不显示。

2.具有4X4键盘,分别表示0~9、+、-、×、/、=和清零键CL,输入的数字从设计的键盘输入。

3.可以对计算结果小于256的两个无符号数进行加、减、乘、除运算,并显示计算结果。

4.结果溢出时发出“嘀”警报声。

1.2单片机AT89C51简介图1-1 AT89C51 元件图芯片AT89C51的外形结构和引脚图如所示。

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。

该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。

由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。

1.主要特性:8051 CPU与MCS-51 兼容4K字节可编程FLASH存储器(寿命:1000写/擦循环)全静态工作:0Hz-24KHz三级程序存储器保密锁定128*8位内部RAM32条可编程I/O线两个16位定时器/计数器5个中断源可编程串行通道低功耗的闲置和掉电模式片内振荡器和时钟电路2.管脚说明VCC:供电电压(图中未画出)GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。

当P1口的管脚第一次写1时,被定义为高阻输入。

P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。

P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。

在FLASH编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。

并因此作为输入时,P2口的管脚被外部拉低,将输出电流。

这是由于内部上拉的缘故。

P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。

在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。

P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。

当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。

作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。

P3口也可作为AT89C51的一些特殊功能口,如下表所示:管脚备选功能P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 /INT0(外部中断0)P3.3 /INT1(外部中断1)P3.4 T0(记时器0外部输入)P3.5 T1(记时器1外部输入)P3.6 /WR(外部数据存储器写选通)P3.7 /RD(外部数据存储器读选通)P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。

当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。

在FLASH编程期间,此引脚用于输入编程脉冲。

在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。

因此它可用作对外部输出的脉冲或用于定时目的。

然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。

如想禁止ALE输出可在SFR8EH 地址上置0。

此时, ALE只有在执行MOVX,MOVC指令时才起作用。

另外,该引脚被略微拉高。

如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。

在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。

但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。

注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。

在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出引脚。

1.3LED数码显示管简介LED,发光二极管,是一种固态半导体器件,它可以直接把电转化为光。

LED的心脏是一个半导体的晶片,晶片的一端附在一个支架上,一端是负极,另一端连接电源正极,使整个晶片被环氧树脂封装起来。

半导体晶片由两部分组成,一部分是P型半导体,在它里面空穴占主导地位,另一端是N性半导体,在这边主要是电子。

但这两种半导体连接起来的时候,它们之间就形成一个“P-N”结。

当电流通过导线作用于这个晶片的时候,电子就被推向P区,在P区里空穴与电子复合,然后就会以光子的形式发出能量,这就是LED发光的原理。

而光的波长也就是光的颜色,是由形成P-N结的材料决定的。

LED的内在特征决定了它是最理想的光源去代替传统的光源,它有着广泛的用途。

七段LED有7个发光二极管按“日”字形排列,所有二极管的阴极或阳极连在一起。

当某个发光二极管的阴极接低电平或阳极接高电平时,对应二极管点亮,根据不同的组合,形成不同的字符0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f。

LED具有动态和静态显示之分。

动态是一个字位一个字位各只LED轮流点亮,由于每个字位停留小于人的视觉,就好像LED是点亮的。

LCD显示器有分段式和点阵式两种结构。

LCD是一种被动显示器,由于它的功耗极低,抗干扰能力强,因而在低功耗的单片机系统中大量运用。

1.4输入设备键盘介绍键盘是由若干按键组成的开关矩阵,能实现简单的人机对话。

与计算机系统的键盘有两类:一类是编码键盘,即键盘上闭合键的识别由专门硬件来实现;另一类是非编码键盘,即键盘输入及闭合键的识别由软件来完成。

图1-2 输入按键开关键盘二.电路设计2.1时钟电路本设计采用内部时钟产生方式。

内部震荡方式所得的时钟信号比较稳定。

在XTAL1和XEAL2两端跨接晶体或陶瓷谐振器,与内部反相器构成稳定的自激振荡器。

晶振选用的12MHZ的内部震荡方式,电路如图:电容器C1、C2起稳定振荡频率,快速起振的作用,电容值取33P。

图2-1 内部震荡结构图2.2复位电路采用上电+按键复位电路,如下图,上电后,由于电容充电,使RST持续一段高电平时间。

当单片机已在运行之中时,按下复位键也能使RST持续一段的高电平,从而实现上电加开关复位的操作。

C3选择30uF,R2选择10K。

这不仅能使单片机复位,而且还能使单片机的外围芯片也同时复位。

图2-2 复位电路图2.3显示驱动电路数码管发光需要一定的电流,但单片机本身不可能提供足够的电流,即拉电流和灌电流不能满足要求,所以想要数码管正常发光,就要加适当的驱动电路。

首先考虑数码管的断码输出端,单片机的P0口可带8个TTL负载,而其他的I/O口只能带4个TTL负载,所以采用P0口作数码管的断码输出端,但P0口是集电极开路输出,要想输出拉电流,必须加上拉电阻,提高驱动能力,电路如图洗啊所示。

图2-3 显示驱动电路图2.4蜂鸣器提示电路在89s52的p3.6连一个蜂鸣器,在输入8位数后,再输入数时,从p3.6脚输入一低电平,并延时一定时间,蜂鸣器发出一“嘀”的声音,提示使用者输入已达8位数。

为限制电流,在电路中加一限流电阻。

图2-4 蜂鸣器电路图2.5电路原理图所需元件清单:元件代号器件名称数量AT89C51 AT89C51 1BUTTON 按键17 RES 电阻 2CAP 电容 37SEG-MPX8-CA-BLUE LED数码显示管 1CRYSTAL 晶振 1RESPACK-8 拉电阻 1SOUNDER 蜂鸣器 1 最终,总的电路原理图如下:图2-5 电路原理图三.C设计和运行3.1 C程序代码#include<reg51.h>#include<absacc.h>sbit P1_0=P1^0;sbit P3_5=P3^5;sbit P3_6=P3^6;sbit P3_7=P3^7;sbit P3_4=P3^4;unsigned int num0,result;unsigned int number,num1;unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};unsigned char dispbuf[8]={0,16,16,16,16,16,16,16};unsigned char disp[8]={0,16,16,16,16,16,16,16};unsigned char dispbitcount;unsigned char temp;unsigned char i,j;unsigned char key;unsigned char keypres;unsigned char yunsuanfu; /***运算标志符/bit alarmflag; /***溢出报警标识符**/bit eq;void rresult() /**拆分result并送入显示数组***/{ i=0;number=result;if(number<0) alarmflag=1;else { for(i=0;i<9;i++){ if(number==0) break;else dispbuf[i]=number%10;number/=10;}}}/******运算num1值*******/unsigned long int calcul(){ switch(yunsuanfu){case 1:result+=num1;return(result);break;case 2:result-=num1;return(result);break;case 3:result*=num1;return(result);break;case 4:result/=num1;return(result);break;default:yunsuanfu=0;}}/***********************/unsigned long int num1process(unsigned char *p,unsigned char count) { num0=*p;while(count-1>0){ for(i=0;i<count-1;i++)*(p+count-1)=(*(p+count-1))*10;num0+=*(p+count-1);count--;}return(num0);}/*******************/void reset(void){for(i=0;i<8;i++){ dispbuf[i]=disp[i];}keypres=0;}/********************/void change(unsigned char *p,unsigned char count){while(count>0){*(p+count)=*(p+count-1);count--;}dispbuf[0]=key;}/*****中断动态显示LED*****/void t0(void) interrupt 1{TH0=(65536-4000) / 256;TL0=(65536-4000) % 256;P2=dispbitcode[dispbitcount];P0=dispcode[dispbuf[dispbitcount]];dispbitcount++;if (dispbitcount==8) dispbitcount=0;if (alarmflag==1){ for(i=0;i<50;i++){ P1_0=~P1_0;for(j=0;j<50;j++);}} alarmflag=0;}void main(void){TMOD=0x01;TH0=(65536-3000) / 256;TL0=(65536-3000) % 256;TR0=1;ET0=1;EA=1;/*********扫描1*********/while(1){P3=0xff;P3_4=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=100;j>0;j--)temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e: key=7; break;case 0x0d: key=8; break;case 0x0b: key=9; break;case 0x07: key=10; break;}/******加法*****/if (key==10){yunsuanfu=1;result=num1process(dispbuf,keypres);reset();}if (key>=7&&key<10){keypres++;if(keypres==1) dispbuf[0]=key;else if(keypres<9)change(dispbuf,keypres);else if(keypres>8) alarmflag=1;}temp=P3;temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f;}}}P3=0xff; /*****扫描2*****/P3_5=0;temp=P3;temp=temp & 0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=100;j>0;j--);temp=P3;temp=temp & 0x0f;if(temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e: key=4; break;case 0x0d: key=5; break;case 0x0b: key=6; break;case 0x07: key=11; break;}if(key==11) /****减法****/{yunsuanfu=2;result=num1process(dispbuf,keypres);reset();}if ((key>=4)&&(key<7)){keypres++;if(keypres==1) dispbuf[0]=key;else if(keypres<9)change(dispbuf,keypres);else if(keypres>8) alarmflag=1;}temp=P3;temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f;}}}P3=0xff; /******扫描3****/P3_6=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=100;j>0;j--);temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e: key=1; break;case 0x0d: key=2; break;case 0x0b: key=3; break;case 0x07: key=12; break;}/*******乘法******/if(key==12){yunsuanfu=3;result=num1process(dispbuf,keypres);reset();}if((key>=1)&&(key<4)){keypres++;if(keypres==1) dispbuf[0]=key;else if(keypres<9)change(dispbuf,keypres);else if(keypres>=9) alarmflag=1;}temp=P3;temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f;}}}P3=0xff; /*******扫描4*****/P3_7=0;temp=P3;temp=temp & 0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=100;j>0;j--);temp=P3;temp=temp & 0x0f;if(temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e: key=0; break;case 0x0d: key=13; break;case 0x0b: key=14; break;case 0x07: key=15; break;}if (key==15) /****除法***/{yunsuanfu=4;result=num1process(dispbuf,keypres);reset();}if(key==14) reset(); eq=0;if(key==13){if(eq!=1){num1=num1process(dispbuf,keypres);reset();calcul();rresult();}}if(key==0&&keypres!=0){ keypres++;if(keypres<9)change(dispbuf,keypres);if(keypres>8) alarmflag=1;}temp=P3;temp=temp & 0x0f;while(temp!=0x0f){ temp=P3;temp=temp & 0x0f;}}}}}3.2 Keil C调试运行(1)在keil 集成开发环境中创建新项目(Project),扩展文件名为.UV2,并为该项目选定合适的单片机CPU器件(本设计采用ATMEL 公司下的AT89C51)(2)用keil的文本编辑器编写源文件,可以是汇编文件(.ASM),并将该文件添加到项目中去。

相关主题