简易计算器设计.docx
《简易计算器设计.docx》由会员分享,可在线阅读,更多相关《简易计算器设计.docx(26页珍藏版)》请在冰点文库上搜索。
![简易计算器设计.docx](https://file1.bingdoc.com/fileroot1/2023-7/9/a16a1071-58fb-4de3-98f9-c1446763841a/a16a1071-58fb-4de3-98f9-c1446763841a1.gif)
简易计算器设计
广东海洋大学寸金学院
《单片机》课程设计
论文题目:
简易计算器设计
系别:
信息技术系
专业:
电气工程及其自动化
班级:
电气工程及其自动化4班
姓名:
李泽辉林卓环
学号:
20121031204132012103120418
指导老师:
叶伟慧
职称:
讲师
日期:
2015年1月4日
广东海洋大学寸金学院教务处制
1设计任务
1.1设计目的和意义
当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活或学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且比较容易出错。
计算器作为一种快速通用的计算工具方便了用户的使用。
计算器可谓是我们最亲密的电子伙伴之一。
本设计着重在于分析计算器软件和开发过程中的环节和步骤,并从实践经验出发对计算器设计做了详细的分析和研究。
单片机由于其微小的体积和极低的成本,广泛的应用于家用电器、工业控制等领域中。
在工业生产中。
单片微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。
单片微型计算机简称单片机,特别适用于控制领域,故又称为微控制器。
本系统采用AT89C51设计计算器控制器,实现了能根据实际输入值显示,简单运算的功能。
1.2设计任务与要求
1、设计4*4的键盘,其中10个数字键0~9,其余6个键为“+”、“-”“*”、“/”、“=”和“C”键;
2、设计2位LED接口电路;
3、实现1位数的简单运算。
2系统设计
2.1总体方案设计
根据系统的要求,确定系统的总体方案如图1所示。
图1系统总体设计方案
2.2芯片选型与具体电路设计
2.2.1单片机的选型
系统采用AT89C51单片机,该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,所以是一种高效微控制器。
主要有以下特性:
1、与MCS-51兼容
2、4K字节可编程FLASH存储器
3、全静态工作:
0Hz-24MHz
4、128×8位内部RAM
5、32可编程I/O线
6、两个16位定时器/计数器
7、5个中断源
8、片内振荡器和时钟电路
各管脚说明如下:
VCC:
供电电压。
GND:
接地。
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P0口的管脚第一次写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)这是由于上拉的缘故。
RST:
复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:
当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:
每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:
反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:
来自反向振荡器的输出。
2.2.2振荡电路的设计
本系统采取12MHz晶振为振荡源,为单片机提供时钟信号,其电路如图2所示。
图2振荡电路设计
2.2.3复位电路的设计
系统复位电路设计如图3所示。
图3复位电路设计
2.2.4矩阵键盘电路与运算法则指示电路的设计
系统采用了KEYPAD-SMALLCALC型4*4计算器专用键盘,包含行线和列线各4根,分别接于P1.0~P1.3和P1.4~P1.7。
可输入数字0~9,进行“+”、“-”、“*”、“/”简单运算,并具有复位功能;运算法则指示电路采用了4只黄色LED-BIRY,并将其共地,另一端分别接至单片机的4个管脚,当执行某种运算法则时,其对应的LED亮,运算完成后,LED灭。
系统矩阵键盘电路与运算法则指示电路如图4所示。
图4矩阵键盘与运算法则指示电路设计
2.2.5LED显示电路的设计
根据设计要求,系统采用了2个7SEG-COM-CATHODE型7位LED显示器,分别接于单片机P0口和P2口得低7位,并分别接上拉排阻RP1和RP2,显示输入数据和运算结果。
当显示数据为一位数时,高位显示“0”,低位显示需要显示的数字。
LED显示电路设计如图5所示。
图5LED显示电路设计
2.3系统总体电路
系统总体上分为单片机、振荡电路、复位电路、LED显示电路、矩阵键盘电路、运算法则指示电路六个部分。
单片机为系统的中央处理器,完成数据的采集、运算、数据输出等功能;振荡电路采用12MHz的晶振,为单片机提供时钟信号;复位电路为单片机提供复位功能;LED显示电路采用2只7位LED显示器,实现2位输入输出数据的显示;运算法则指示电路通过4只LED显示系统当前的运算法则。
系统总体电路如图6所示。
图6系统总体电路设计
2.4系统所用元器件
本系统所用的元器件清单如表1所示。
表1本系统所用的元器件
元器件名称
数量
单片机AT89C51
1
7位LED显示器7SEG-COM-CATHODE
2
电容CAP
2
极性电容CAP-ELEC
1
晶振CRYSTAL
1
计算器键盘KEYPAD-SMALLCALC
1
LED-BIRY
4
电阻RES
1
排阻RESPACK-8
2
电源VCC
1
导线
若干
3.软件系统设计
3.1软件系统总体设计方案
系统通过矩阵键盘输入数据,单片机对输入数据进行处理,将处理结果输出,通过LED显示电路和运算法则指示电路显示处理结果。
软件系统总体设计方案如图7所示。
图7软件系统总体设计方案
3.2软件系统流程图
3.2.1主程序流程图
主程序流程图如图8所示。
图8主程序流程图
3.2.2按键扫描子程序设计(小四宋体加粗)
由于矩阵键盘的行线和列线分别接于P1口得高4位和低4位,通过线反转法检测键盘按键状态,根据所得值向单片机反馈相应数据。
按键扫描流程图如图9所示。
图9按键扫描流程图
4系统调试
4.1系统初始状态的调试
系统初始状态时,2个LED显示器显示“0”,运算法则指示灯全灭。
调试结果如图10所示。
图10系统初始状态调试结果
4.2键盘输入功能的调试
通过键盘分别输入“8”、“*”、“9”,LED显示电路和运算法则指示电路分别显示相应的结果。
调试结果如图11所示。
(a)输入“8”
(b)输入“*”
(c)输入“9”
图11键盘输入功能调试结果
4.3系统运算功能的调试
当输入“8”、“*”、“9”后,点击“=”可得到运算结果“72”,并通过LED显示电路显示。
调试结果如图12所示。
图12系统运算功能调试结果
课程设计心得体会:
通过这次单片机课程设计,我们深感自己动手操作的重要性。
我们在课堂上接触到的多半是苍白的理论,在实践层面上只有一定的指导作用。
但是真正在实际运用过程中,我们如果缺乏必要的及时锻炼,那将会感觉到力不从心。
工科本来就是一门集思维和动手能力于一体的学科,要想真正掌握好,思考、假设和实验验证都是必不可少的。
在通过很多的理论学习之后,我们通过课程设计和相关的实验把书本上的理论知识在实际运用中加以利用,巩固了理论知识的同时也增强了我们的动手能力。
通过实习,我才真正领略到“艰苦奋斗”这一词的真正含义,我才意识到老一辈电子设计为我们的社会付出。
我们学习理论知识的最终目的还是要走向实际运用, 通过这种模拟式的学习,我们加深认识到理论与实践的差异。
通过这个课程设计,我们大家把整个学习阶段的各种学科知识窜联在一起,更好地认识到学习是一个系统工程。
我们的每一个环节都是在为以后的实践环节做铺垫,我们的每一个环节都是要有所掌握才可以顺利完成任务。
通过这样的实践活动,我们都深感动手起来遇到的各种问题都要亲自去解决是一件很不容易的事情,同时我们也在实践过程中修复了以往学习的很多漏洞。
我们也得到了不同程度的完善和提升。
希望以后能多举行多参与这类型的实践活动。
把理论知识结合到实践层面去,理论结合实际学习才会更有声有色。
要把我们学到理论知识的真正利用到生产实际中还需要大量的实践和运用。
我们忘不了自己在这一过程中的努力与收获,我们也相信付出与收获成正比,我们付出的越多,相应地收获也就越多,学习的过程中,我们要不断地改进和学习,多多交流才能更好更轻松地学习。
这次课程设计终于顺利完成了,在设计中遇到了很多专业知识问题,最后在老师的辛勤指导下,终于顺利完成。
同时,在老师的身上我们学也到很多实用的知识,在次我们表示感谢!
同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
成绩:
评阅老师:
日期:
附录:
简易计算器设计的源程序清单
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitJia=P3^4;//加法标志
sbitJian=P3^5;//减法标志
sbitCheng=P3^6;//乘法标志
sbitChu=P3^7;//除法标志
inta=0,b=0,c=0;
intflag=0;//输入数据标志位
intflag1=0;//运算法则标志位
ucharcodeKeyCodeTable[]=
{
0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88
};//按键扫描码表
unsignedcharconsttable[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};//0-F//LED共阴极字码表
voidDelay_ms(unsignedintt)//延时函数
{
unsignedinti;
while(t--)
{
for(i=0;i<560;i++);
}
}
voidJiSuan()//运算函数
{
if(flag1==0)
c=a+b;//加运算
elseif(flag1==1)
c=a-b;//减运算
elseif(flag1==2)
c=a*b;//乘运算
elseif(flag1==3)
c=a/b;//除运算
flag1=0;
Jia=0;
Jian=0;
Cheng=0;
Chu=0;
if(c>9)
{
a=c/10;
b=c%10;
P0=table[a];
P2=table[b];
}
else
{
P0=table[0];
P2=table[c];
}
}
ucharKeys_Scan()//按键扫描函数
{
ucharsCode,kCode,k;
P1=0xf0;
if((P1&0xf0)!
=0xf0)
{
Delay_ms(30);
if((P1&0xf0)!
=0xf0)
{
sCode=0xfe;
Delay_ms(20);
for(k=0;k<4;k++)
{
P1=sCode;
if((P1&0xf0)!
=0xf0)
{
kCode=~P1;
if(kCode==KeyCodeTable[0])return0;
if(kCode==KeyCodeTable[1])return1;
if(kCode==KeyCodeTable[2])return2;
if(kCode==KeyCodeTable[3])return3;
if(kCode==KeyCodeTable[4])return4;
if(kCode==KeyCodeTable[5])return5;
if(kCode==KeyCodeTable[6])return6;
if(kCode==KeyCodeTable[7])return7;
if(kCode==KeyCodeTable[8])return8;
if(kCode==KeyCodeTable[9])return9;
if(kCode==KeyCodeTable[10])return10;
if(kCode==KeyCodeTable[11])return11;
if(kCode==KeyCodeTable[12])return12;
if(kCode==KeyCodeTable[13])return13;
if(kCode==KeyCodeTable[14])return14;
if(kCode==KeyCodeTable[15])return15;
}
else
sCode=_crol_(sCode,1);
}
}
}
return-1;
}
voidmain()//主函数
{
unsignedcharkey;
P0=table[0];
P2=table[0];
flag1=0;
Jia=0;
Jian=0;
Cheng=0;
Chu=0;
while
(1)
{
key=Keys_Scan();//键盘扫描结果
switch(key)
{
case0:
//第一行
if(flag==0)//c=a+b;c=a*b;c=a-b;c=a/b
{
a=7;
flag=1;
}
else
{
b=7;
flag=0;
}
P2=table[b];
break;
case1:
if(flag==0)
{
a=8;
flag=1;
}
else
{
b=8;
flag=0;
}
P2=table[8];
break;
case2:
P2=table[9];
if(flag==0)
{
a=9;
flag=1;
}
else
{
b=9;
flag=0;
}
break;
case3:
flag1=3;
Chu=1;
break;
case4:
P2=table[4];//第二行
if(flag==0)
{
a=4;
flag=1;
}
else
{
b=4;
flag=0;
}
break;
case5:
P2=table[5];
if(flag==0)
{
a=5;
flag=1;
}
else
{
b=5;
flag=0;
}
break;
case6:
P2=table[6];
if(flag==0)
{
a=6;
flag=1;
}
else
{
b=6;
flag=0;
}
break;
case7:
flag1=2;
Cheng=1;
break;
case8:
P2=table[1];//第三行
if(flag==0)
{
a=1;
flag=1;
}
else
{
b=1;
flag=0;
}
break;
case9:
P2=table[2];
if(flag==0)
{
a=2;
flag=1;
}
else
{
b=2;
flag=0;
}
break;
case10:
P2=table[3];
if(flag==0)
{
a=3;
flag=1;
}
else
{
b=3;
flag=0;
}
break;
case11:
flag1=1;
Jian=1;
break;
case12:
P0=table[0];//第四行
P2=table[0];
flag=0;
flag1=0;
a=0;b=0;c=0;
break;
case13:
P2=table[0];
if(flag==0)
{
a=0;
flag=1;
}
else
{
b=0;
flag=0;
}
break;
case14:
JiSuan();
break;
case15:
flag1=0;
Jia=1;
break;
default:
break;
}
}
}