admin 管理员组

文章数量: 1086019


2024年4月22日发(作者:altered scale)

4位数加法器设计报告

一、设计任务和要求

1.1、任务描述:

1、系统通过4×4的矩阵键盘输入数字及运算符;

2、可以进行4位十进制数以内的加法运算,如果计算结果超过4位十进制

数,则屏幕显示E;

3、可以进行加法以外的计算(乘、除、减);

4、创新功能。

1.2、

任务要求:

1、理解任务书要求,明确分工,查找相关资料,制定系统方案;

2、论证系统设计方案,运用Proteus等软件绘制电路原理图;

3、根据硬件电路,确定算法,设计程序框图,编写程序代码;

4、误差分析与改进,完成设计报告。

二、方案论证

2.1、适用矩阵键盘控制作为输入电路,电路和软件稍微复杂,但是相比

用独立按键,可节省I/O口,其原理图如2.1所示:

S1

S5

S9

S13

S2

S6

S10

S14

S3

S7

S11

S15

S4

S8

S12

S16

图2.1 矩阵键盘控制电路

2.2、采用LED数码管显示,数码管图如图2.2.1所示:

图2.2.1 LED数码管

一、 电路基本单元电路设计

本电路的总体的工作框图如下所示:

矩阵键盘控制电

AT89C51主控制电路

LED数码管显示

下图则是加法器电路的原理图:

P

2

.

0

P

2

.

1

P

2

.

2

P

2

.

3

P

2

.

4

P

2

.

5

R1R2R3R4R5R6R7R8

P

2

.

0

P

2

.

1

P

2

.

2

P

2

.

3

P

2

.

4

P

2

.

5

1k1k1k1k1k1k1k1k

1

9

1

6

1

5

1

2

9652

Q

7

Q

6

Q

5

Q

4

Q

3

Q

2

Q

1

Q

0

L

E

O

E

D

7

D

6

D

5

D

4

D

3

D

2

D

1

D

0

U2

74LS373

1

11

1

8

1

7

1

4

1

38743

U1

8

7

6

5

4

3

2

1

P1.7

P1.6

P1.5

P1.4

P1.3

P1.2

P1.1/T2EX

P1.0/T2

P3.7/RD

P3.6/WR

P3.5/T1

P3.4/T0

P3.3/INT1

P3.2/INT0

P3.1/TXD

P3.0/RXD

P2.7/A15

P2.6/A14

P2.5/A13

P2.4/A12

P2.3/A11

P2.2/A10

P2.1/A9

P2.0/A8

P0.7/AD7

P0.6/AD6

P0.5/AD5

P0.4/AD4

P0.3/AD3

P0.2/AD2

P0.1/AD1

P0.0/AD0

17

16

15

14

13

12

11

10

28

27

26

25

24

23

22

21

32

33

34

35

36

37

38

39

LE

GND

S1

S5

S9

R10

R11

R12

10k

R13

10k

10k10k

P0.0

P0.1

P0.2

P0.3

P0.4

P0.5

P0.6

P0.7

S2

S6

S10

S14

S3

S7

S11

S15

S4

S8

S12

S16

V

C

C

C1

1uF

31

30

29

EA

ALE

PSEN

P2.5

P2.4

P2.3

P2.2

P2.1

P2.0

P0.7

P0.6

P0.5

P0.4

P0.3

P0.2

P0.1

P0.0

R9

10k

9

RST

S13

C3

18

30uF

XTAL2

X1

CRYSTAL

19

R15

R16R14

10k

R17

10k

10k

10k

XTAL1

AT89C51

C2

30uF

GND

3.1、主控模块

该设计的核心控制电路是 AT89C52单片机。AT89C51是一种带4K字

节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only

Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。AT89C2051

是一种带2K字节闪存可编程可擦除只读存储器的单片机。单片机的可擦

除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失

存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。

由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的

AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C

单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。其引脚

U1

19

XTAL1P0.0/AD0

P0.1/AD1

P0.2/AD2

P0.3/AD3

P0.4/AD4

P0.5/AD5

P0.6/AD6

P0.7/AD7

P2.0/A8

P2.1/A9

P2.2/A10

P2.3/A11

P2.4/A12

P2.5/A13

P2.6/A14

P2.7/A15

P3.0/RXD

P3.1/TXD

P3.2/INT0

P3.3/INT1

P3.4/T0

P3.5/T1

P3.6/WR

P3.7/RD

39

38

37

36

35

34

33

32

21

22

23

24

25

26

27

28

10

11

12

13

14

15

16

17

18

XTAL2

9

RST

29

30

31

PSEN

ALE

EA

1

2

3

4

5

6

7

8

P1.0

P1.1

P1.2

P1.3

P1.4

P1.5

P1.6

P1.7

AT89C51

图以及工作原理如下:

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

为外部程序存储器访问允许控制端。当它为高电平时,单片机读片内

程序存储器,在PC值超过0FFFH后将自动转向外部程序存储器。当它为低电

平时,只限定在外部程序存储器,地址为0000H~FFFFH。Vpp为该引脚的第二

功能,为编程电压输入端。

(5)ALE/

PROG

(30引脚)

ALE为低八位地址锁存允许信号。在系统扩展时,ALE的负跳沿江P0口

发出的第八位地址锁存在外接的地址锁存器,然后再作为数据端口。

PROG

为该

引脚的第二功能,在对片外存储器编程时,此引脚为编程脉冲输入端。

(6)

PSEN

(29引脚)

片外程序存储器的读选通信号。在单片机读片外程序存储器时,此引脚输

出脉冲的负跳沿作为读片外程序存储器的选通信号。

(7) pin39-pin32为P0.0-P0.7输入输出脚,称为P0口。

P0是一个8位漏极开路型双向I/O口。内部不带上拉电阻,当外接上拉电阻

时,P0口能以吸收电流的方式驱动八个LSTTL负载电路。通常在使用时外接上

拉电阻,用来驱动多个数码管。 在访问外部程序和外部数据存储器时,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口。

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

负载,这8个引脚还用于专门的第二功能。端口置1时,内部上拉电阻将端口拉

到高电平,作输入用。对内部Flash程序存储器编程时,接控制信息。

3.2、显示模块

该电路的显示模块采用共阴极数码管显示。共阴极数码管的位选采用低电平,

而段选采用高电平控制。LED数码管十六位进数的字形码如表3.2.1所示,而显示

模块控制电路如3.2.2所示:

0

1

2

3

4

5

6

7

8

共阳极代共阴极代字共阳极代共阴极代

码 码 型 码 码

C0H 3FH 9 90H 6FH

F9H 06H A 88H 77H

A4H 5BH B 83H 7CH

B0H 4FH C C6H 39H

99H 66H D A1H 5EH

92H 6DH E 86H 79H

82H 7DH F 8EH 71H

F8H 07H 灭 FFH 00H

80H 7FH

表3.2.1 LED数码管十六位进数的字形码

R1R2R3R4R5R6R7R8

U1

8

7

6

5

4

3

2

1

P1.7

P1.6

P1.5

P1.4

P1.3

P1.2

P1.1/T2EX

P1.0/T2

P3.7/RD

P3.6/WR

P3.5/T1

P3.4/T0

P3.3/INT1

P3.2/INT0

P3.1/TXD

P3.0/RXD

P2.7/A15

P2.6/A14

P2.5/A13

P2.4/A12

P2.3/A11

P2.2/A10

P2.1/A9

P2.0/A8

P0.7/AD7

P0.6/AD6

P0.5/AD5

P0.4/AD4

P0.3/AD3

P0.2/AD2

P0.1/AD1

P0.0/AD0

17

16

15

14

13

12

11

10

28

27

26

25

24

23

22

21

32

33

34

35

36

37

38

39

LE

V

C

C

C1

1uF

31

30

29

EA

ALE

PSEN

P2.5

P2.4

P2.3

P2.2

P2.1

P2.0

P0.7

P0.6

P0.5

P0.4

P0.3

P0.2

P0.1

P0.0

R9

10k

9

RST

C3

18

30uF

XTAL2

X1

CRYSTAL

19

XTAL1

AT89C52

C2

30uF

GND

P

2

.

0

P

2

.

1

P

2

.

2

P

2

.

3

P

2

.

4

P

2

.

5

R10

R11

R12

10k

R13

10k

10k10k

1k1k1k1k1k1k1k1k

R15

R16R14

10k

R17

10k

10k

10k

图3.2.2 显示模块控制电路

3.3、操作模块

该操作模块的实际操作如下图所示:

0 1 2 3

4 5 6 7

8 9 C=

+ - * /

图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

#define uchar unsigned char

long First,End; //定义全局变量

//此表为 LED 的字模, 共阴数码管 0-9 -

unsigned char code Disp_Tab[] =

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39

,0x5e,0x79,0x71}; //段码控制

//此表为8个数码管位选控制, 共阴数码管 1-8个 -

unsigned char code dispbit[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

//位选控制 查表的方法控制

void delay(int n) /***延时程序***/

{int i,j;

for(i=0;i

{for(j=0;j<50;j++)

;}

}

long add(long x,long y) /***加法程序***/

{long z;

z=x+y;

return(z);

}

long sub(long x,long y) /***减法程序***/

{long z;

if(x>=y)

z=x-y;

else

{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;

P0=0xf0;

if((P0&0xf0)!=0xf0) //发全0行扫描码,列线输入

{ delay(222); //延时去抖

if((P0&0xf0)!=0xf0)

{sccode=0xfe; //逐行扫描初值

while((sccode&0x10)!=0)

{P0=sccode; //输出行扫描码

if((P0&0xf0)!=0xf0)

{

return(P0);} //如果检测到有键按下,返回键值

else

sccode=(sccode<<1)|0x01; //行扫描码左移一位

}

}

}

return(0); //无键按下,返回值为0

}

void display(void) /***显示程序***/

{int i;

uchar data num[6];

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) //不断查询是否有按键动作

{ key=kbscan(); //获取返回键值

if(key!=0)

{

switch(key) //译码,将对应按键返回值转换为

相应数值

{

case 0xee: k=0;break;//0

case 0xde: k=1;break;//1

case 0xbe: k=2;break;//2

case 0x7e: k=3;break;//3

case 0xed: k=4;break;//4

case 0xdd: k=5;break;//5

case 0xbd: k=6;break;//6

case 0x7d: k=7;break;//7

case 0xeb: k=8;break;//8

case 0xdb: k=9;break;//9

case 0xbb: k=10;First=0;End=0;f=0;break;//清除

case 0x7b: k=11;break;//等于

case 0xe7: k=12;f=1;break;//加

case 0xd7: k=13;f=2;break;//减

case 0xb7: k=14;f=3;break;//乘

case 0x77: k=15;f=4;break;//除

}

//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 //如果没有功能键按下

{

n++;

gn1=1; //定义标志,当下一次为功能键时,

停止数据输入

if(n==1)

First=k;

else if(n>1)

First=First*10+k;

End=First; //将第一个数保存

}

}

else if(k>11) //为功能键时(+-*/)

{

if(gn1==1) //前一次数字键之后为功能键时

{

n=0; //清除计数标志

}

else //如果再次输入功能键,则进行

运算

{

n=0; //清除计数标志

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;

}

}

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;

}

End=First; //保存最终运算结果

f=0; //清除运算标志

if(End>9999) /***当结果大于9999时,显示E*****/

{

P1=0XF9; //显示E

for(i=5;i>=0;i--)

{

P2=dispbit[i]; //位选输出

//P1=Disp_Tab[num[i]]; //数据输

delay(1); //此延时必不可少?

}

}

}

}

display(); //调用显示程序

}

}


本文标签: 程序 存储器 电路 数码管 设计