当前位置:文档之家› 位数加法器设计报告

位数加法器设计报告

4位数加法器设计报告
一、设计任务和要求
1.1、任务描述:
1、系统通过4×4的矩阵键盘输入数字及运算符;
2、可以进行4位十进制数以内的加法运算,如果计算结果超过4位十进制
图2.1 矩阵键盘控制电路
2.2、采用LED数码管显示,数码管图如图2.2.1所示:
下图则是加法器电路的原理图:
AT89C51芯片模型
3.1.1、主要功能特性
(1) 4K字节可编程闪烁存储器。

(2) 32个双向I/O口;128×8位内部RAM 。

(3) 2个16位可编程定时/计数器中断,时钟频率0-24MHz。

(4) 可编程串行通道。

(5) 5个中断源。

(6) 2个读写中断口线。

(7) 低功耗的闲置和掉电模式。

(8) 片内振荡器和时钟电路。

3.1.2、AT89C51的引脚介绍
89C51单片机多采用40只引脚的双列直插封装(DIP)方式,下面分别简单介绍。

(1)电源引脚
电源引脚接入单片机的工作电源。

Vcc(40引脚):+5V电源。

GND(20引脚):接地。

(2)时钟引脚
XTAL1(19引脚):片内振荡器反相放大器和时钟发生器电路的输入端。

XTAL2(20引脚):片内振荡器反相放大器的输出端。

电源接入方式
(3)复位RST(9引脚)
在振荡器运行时,有两个机器周期(24个振荡周期)以上的高电平出现在此引脚时,将使单片机复位,只要这个脚保持高电平,51芯片便循环复位。

(4)EA/Vpp(31引脚)
EA为外部程序存储器访问允许控制端。

当它为高电平时,单片机读片内

为该
拉电阻,用来驱动多个数码管。

在访问外部程序和外部数据存储器时,P0口是分时转换的地址(低8位)/数据总线,不需要外接上拉电阻。

(8)Pin1-Pin8为P1.0-P1.7输入输出脚,称为P1口,是一个带内部上拉电阻的8位双向I/0口。

P1口能驱动4个LSTTL负载。

(9)Pin21-Pin28为P2.0-P2.7输入输出脚,称为P2口。

P2口是一个带内部上拉电阻的8位双向I/O口,P2口能驱动4个LSTTL 负载。

端口置1时,内部上拉电阻将端口拉到高电平,作输入用。

对内部Flash 程序存储器编程时,接收高8位地址和控制信息。

在访问外部程序和16位外部数据存储器时,P2口送出高8位地址。

而在访问8位地址的外部数据存储器时其引脚上的内容在此期间不会改变。

(10)Pin10-Pin17为P3.0-P3.7输入输出脚,称为P3口。

图3.3.1 矩阵键盘实际操作图
四、程序设计
本作品实现的功能全部是由C语言程序编写实现。

通过程序的编写使简单的器件实现丰富的功能。

如下所示是主程序流程图
五、系统调试及结果
本设计应用Proteus6及KEIL51软件,首先根据自己设计的电路图用Proteus6软件画出电路模型,关于这个软件的使用通过查一些资料和自己的摸索学习;然后我们用KEIL51软件对所编写的程序进行编译、链接,如果没有错误和警告便可生成程序的hex文件,将此文件加到电路图上使软硬件结合运行。

下图为运行状况图,为首先输入10+990,再加上9999,最后每个数码管上为E,因为为了满足实验要求,当结果超过了9999后显示E.
刚开始为0
输入10
再加上990得到了1000
最后显示E
五、设计个人总结
经过一周的努力终于设计成功,LED数码管的显示结果与理想所保持的一样。

在这一周的设计中,完成这个简易的计算器,虽然精度不高,但是对于一般的计算,是绰绰有余。

起初,电路的设计对我们这些人来说,是一大障碍,通过查找资料,发现一个简易的计算器,似乎没有那么难,只要有心,定能成功。

后来数码管的显示一直困扰着我,但随着慢慢地了解它,在相关资料帮助之下,终于明白如何用C语言写程序去控制数码管的显示。

加之以前学过一些计算机方面的C语言,那并不是针对单片机C语言的,虽有相似之处,但差之甚大,如今已经了逐步地了解,相信若坚持下去,定能学好这一门课程。

通过此次设计课程,使我受益匪浅。

终于更深刻地体会到实践是唯一的真理。

附录 ( 程序 ):
/**********通过用单片机MCU与矩阵及数码管的相互连接构成一个简易的数计算器--------可以进行加减乘除********/
#include <reg51.h>
#define uchar unsigned char
long First,End; //定义全局变量
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] =
{z=y-x;
z=z+100000;} /***最高位用1表示负数***/
return(z);
}
long mul(long x,long y) /***乘法程序***/
{long z;
z=x*y;
return(z);
}
long div(long x,long y) /***除法程序***/
{long z;
z=x/y;
return(z);
}
uchar kbscan(void) /***键盘扫描程序***/ {
uchar sccode;
num[0]=First/100000%10; //十万
num[1]=First/10000%10; //万
num[2]=First/1000%10; //千位
num[3]=First/100%10; //百位
num[4]=First/10%10; //十位
num[5]=First%10; //个位
for(i=5;i>=0;i--)
{P2=dispbit[i]; //位选输出 P1=Disp_Tab[num[i]]; //数据输出 delay(2); //此延时必不可少?
}
}
void main(void) /***主程序***/
{ int k,n;
uchar f,g,key,gn1,i;
n=0;
f=0;
//P1=0; //初始时指示灯灭
while(1) //不断查询是否有按键动作
//P1=1;
delay(280); //有按键时,指示灯的显示时间
//P1=0; //按键指示灭
if(k<10) //为数字键时(0-9)
{
if(f!=0) //为数字键时,如果已经有功能键按下
{
n++; //记录数字键所按次数
gn1=0; //清除标志,再次为功能键时进行运算
g=f; //保存运算标志
if(n==1) //输入为各位数时,直接赋值
First=k;
else if(n>1) //输入为多位数时,将它转化为10进制的多位数
First=First*10+k;
}
else //如果没有功能键按下
case 1: First=add(End,First);break;
case 2: First=sub(End,First);break;
case 3: First=mul(End,First);break;
case 4: First=div(End,First);break;
}
}
End=First; //保存本次结果
}
else if(k==11) //为等于号时(=)
{
n=0;
gn1=1; //接着输入为功能键时可以继续运算
switch(g)
{
case 1: First=add(End,First);break;
case 2: First=sub(End,First);break;
case 3: First=mul(End,First);break;
case 4: First=div(End,First);break;
}。

相关主题