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(); //调用显示程序 } }
版权声明:本文标题:4位数加法器设计报告 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1713741152a649398.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论