基于AT89C51单片机简易计算器的设计

更新时间:2023-04-29 13:15:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《微机原理与单片机课程设计》课程设计报告

基于51单片机得简易计算器设计

学生姓名卓国焕()

专业电子信息工程

所在班级1141

学号 2

指导老师欧触灵

日期2016、10、31——2016、11、4

一、设计目得

单片机得出现就是计算机制造技术高速发展得产物,它就是嵌入式控制系统得核心,如今,它已广泛得应用到我们生活得各个领域,电子、科技、通信、汽车、工业等。本设计就是基于51系列单片机来进行得简单数字计算器设计,可以完成计算器得键盘输入,进行加、减、乘、除六位整数数范围内得基本四则运算,并在LED上显示相应得结果.软件方面使用C语言编程,并用PROTUES仿真.

二、总体设计及功能介绍

根据功能与指标要求,本系统选用MCS—51系列单片机为主控机,实现对计算器得设计。具体设计及功能如下:

(1)由于要设计得就是简单得计算器,可以进行四则运算,为了得到较好得显示效果,采用LED 显示数据与结果。

(2)另外键盘包括数字键(0~9)、符号键(+、-、×、÷)、清除键与等号键,故只需要16 个按键即可,设计中采用集成得计算键盘。

(3)执行过程:开机显示零,等待键入数值,当键入数字,通过L ED显示出来,当键入+、-、*、/运算符,计算器在内部执行数值转换与存储,并等待再次键入数值,当再键入数值后将显示键入得数值,按等号就会在LED上输出运算结果。

(4)错误提示:当计算器执行过程中有错误时,会在LED上显示相应得提示,如:当输入得数值或计算得到得结果大于计算器得表示

范围时,计算器会在LED上显示“CUO",提示溢出。

三、系统模块组成框图:

本设计选用AT89C51单片机为主控单元。显示部分:采用LED

动态显示.按键部分:采用4*4集成计算键盘;

总电路图:

(1)4×4集成计算键盘

集成计算键盘本质上就是4×4矩阵键盘,矩阵键盘采用四条I /O 线作为行线,四条I/O 线作为列线组成键盘,在行线与列线得每个交叉点上设置一个按键。这样键盘上按键得个数就为4×4个。这种行列式键盘结构能有效地提高单片机系统中I/O 口得利用率.

矩阵键盘得工作原理:

计算器得键盘布局如图2所示:一般有16个键组成,在单片机中正好可以用一个P口实现16个按键功能,这种形式在单片机系统中也最常用。

矩阵键盘内部电路图如图所示:

(三)、LED显示模块

如图

本设计采用LED共阴数码管来显示输出数据.共阴数码管得每一位都就是公共得阴极,只有输入低电平得时候才有可能被点亮,所以位选得时候被选中得位必须就是低电平。

本设计采用两个74HC573锁存器来驱动数码管,引脚如上图所示.74HC573—1就是控制段选得,74HC573—2就是控制位选得,P2、6与P2、7端口就是锁存使能位,置高电平时锁存器透明(即输入与输出相同),置低电平时锁存。

74HC573得八个锁存器都就是透明得D 型锁存器,当使能(G)为高时,Q 输出将随数据(D)输入而变。当使能为低时,输出将锁存

在已建立得数据电平上。输出控制不影响锁存器得内部工作,即老数据可以保持,甚至当输出被关闭时,新得数据也可以置入.这种电路可以驱动大电容或低阻抗负载,可以直接与系统总线接口并驱动总线,而不需要外接口.特别适用于缓冲寄存器,I/O 通道,双向总线驱动器与工作寄存器。

HC573引脚功能:

引脚号符号名称及功能

1 OE?3态输出使能输入(低电平)

2—9? D0—D7?数据输入

12-19Q0 — Q7?3态锁存输出

11?LE?锁存使能输入

10 GND?接地(0V)

20 VCC 电源电压

(四)运算模块(51单片机控制)

51 单片机就是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器与多功能I/O等一台计算机所需要得基本功能部件。如果按功能划分,它由如下功能部件组成,即微处理器(CPU)、数据存储器(RA M)、程序存储器(ROM/EPROM)、并行I/O 口、串行口、定时器/计数器、中断系统及特殊功能寄存器(SFR).

单片机就是靠程序运行得,并且可以修改。通过不同得程序实现不同得功能,尤其就是特殊得独特得一些功能,通过使用单片机编写得程序可以实现高智能,高效率,以及高可靠性!因此我们采用单片机

作为计算器得主要功能部件,可以很快地实现运算功能。

单片机最小系统

复位时单片机得初始化操作,只要给RST引脚加上两个机器周期以上得高电平信号,就可以使STC89C51单片机复位。本次采用得就是12M晶振,按钮复位电路。

三、软件设计

现实生活中人们熟知得计算器,其功能主要如下:

1、键盘输入;

2、数值显示;

3、加、减、乘、除四则运算;

针对上述功能,计算器软件程序要完成以下程序得设计:

1、键盘输入检测程序

2、LED显示程序

3、算术运算程序

1、程序流程图

系统总流程图

算术运算程序流程图

2、程序清单

#include<reg52、h〉

#include〈math、h〉

#define uchar unsigned char #define uint unsigned int

#define ulong unsigned long

sbit wela=P2^7; //定义端口

sbit dula=P2^6;

long in1,in2,out,x;

int cnt,i,flag;

uchar code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //LED显示字模,共阴void delay(uint xms) //延时函数

{

uint j;

?for(i=xms;i>0;i--)

for(j=114;j〉0;j-—);

}

void display() //显示函数声明

?ucharw1,w2,w3,w4,w5,w6,f=0;

?long y;

if(x〉=0)//显示六位计时数

?{

if(x>=1e6)

?{

??P0=0xff;

??wela=1;

??P0=0xf7;

?wela=0;

???dula=1;

P0=num[12];

?dula=0;

??delay(2);

?P0=0xff;

?wela=1;

?P0=0xef;

?wela=0;

?dula=1;

?P0=0x3e;

??dula=0;

??delay(2);

?P0=0xff;

?wela=1;

??P0=0xdf;

???wela=0;

?dula=1;

??P0=num[0];

?dula=0;

??delay(2);

?return;

?}

?w1=x%10;w2=x/10%10;w3=x/100%10;w4=x/1000%10;w5=x/10000%10;w6=x/100000%10;

??if(f==1||w6)

?{

??f=1;

??P0=0xff;

???wela=1;

?P0=0xfe;

???wela=0;

?dula=1;

?P0=num[w6];

?dula=0;

delay(2);

?}

if(f==1||w5)

?{

?f=1;

??P0=0xff;

??wela=1;

???P0=0xfd;

??wela=0;

??dula=1;

P0=num[w5];

???dula=0;

??delay(2);

?}

?if(f==1||w4)

??{

??f=1;

P0=0xff;

wela=1;

??P0=0xfb;

??wela=0;

?dula=1;

??P0=num[w4];

?dula=0;

?delay(2);

?}

?if(f==1||w3)

?{

???f=1;

?P0=0xff;

wela=1;

P0=0xf7;

?wela=0;

???dula=1;

???P0=num[w3];

dula=0; ???delay(2);

?}

?if(f==1||w2)

??{

???f=1;

?P0=0xff;

?wela=1;

?P0=0xef;

?wela=0;

??dula=1;

???P0=num[w2];

dula=0;

?delay(2);

?}

?P0=0xff;

?wela=1;

P0=0xdf;

?wela=0;

??dula=1;

??P0=num[w1];

??dula=0;

??delay(2);

?}

else

?{

y=labs(x);

?if(y〉=1e5)

?{

?P0=0xff;

wela=1;

??P0=0xf7;

?wela=0;

??dula=1;

??P0=num[12];

??dula=0;

??delay(2);

??P0=0xff;

??wela=1;

?P0=0xef;

?wela=0;

?dula=1;

??P0=0x3e;

?dula=0;

?delay(2);

?P0=0xff;

??wela=1;

???P0=0xdf;

wela=0;

?dula=1;

?P0=num[0];

?dula=0;

delay(2);

?return;

}

?w1=y%10;w2=y/10%10;w3=y/100%10;w4=y/1000%10;w5=y/10000%10;

?if(f==1||w5)

?{

?if(f==0)

???{

??P0=0xff;

??wela=1;

??P0=0xfe;

??wela=0;

?dula=1;

?P0=0x40;

?dula=0;

??delay(2);

??}

?f=1;

??P0=0xff;

???wela=1;

??P0=0xfd;

??wela=0;

??dula=1;

P0=num[w5];

dula=0;

?delay(2);

?}

?if(f==1||w4)

{

??if(f==0)

?{

????P0=0xff;

???wela=1;

??P0=0xfd;

??wela=0;

????dula=1;

?P0=0x40;

?dula=0;

??delay(2);

??}

?f=1;

??P0=0xff;

??wela=1;

???P0=0xfb;

?wela=0;

??dula=1;

??P0=num[w4];

??dula=0;

?delay(2);

}

?if(f==1||w3)

{

?if(f==0)

???{

??P0=0xff;

wela=1;??P0=0xfb;

??wela=0;

??dula=1;

???P0=0x40;

??dula=0;

????delay(2);

??}

?f=1;

P0=0xff;

??wela=1;

??P0=0xf7;

?wela=0;

??dula=1;

?P0=num[w3];

dula=0;

?delay(2);

?}

if(f==1||w2)

?{

??if(f==0)

?{

????P0=0xff;

?wela=1;

???P0=0xf7;

??wela=0;

?dula=1;

???P0=0x40;

????dula=0;

??delay(2);

?}

?f=1;

?P0=0xff;

???wela=1;

?P0=0xef;

??wela=0;

??dula=1;

??P0=num[w2];

??dula=0;

?delay(2);

??if(f==0)

{

?P0=0xff;

??wela=1;

?P0=0xef;

??wela=0;

??dula=1;

??P0=0x40;

??dula=0;

??delay(2);

P0=0xff;

?wela=1;

??P0=0xdf;

?wela=0;

?dula=1;

??P0=num[w1];

?dula=0;

?delay(2);

void keyscan() //键盘扫描函数{

?uchar temp;

P1=0xfe;

temp=P1;

temp=temp&0xf0;

if(temp!=0xf0)

??delay(8);

??temp=P1;

?temp=temp&0xf0;

?if(temp!=0xf0)

?{

?temp=P1;

???switch(temp)

???{

????case 0xee:

??if(cnt〈6)

?{

?cnt++;

???if(flag==0)

??{

????in1=in1*10+7;

???x=in1;

????}

??else

????{

??in2=in2*10+7;

???x=in2;

??}

??break;

?case 0xde:

???if(cnt〈6)

???{

?cnt++;

????if(flag==0)

???{

????in1=in1*10+8;

???x=in1;

????}

???else

?????{

???in2=in2*10+8;

?x=in2;

??}

??}

??break;

case 0xbe:

?if(cnt〈6)

?{

????cnt++;

???if(flag==0)

???{

????in1=in1*10+9;

???x=in1;

?}

?else

???{

????in2=in2*10+9;

???x=in2;

???}

?}

break;

??case0x7e:

???if(cnt!=0&&flag==0)

?{

???cnt=0;

????flag=4;

??}

??break;

???}

??while(temp!=0xf0)

??{

???temp=P1;

??temp=temp&0xf0;

?}

?}

}

?P1=0xfd;

?temp=P1;

?temp=temp&0xf0;

if(temp!=0xf0)

?{

delay(8);

temp=P1;

?temp=temp&0xf0;

if(temp!=0xf0)

?{

??temp=P1;

?switch(temp)

?{

??case 0xed:

???if(cnt<6)

??{

?cnt++;

?if(flag==0)

?{

?????in1=in1*10+4;

???x=in1;

???}

?else

??{

??in2=in2*10+4;

?x=in2;

???}

???}

??break;

????case 0xdd:

???if(cnt<6)

?{

??cnt++;

????if(flag==0)

????{

???in1=in1*10+5;

?x=in1;

}

???else

?{

??in2=in2*10+5;

??x=in2;

?}

}

???break;

case 0xbd:

if(cnt〈6)

???{

????cnt++;

???if(flag==0)

???{

???in1=in1*10+6;

?x=in1;

???}

???else

{

??in2=in2*10+6; ??x=in2;

????}

??}

??break;

?case 0x7d:

??if(cnt!=0&&flag==0)??{

?cnt=0;

??flag=3;

???}

???break;

?}

?while(temp!=0xf0)

??{

?temp=P1;

???temp=temp&0xf0;

??}

??}

?}

?P1=0xfb;

temp=P1;

?temp=temp&0xf0;

?if(temp!=0xf0)

?{

??delay(8);?//消除抖动

temp=P1;

??temp=temp&0xf0;

?if(temp!=0xf0)

?{

???temp=P1;

switch(temp)

{

case 0xeb:

??if(cnt<6)

???{

?cnt++;

??if(flag==0)

??{

???in1=in1*10+1;

?x=in1;

????}

??else

??{

??in2=in2*10+1;

????x=in2;

???}

??}

?break;

?case0xdb:

?if(cnt〈6)

???{

???cnt++;

????if(flag==0)

??{

???in1=in1*10+2;

???x=in1;

???}

???else

?{

?????in2=in2*10+2;

???x=in2;

??}

??}

???break;

??case 0xbb:

???if(cnt〈6)

??cnt++;

??if(flag==0)

???{

??in1=in1*10+3;

???x=in1;

??}

???else

???{

???in2=in2*10+3;

???x=in2;

???}

???}

??break;

???case 0x7b:

??if(cnt!=0&&flag==0)

??{

????cnt=0;

?flag=2;

???}

?break;

本文来源:https://www.bwwdw.com/article/j33q.html

Top