目录一、设计任务和性能指标………………………………………………11.1设计任务………………………………………………………21.2性能指标………………………………………………………2二、设计方案……………………………………………………………2三、系统硬件设计………………………………………………………33.1单片机最小系统………………………………………………33.2键盘接口电路…………………………………………………43.3数码管显示电路………………………………………………53.5按键监视电路…………………………………………………5四、系统软件设计………………………………………………………64.1键盘扫描子程序设计…………………………………………64.2移位子程序及结果计算子程序设计…………………………74.3显示子程序设计………………………………………………74.4主程序设计……………………………………………………20五、调试及性能分析……………………………………………………205.1调试步骤………………………………………………………205.2性能分析………………………………………………………20六、心得体会……………………………………………………………21参考文献………………………………………………………………21附录1、系统硬件电路图………………………………………………22附录2、硬件实物图……………………………………………………23附录3、器件清单……………………………………………………24一、设计任务和性能指标1.1设计任务自制一个单片机最小系统,包括复位电路,采用外部小键盘输入数据,能够实现加法、乘法及一个科学计算,计算结果显示在四位一体的数码管上。要求用Protel画出系统的电路原理图(要求以最少组件,实现系统设计所要求的功能),印刷电路板(要求布局合理,线路清晰),绘出程序流程图,并给出程序清单(要求思路清晰,尽量简洁,主程序和子程序分开,使程序有较强的可读性)。1.2性能指标1.加法:四位加法,计算结果若超过四位则显示计算错误;2.减法:四位减法,计算结果若小于零则显示计算错误;3.乘法:个位数乘法;4.除法:整数除法;5.取对数;6.开平方;7.指数运算;8.有清零功能二.设计方案按照系统设计的功能的要求,初步确定设计系统由主控模块、监测模块、显示模块、键扫描接口电路共四个模块组成,电路系统构成框图如图1.1所示。主控芯片使用51系列AT89C52单片机,采用高性能的静态80C51设计,由先进工艺制造,并带有非易失性Flash程序存储器。它是一种高性能、低功耗的8位COMS微处理芯片,市场应用最多。监测模块采用二极管和扬声器(实验室用二极管代替)组成电路。键盘电路采用4*4矩阵键盘电路。显示模块采用4枚共阳极数码管和74ls273锁存芯片构成等器件构成。整个单片机的接口电路:P0用于显示输出;P1用于键扫描输入;P2用于数码管位选控制;P3用于键盘扩展(部分运算符输入);三.系统硬件设计3.1单片机最小系统单片机最小系统就是支持主芯片正常工作的最小电路部分,包括主控芯片、复位电路和晶振电路。主控芯片选取STC89C52RC芯片,因其具有良好的性能及稳定性,价格便宜应用方便。晶振选取11.0592MHz,晶振旁电容选取20pF。采用按键复位电路,电阻分别选取100Ω和10K,电容选取10μF。以下为单片机最小系统硬件电路图。单片机最小系统硬件电路3.2键盘接口电路计算器所需按键有:数字键:’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’功能键:’+’,’-‘,’*’,’/’,’=’,’C(清零)’扩展键:“log”,“ln”,“x^2”“小数点”,“开方”共计25个按键,采用4*4矩阵键盘,键盘的行和列之间都有公共端相连,四行和四列的8个公共端分别接P1.0~P1.7,这样扫描P1口就可以完成对矩阵键盘的扫描,通过对16个按键进行编码,从而得到键盘的口地址,对比P1口德扫描结果和各按键的地址,我们就可以得到是哪个键按下,从而完成键盘的功能。以下为键盘接口电路的硬件电路图键盘接口电路实物图:扩展键接口电路:3.3数码管显示电路采用8位数码管对计算数据和结果的显示(实验时只用到了4位),这里选取共阴数码管,利用74LS244N对数码管进行驱动,为了节省I/O资源,采取动态显示的方法来显示计算数据及结果。P0口输出显示值,P2.0~P2.7(实际操作用到P2.0-P2.3)用来作为位选端,控制哪几位数码管进行显示。以下为数码显示电路的硬件电路图74LS244N接口电路:3.4按键监视电路按键监视电路就是在按键时,发出声音提醒,以确保输入数字有效。这里就采用5V蜂鸣器作为示音设备(实际操作用发光二极管代替)。用p3.7口输出信号。以下为报警电路硬件电路图按键监视电路图系统整体硬件电路图见附录一四、系统软件设计4.1键盘扫描子程序设计要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。以下为键盘扫描子程序的程序清单。ucharKeyscan(void){uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};for(j=0;j4;j++){P1=Buffer[j];/*以下三个_nop_();作用为让P1口的状态稳定*/delay();temp=0x01;for(i=0;i4;i++){if(!(P1&temp)){return(i+j*4);}temp=1;}}}4.2移位程序及结果计算代码设计输入数据要存储在一四位数组内,而我们键入的值是数据的高位,后键入的值是低位,这样我们就需要在输入低位数值时将高位数值从数组的低位移向数组的高位,这就是编写移位子程序的目的。对于结果计算子程序,包含加、减、乘、除四种运算。以加法运算为例,各种运算各有其标志位来代表计算类型,当加法标志位add=1是,就将输入的两个数据按照加法进行计算。首先将数组内的数按照对应的位关系,将其转化为一个十进制数,这样我们就得到了加速和被加数这样俩个十进制数,从而我们就可以简单的将两个数进行相加,结果就是我们所求的数值。但这个数值不能直接显示到数码管上,我们还要对其进行处理,使其变为对应进位的四个数存入数组内,以便显示。既通过对结果数值分别除以1000、100、10和对10取余,得到我们想要的四个数,送显示子程序显示。其余减、乘、除的计算方法与加法的计算方法一样,这里不再累述。以下为移位子程序和结果计算子程序的程序清单。这部分嵌入到了主函数中。调用输入数据函数:4.3显示子程序设计从始至终无论是输入的计算数据,还是计算后的结果值。都存储在同一数组dat[]中,这样我们只要在显示时一直调用dat[]中的值,就能正确的显示数据。以下为显示子程序的程序清单。voiddiaplay(void)interrupt1{ucharlen;TH0=(65536-2000)/256;TL0=(65536-2000)%256;P2=Disbuf[dcounter];len=dcounter;P0=xx[len];dcounter+=1;if(dcounter==8){dcounter=0;}}延时程序:voidDelay_1ms(uinti)//1ms延时{ucharx,j;for(j=0;ji;j++)for(x=0;x=148;x++);}voiddelay(){inti,j;for(i=0;i=10;i++)for(j=0;j=2;j++);}4.4主程序设计主程序既把以上各子程序串连成一个整体,使整个程序循环运行。而在以上程序中也已经加入了个程序之间的连接点,首先进入程序后就立即进入显示子程序,而显示子程序内又调用键盘扫描子程序,若有键按下,则会跳转到移位子程序和结果计算子程序进行相应的处理。通过计算或移位后,数组内的值发生改变,显示的值也会同时发生改变。之后再进行键盘扫描,如此反复运行,就构成了程序的整体。整体程序清单如下:#includereg52.h#includeintrins.h#includemath.htypedefunsignedcharuchar;typedefunsignedintuint;voiddelay();ucharKeyscan(void);voidresult_a(void);voiddiaplay(void);voidDelay_1ms(uinti);ucharvie_a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};ucharexchg_a[16]={7,8,9,13,4,5,6,12,1,2,3,11,14,0,15,10};ucharxx[8];ucharxxu[8];voidSpeak_a(void);sbitspp=P3^7;//响铃sbitcl3=P3^6;//小数点sbitcl=P3^1;//求lnsbitcl0=P3^2;//开方sbitcl1=P3^3;//求logsbitcl2=P3^4;//求e的x次幂ucharflo[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xef,0xef};ucharzz[8]={0x77,0x3f,0x77,0x77,0x79};ucharDisbuf[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};ucharyy[8]={0x3f,0,0};floata=0,b=0,c;ucharL=1;ucharcal_a=0,dcounter=0;voidmain(void){ucharsinglp_a=1,n=1;ucharkey=18;ucharall_m=0,ent_a=0,att=1;signedlongs,r;TMOD=0x01;TH0=(65536-2000)/256;TL0=(65536-2000)%256;EA=1;ET0=1;TR0=1;spp=0;while(1){if(singlp_a==1){singlp_a=0;P3=0x7f;if(P3!=0x7f){Delay_1ms(2);if(cl==0){Speak_a();cal_a=14;//求以㏑xkey=15;}if(cl0==0){Speak_a();cal_a=15;//开方key=15;}if(cl1==0){Speak_a();cal_a=16;//求以十为底对数key=15;}if(cl2==0){Speak_a();cal_a=17;//求e的x次幂key=15;}if(cl3==0){att=0;xx[0]=xx[0]+0x80;}}P1=0x0f;if(P1!=0x0f){Delay_1ms(2);if(P1!=0x0f){key=exchg_a[Keyscan()];Speak_a();}}}P1=0x0f;P3=0x7f;if(P1==0x0f&&P3==0x7f){singlp_a=1;}if(key=9&&key=0){if(all_m==0){if(ent_a==0){uchari;ent_a=1;for(i=0;i=7;i++){xx[i]=0;}}else{}if(att==1){uchari;a=a*10+key;for(i=7;i0;i--){xx[i]=xx[i-1];}xx[0]=vie_a[key];key=18;}else{uchari;doublem;for(i=7;i0;i--){xx[i]=xx[i-1];}xx[0]=vie_a[key];m=key;for(i=1;i=n;i++){m=m/10;}a=m+a;n++;key=28;}}else{if(att==1){uchari;b=b*10+key;for(i=7;i0