当前位置首页 > 建筑/施工 > 设计及方案
搜柄,搜必应! 快速导航 | 使用教程  [会员中心]

多功能数字电子表 总结报告【文档知识】

文档格式:DOC| 28 页|大小 700KB|积分 20|2022-09-24 发布|文档ID:155753059
第1页
下载文档到电脑,查找使用更方便 还剩页未读,继续阅读>>
1 / 28
此文档下载收益归作者所有 下载文档
  • 版权提示
  • 文本预览
  • 常见问题
  • 电子技术综合设计总结报告姓名: 王功臣、刘聪 学号:04101686、04101680 专业与班级: 电气工程与自动化10-7班 设计题目: 多功能数字电子表 时 间: 2011 ~ 2012 学年第(1)学期 指导教师: 成 绩: 日 期: 绪论:随着计算机在社会各领域的渗透和大规模集成电路的发展,单片机的应用正不断的走向深入 单片机是一种集成在电路里的芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能集成到一块硅片上构成的一个小而完善的计算机系统随着单片机的不断发展,现已应用领域十分广泛 本文介绍的多功能数字电子钟的控制核心是单片机(STC89C52),以单片机内部定时计数器在计数满1s时产生一次中断,从而计数变量增加1,采用蜂鸣器、数码管显示器、语音报时电路以及其他电路构成。

    实现了时间显示、电子日历、时间预置、秒表、倒计时、闹铃、语音报时和复位等功能; 通过对多功能时钟的设计,加深对单片机的理解,熟悉了单片机的内部硬件资源,掌握单片机的编程方法,学会对单片机各部分硬件资源的控制方法此外,还要学会怎么利用所学单片机知识独立设计系统的能力,达到学于致用的目的,要学会发创设计编程思想,要学会开发系统的一般过程,并不断创新.一 课题任务名称:多功能数字电子表基本要求:计时功能:显示时、分、秒,定闹功能,秒表功能,倒计时功能提高要求:增加“语音报时”功能,增加“电子日历”功能二 方案比较与选择方案一:采用中规模集成电路,由电容、电阻、CMOS非门、晶体组成震荡电路提供一个频率稳定的方波信号,分频器电路将高频方波信号经若干次分频后得到1Hz的方波信号供秒计数器进行计数,秒位、分位、时位计数器分别为60、60、24进制计数器,译码驱动电路将计数器输出的8421BCD码转换为数码管需要的逻辑状态,并且为保证数码管正常工作提供足够的工作电流整点报时、校时等功能也可以通过与非门组成的逻辑电路来实现方案二: 采用单片机内部定时计数器中断,控制计数变量,将计数变量通过单片机引脚送至总线驱动,为数码管提供足够的电流,通过程序控制每位数码管,实现动态显示。

    通过7个按键来实现时间预置、秒表、倒计时、闹钟设置、复位的功能在没有中断,没有按键按下的时候,单片机循环执行显示程序,当中断发生时、有按键按下时,单片机进入相应的子程序执行语音报时电路采用isd1420语音芯片,用麦克风录下人声,单片机控制语音芯片在适当的时候通过喇叭播放事先录好的声音附加功能都可以通过单片机程序来实现方案比较:方案一重要用逻辑电路来实现,需要的芯片较多,集成化低,功能越多,硬件电路越复杂,需要的芯片比较多,成本也较高,故障率高,而且技术相对落后方案二采用单片机控制,可以方便地控制外围的器件,所有的功能都可以通过编程来实现,实现的功能也更加丰富,需要的芯片数少, 电路相对简单综合比较两种方案,本设计决定采用方案二三 电路设计3.1系统总体框图3.2 各部分电路设计3.2.1 复位电路 在RST复位引脚接一个电容到VCC,接一个电阻到地就可以了在给系统上电时,复位电路通过电容加到RST复位引脚一个短暂的高电平信号,这个复位信号随着VCC对电容的充电过程而回落,所以RST引脚复位的高电平维持时间取决于电容的充电时间为了保证系统安全可靠的复位,RST引脚的高电平信号必须维持足够长的时间。

    电路图如图3.2.2 时钟电路 时钟是单片机的心脏,单片机各功能部件的运行都是以时钟频率为基准, MCS-51单片机内部有一个用于构成振荡器的高增益反相放大器,该高增益反向放大器的输入端为芯片引脚XTAL1,输出端为引脚XTAL2这两个引脚跨接石英晶体振荡器和微调电容,就构成一个稳定的自激振荡器电路中的C1、C2的选择在30PF左右,但电容太小会影响振荡的频率、稳定性和快速性晶振频率为在1.2MHZ~12MHZ之间,频率越高单片机的速度就越快,但对存储器速度要求就高为了提高稳定性我们采用温度稳定性好的NPO电容,采用的晶振频率为12MHZ本次系统的时钟电路设计如图 3.2.3数码管显示电路用六个共阳极7段数码管动态扫描显示时间变量,单片机P3口和P0口分别给数码管送位码和字型码,由于P0口没有内置上拉电阻,它输出不了高电平,所以要先给P0口加上上拉电阻由于数码管输出电流比较小,由P3经过总线驱动器74ls573(或245)给需要显示的数码管的阳极高电平,为数码管提供足够的电流,这样相应的数码管就会点亮,延时一段时间接着显示下一位,循环显示数码管管压降3.5v左右静态显示时工作电流大约5mA,动态显示时工作电流大约20mA,这里动态显示六个数码管,电流取30mA,所以,流过数码管的的限流电阻计算为:R=(5v-3.5v)/0.03A=50欧姆。

    3.2.4语音芯片电路采用ISD1420语音芯片,它是美国ISD公司出品的优质单片语音录放电路,由振荡器、语音存储单元、前置放大器、自动增益控制电路、抗干扰滤波器、输出放大器组成一个最小的录放系统仅由一个麦克风、一个喇叭、两个按钮、一个电源、少数电阻电容组成使用方便的单片录放系统,外部元件少,信息可保存100年,可反复录放10万次 录音端/REC和下降沿触发放音端/PLAYE分别接开关,用于手动录放音测试按下开关,此端为低电平,开始录音或放音此外,录音端口/REC还接到了三极管的集电极,三极管的基极由单片机的P1.0口控制,用于软件控制录音,每当P1.0为高电平时,按照事先设定好的录音时间和存放地址开始录音三极管的发射极接了一个led,用于提示录音(录音期间led亮,录音结束led灭),集电极接了开关,不录音时关断开关,防止单片机影响引起误录音3.2.5按键电路P1口通过10K的电阻接+5v电源,同时通过开关接地,开关没按下时P1口为高电平,当按键按下时P1口为低电平3.2.6 蜂鸣器驱动电路由于蜂鸣器额定电流较大,所以单片机无法直接驱动,这里用npn三极管驱动,电路图如图,由单片机控三极管基极来控制三极管的导通与关断。

    蜂鸣器两端电压按照1.5v计算,三极管集电极限流电阻计算公式为R=(5v-0.3v-1.5v)/50mA=64欧姆四 程序设计4.1 总体思路采用定时计数器中断T0, 10ms中断一次,秒表计时变量m[0]加1,依次往下进位m[0]满100,计时变量a[7]的秒变量a[0]加1,依次向下进位延时函数 主函数为一个大的while(1)循环,在这个循环里先进行初始化,然后进入第二个while(1)循环,在没有按键按下时一直显示当前时间变量,当有按键按下时,进入按键函数,再次返回后判断复位变量restar是否为1,为1则跳出小的while(1)循环,在大循环中进行初始化然后再进入小的while(1)循环中 显示函数分为普通显示函数和时间预置状态下的显示函数时间预置状态下的显示函数通过两个形参来确定要显示的变量以及要显示小数点的位(用于标示可调位)按键函数keyscan()分为7个子功能函数,通过判断分别进入不同的功能函数执行4.2 程序框图(总体)五 测试方案5.1仿真测试各个按键功能的程序分别编写,一个功能的程序编好后,在protues里仿真,出现问题回去分析修改程序直到仿真成功然后开始接着写下一个功能程序,按照同样的方法测试仿真各个功能程序。

    5.2 语音电路部分测试a)不用单片机控制,给语音芯片的地址端接低电平,从0x00开始录音,上电,按下录音按键,说一段语音,松开录音键,按下播放按键,看喇叭是否正常播放刚才录下的语音b)通过录音程序,由单片机控制,上电,录音指示灯开始亮灭闪烁,指示灯亮时开始录入“1”、“2”、“3”、“4”、“5”·····的语音然后通过放音按键看播放是否正确5.3 数字钟部分测试a) 将程序烧进单片机,上电运行,观察数码管是否从00.00.00开始计时b) 按下按键3,看数码管显示是否进入时间预置状态各个可调位的移动是否正确,各个位的增减是否可以,进率是否正确设置好时间,再次进入时间预置状态,看年月日十分秒星期是否正确,退出状态是否顺利c) 按下按键4,看数码管显示是否进入秒表状态,通过按键1(开始暂停键)和按键2(清零键)观察秒表是否正确,退出状态是否顺利d) 按下按键5,应该进入倒计时状态,按照“b)”的方法进行倒计时初始时间设置的测试然后再按下按键5,观察倒计时状态,观察计到零时是否停止在00.00.00,退出状态是否顺利e) 按下按键6,看是否进入闹钟时间设置状态,按照“b)”的方法进行闹钟时间预置测试。

    退出此状态,等待时间到达闹钟时间观察语音芯片是否报时f) 在任意状态下按下按键7观察数码管是否复位清零从00.00.00开始显示g) 测试整点报时可以先将时间设置在靠近整点前,然后观察到整点时蜂鸣器、语音芯片是否都能正常报时六 测试结果与系统调试a)在各个按键功能的仿真测试上,每个功能按键的程序上都浪费了很长时间,出现了很多问题比如:进率错误、复位按键不灵、显示不稳定、显示乱码、状态跳不出来等等最终,数字钟显示功能包括时间显示(包括年月日星期)、时间预置、秒表、倒计时、闹钟、蜂鸣器整点报时、复位都能较好地实现b)一开始,功能正确,但数码管显示非常暗,几乎看不清,一位是限流电阻太大了,改成小的还是不行,有把限流电阻短路掉,数码管显示仍然很暗,最后反复检查电路后发现我们使用的是共阳极数码管,而电路中总线驱动器74ls573接在了字型码信号输出端,将573改接到位选信号线上数码管显示就正常了c) 语音电路一直没有反应,录音之后放不出音,后来发现ISD1420芯片根本买有焊到电路里去,由于芯片没有封装,所以没有引脚,只有28个焊点,要认为地用插针将它固定在电路板上,然后插针的两端分别和电路板和芯片焊在一起。

    这个问题解决之后电路也检查了几遍语音功能还是没有成功我觉得是不是有原件坏了八 总结通过实践,基本完成了多功能数字钟的设计制作,它可以实现时间显示(包括年月日星期)、时间预置、秒表、倒计时、闹钟、蜂鸣器整点报时、复位的功能,基本功能实现得比较充分、丰富从最初的选题、方案选择、查资料、电路设计、程序设计、原件参数的计算、焊接,整个过程下来,自己的基本的能力有了很大的提高数字钟这个选题,电路不是很复杂,主要是编程麻烦点,很多功能的实现都需要比较复杂的程序来实现,程序的逻辑性比较强,所以,感觉最有收获的应该是C语言编程得到了很好的锻炼为了美观同时也锻炼焊接技术,我们在焊接时尽量少用排线多用焊锡另外,通过一起努力,也锻炼了我们的团队合作能力我们的设计也存在着一些不足:(1) 语音电路没有实现,时间有限,检测调试也没有出结果2) 焊锡的走线存在浪费的现象,可能原件布局不是很合理另外,有的原件焊错了之后有的线就成了“废线”3) 程序太长,一些功能应该还有更好更简洁的算法来实现这些不足也是以后应该努力的地方九 参考文献[1]. 夏兰 ,等.语音芯片ISD1420在轴位移监控表中的应用[J].自动化技术与应用.2004,23(11)[2].周润景,等.单片机电路设计分析与制作[M].北京:机械工业出版社,2010.5[3]. 胡汉才,单片机原理及接口技术,清华大学出版社,1996十 附录A 电路设计图a)原理图b)PCB图B程序主程序:青草绿#include #define uint unsigned int #define uchar unsigned char void playsound(uchar a[7]);sbit key1=P1^0; //key1~key7为数字钟功能按键sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit key6=P1^5;sbit key7=P1^6;sbit PLAYLE=P2^7; //语音芯片放音控制位sbit baoshi=P1^7; //整点报时控制位uchar restar=0,count=0; //restar:复位标志位 count:中断次数记录变量uchar a[7]={0}; //存放计时变量星期、年、月、日、时、分、秒uchar m[3]={0}; //存放秒表计时变量分钟、秒、毫秒uchar g[3]={0}; //存放闹钟时间变量 存放时、分钟、秒uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管段码uchar code table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点的段码//*********************************************延时函数******************************************************//void delay( uint ms) //延时函数{uchar i; while(ms--) for(i=0;i<110;i++);} //*********************************************中断函数*****************************************************//void Timer0(void) interrupt 1 {TH0=(65535-10000)/256; TL0=(65535-10000)%256; m[0]++; //每10ms中断一次,秒表计数变量的毫秒位加1 if(m[0]==100) {m[0]=0; // 毫秒位满100置0,秒位加1 m[1]++; a[0]++; //计时变量秒位加1 baoshi=0; //整点报时蜂鸣器响1s结束 PLAYLE=1; // 语音控制端置高,为下一次下降沿触发放音做准备 if((a[0]==g[0]&&a[1]==g[1]&&a[2]==g[2])||(a[2]==g[2]&&g[1]==1&&g[0]==0&&a[1]==0&&a[0]==60)) //若当前时间和闹钟预置时间相等,则: //若闹钟预置时间为01:01:00或00:01:00,则判断a[0]是否为60 P2=0x4b; //给送语音芯片送播放地址 PLAYLE=0; // 开始播放“起床起床起床起床”的声响if(m[1]==100) //秒位满100置0,更高位加1{m[1]=0; m[2]++; if(m[2]==100) m[2]=0;} if(a[0]==60) //秒变量满 {a[0]=0; a[1]++; if(!(g[1]==1&&g[0]==0)) // 如果特殊情况(闹钟预置时间为01:01:00或00:01:00)不满足, if(a[1]==60) //分钟变量满 {a[1]=0; a[2]++; baoshi=1; //若分钟变量满则蜂鸣器整点报时(P1.7输出高电平),维持1秒 playsound(a); //调用放音函数进行语音整点报时 if(a[2]==24) {a[2]=0; a[3]++; if (a[3]==31&&(a[4]==4||a[4]==6||a[4]==9||a[4]==11)) //日变量加到31溢出(4、6、9、11月) {a[3]=0; a[4]++; } else if (a[3]==32&&(a[4]==1||a[4]==3||a[4]==5||a[4]==7||a[4]==8||a[4]==10||a[4]==12)) // 日变量加到32溢出(1、3、5、7、8、10、12月) {a[3]=0; a[4]++; } else if (a[3]==29&&a[4]==2&&a[5]%4!=0) //日变量加到29溢出(平年的2月) {a[3]=0; a[4]++; } else if(a[3]==30&&a[4]==2&&a[5]%4==0) //日变量加到30溢出(润年的2月) {a[3]=0; a[4]++; } else ; } } } }}//************************************显示函数********************************************************************//void disp(uchar a[7]) {P3=0x20; P0=table[a[0]%10]; delay(2); P3=0x10; P0=table[a[0]/10]; delay(2); P3=0x08; P0=table1[a[1]%10]; delay(2); P3=0x04; P0=table[a[1]/10]; delay(2); P3=0x02; P0=table1[a[2]%10]; delay(2); P3=0x01; P0=table[a[2]/10]; delay(2);}//*************************************语音整点报时函数*********************************************************************//void playsound(uchar a[7]) { uchar i; uchar ad; if(a[2]<=10) { P2=0x41; //语音“现在时间”的地址, PLAYLE=0; for (i=0;i<10;i++)disp(a); //放音期间显示时间 PLAYLE=1; ad=a[2]*5; //语音"*"的地址 P2=ad; PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; P2=0x55; //语音"点整"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; } if(a[2]>10&&a[2]<=19) { P2=0x41; //语音"现在时间"的地址 PLAYLE=0; for (i=0;i<10;i++)disp(a); PLAYLE=1; P2=0x32; //语音"十"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; ad= a[2]*5%10; //语音"*"的地址 P2=ad; PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; P2=0x55; //语音"点整"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; } if(a[2]==20) { P2=0x41; //语音"现在时间"的地址 PLAYLE=0; for (i=0;i<10;i++)disp(a); PLAYLE=1; P2=0x0a; //语音"二"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; P2=0x32; //语音"十"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; P2=0x55; //语音"点整"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; } if(a[2]>20&&a[2]<24) { P2=0x41; //语音"现在时间"的地址 PLAYLE=0; for (i=0;i<10;i++)disp(a); PLAYLE=1; P2=0x0a; //语音"二"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); P2=0x32; //语音"十"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; ad=a[2]*5%10; //语音"*"的地址 P2=ad; PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; P2=0x55; //语音"点整"的地址 PLAYLE=0; for (i=0;i<5;i++)disp(a); PLAYLE=1; } }//*****************************时间预置显示函数(使用小数点区别预置位和其他位)*******************************************//void disp1(uchar f[7],uchar n) { if(n<4) //n小于4表示,key3按下的次数小于4,数码管显示时分秒,预置位为时、分或秒位 { P3=0x20; //显示秒 if(n==1) //若n等于1,表示key3只按一次,预置位为秒位 P0=table1[f[0]%10]; else P0=table[f[0]%10]; delay(2); P3=0x10; //显示秒 if(n==1) P0=table1[f[0]/10]; else P0=table[f[0]/10]; delay(2); P3=0x08; //显示分 if(n==2) P0=table1[f[1]%10]; else P0=table[f[1]%10] ; delay(2); P3=0x04; //显示分 if(n==2) P0=table1[f[1]/10]; else P0=table[f[1]/10]; delay(2); P3=0x02; //显示时 if(n==3) P0=table1[f[2]%10]; else P0=table[f[2]%10]; delay(2); P3=0x01; //显示时 if(n==3) P0=table1[f[2]/10]; else P0=table[f[2]/10]; delay(2); } if(n>3&&n<7) //表示key3按下的次数为4、5或6,数码管显示年月日,预置位为年、月或日位 { P3=0x20; if(n==4) P0=table1[f[3]%10]; else P0=table[f[3]%10]; delay(2); P3=0x10; if(n==4) P0=table1[f[3]/10]; else P0=table[f[3]/10]; delay(2); P3=0x08; if(n==5) P0=table1[f[4]%10]; else P0=table[f[4]%10]; delay(2); P3=0x04; if(n==5) P0=table1[f[4]/10]; else P0=table[f[4]/10]; delay(4); P3=0x02; if(n==6) P0=table1[f[5]%10]; else P0=table[f[5]%10]; delay(2); P3=0x01; if(n==6) P0=table1[f[5]/10]; else P0=table[f[5]/10]; delay(2); } if(n>6) // 显示星期,预置位为星期位 { P3=0x20; P0=table1[f[6]%10] ; delay(2); }}//*****************************************按键函数*************************************************************************// void keyscan() { uchar num=1; //num表示要预置的计时变量的序号,按一下,预置位移动一位 uchar t=1; //t用在倒计时设置初始时间中,功能类似num uchar b[3]={0} ; //用于存放秒表正在运行时的时间变量(调用秒表显示函数的实参) uchar c[3]={0}; //用于存放秒表开始时刻的m[]值 uchar d[3]={0}; //用于存放上一次暂停时的b[]值 uchar e[3]={0}; uchar i=0,j=0; //*******************时间预置程序********************// if(key3==0) //key3:进入时间预置状态 {delay(10); if(key3==0) { EA=0; while(!key3)disp1(a,num); while(num<8) { while(key1&&key2&&key3&&key7) disp1(a,num); if(key3==0) //调整预置变量序号 { delay(10); if(key3==0) num++; } while(!key3)disp1(a,num); if(key2==0) { delay(10); if(key2==0) if(a[num-1]==0) switch(num) { case 1:a[num-1]=60;break; //若秒变量减到零,则置60 case 2:a[num-1]=60;break; //若秒变量减到零,则置60 case 3:a[num-1]=24;break; //若小时变量减到零,则置24 case 4:a[num-1]=31;break; //若日变量减到零,则置31 case 5:a[num-1]=13;break; //若月变量减到零,则置13 case 6:a[num-1]=100;break; //若年变量减到零,则置100(只显示年份的后两个数字) case 7:a[num-1]=8;break; //若星期变量减去到零,则置7 } a[num-1]--; //放在后面,防止计时变量一开始就0溢出 } while(!key2)disp1(a,num); if(key1==0) { delay(10); if(key1==0) a[num-1]++; switch(a[num-1]) //判断计时变量有没有达到溢出值 { case 13:if(num==5)a[num-1]=1;break ; case 24:if(num==3)a[num-1]=0;break; case 31:if(num==4)a[num-1]=1;break; case 60:if(num==1||num==2)a[num-1]=0;break; case 100:if(num==6)a[num-1]=0;break; case 8:if(num==7)a[num-1]=1;break; } } while(!key1)disp1(a,num); if(key7==0) //整机复位检测 {delay(5); if(key7==0) {restar=1;break;} } } } EA=1; while(!key7)disp(a); //复位键松手检测 } //******************秒表程序******************// if(key4==0) //进入秒表状态 {delay(5); if(key4==0) {while(!key4)disp(b); while(1) {if(key4==0) //若key4按下,退出抄表状态 {delay(5); if(key4==0) while(!key4)disp(b); break; } if(key2==0) //若key2复位键按下,显示000000 {delay(5); if(key2==0) {for(j=0;j<3;j++) {b[j]=0; d[j]=0; } while(!key2)disp(b); while(key1&&key4&&key7)disp(b); } } while(key2&&key4&&key7) //若key2、key4、key7键没按下,则执行下面程序 { if(key1==0) //若秒表启停位key1按下 { delay(5); if(key1==0) { // 状态变量i加1 i++; if(i%2==1) //若i为奇,启动秒表 { for(j=0;j<3;j++) c[j]=m[j]; while(!key1) { for(j=0;j<3;j++) b[j]=m[j]-c[j]+d[j]; disp(b); } while(key2&&key4&&key1) //若无按键按下,显示 { for(j=0;j<3;j++) b[j]=m[j]-c[j]+d[j]; disp(b); } } else // 否则,暂停秒表 { while(!key1)disp(b); while(key2&&key4&&key1&&key7)disp(b); for(j=0;j<3;j++) d[j]=b[j]; //记录暂停时b[]的值 } } } disp(b); } if(key7==0) //整机复位检测 {delay(5); if(key7==0) break; } disp(b); } } } //***************倒计时程序******************// if(key5==0) //进入倒计时状态 {delay(5); if(key5==0) { while(!key5)disp1(e,t); while(t<5) // 若按满5次退出秒表 { while(key1&&key2&&key5&&key7) disp1(e,t); if(key1==0) //如果key1按下,初始值加1 {delay(5); if(key1==0) { e[t-1]++; //相应的倒计初始值变量加1 if(e[t-1]==60&&(t==1||t==2)) //加到60,置0,进1 e[t-1]=0; if(e[t-1]==24&&t==3) //加到24,置0,进1 e[t-1]=0; while(!key1)disp1(e,t); while(key1&&key2&&key5&&key7)disp1(e,t); //若无按键按下,显示当前值 } } if(key2==0) //如果key2按下,初始值减1 {delay(5); if(key2==0) { if(e[t-1]==0&&(t==1||t==2)) e[t-1]=60; if(e[t-1]==0&&t==3) e[t-1]=24; e[t-1]--; while(!key2)disp1(e,t); while(key1&&key2&&key5&&key7)disp1(e,t); } } if(key5==0) //如果key5按下 {delay(5); if(key5==0) {t++; // 记录按下次数变量加1 if(t==1||t==2||t==3) // 按下次数为1、2或3,处于初始值预置状态 { while(!key5)disp1(e,t); while(key1&&key2&&key5&&key7)disp1(e,t); } if(t==4) //如果key5按下4次,则进入倒计时程序 { if(e[0]==0&&e[1]==0&&e[2]==0) // 若倒计时变量为0就进入倒计时状态,则 while(key1&&key2&&key5&&key7) //一直显示000000 disp(e); for(j=0;j<3;j++) {c[j]=a[j]; //c记录此刻计时变量 d[j]=e[j]; //d记录倒计时初始值 } while(!key5) {for(j=0;j<3;j++) {e[j]=d[j]-a[j]+c[j]; //做减法运算 disp(e); }} while(key5&&key7) {for(j=0;j<3;j++) e[j]=d[j]-a[j]+c[j]; if(e[0]==0&&(e[1]!=0||e[2]==0)) //减到60时向高位借位 {e[0]=59; e[1]-- ; } if(e[0]==0&&(e[1]==0||e[2]!=0)) { e[0]=59; e[1]=59; e[2]--; } if(e[0]==0&&(e[1]!=0||e[2]!=0)) {e[0]=59; e[1]--; if(e[1]==0) e[2]--; } if(e[0]==0&&e[1]==0&&e[2]==0) // 若倒计时时间减到0,则一直显示000000 while(key5&&key7)disp(e); disp(e); } while(!key5)disp(e) ; // key5按下了5次,跳出程序前松手检测 t++; //,t加1,使循环条件不满足,跳出倒计时函数 } } } if(key7==0) //整机复位检测 {delay(5); if(key7==0) {t=5;} } } } } //*********************闹钟程序**************************// if(key6==0) //key6:进入闹钟时间预置状态 {delay(5); if(key6==0) { while(!key6)disp1(g,num); while(num<4) { while(key1&&key2&&key6&&key7) disp1(g,num); if(key6==0) //调整预置变量序号 { delay(5); if(key6==0) num++; } while(!key6)disp1(g,num-1); if(key2==0) { delay(10); if(key2==0) if(g[num-1]==0) switch(num) { case 1:g[num-1]=60;break; //若秒变量减到零,则置60 case 2:g[num-1]=60;break; //若秒变量减到零,则置60 case 3:g[num-1]=24;break; //若小时变量减到零,则置24 } g[num-1]--; //放在后面,防止计时变量一开始就0溢出 } while(!key2)disp1(g,num); if(key1==0) { delay(5); if(key1==0) g[num-1]++; switch(g[num-1]) //判断计时变量有没有达到溢出值 { case 25:if(num==3)g[num-1]=0;break; case 61:if(num==1||num==2)g[num-1]=0;break; } } while(!key1)disp1(g,num); if(key7==0) { delay(5); if(key7==0) { restar=0;num=4; } } } } }//****************复位程序********************// if(key7==0) //key7:复位 { delay(10); if (key7==0) restar=1; }}//***************************************主函数******************************************************************************// void main() //主函数{ while(1) { a[0]=0; //初始化 a[1]=0; a[2]=0; a[3]=0; a[4]=0; a[5]=0; a[6]=0; TH0=(65535-50000)/256; TL0=(65535-50000)%256; TMOD=0x01; TR0=1; EA=1; ET0=1; restar=0; while(1) { while(!key7)disp(a); while(key3&&key4&&key5&&key6&&key7) disp(a); //若无按键按下,一直显示当前值 keyscan(); //有按键按下,进入键盘函数 if(restar==1) //判断复位标志位 break; } }}录音程序:#include sbit a=P3^7 ;void delay(){ unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0;j--) for(k=81;k>0;k--);}void main() { a=0; P2=0x00; //录音“0”,放入0x00开始的5个存储单元a=1; //开始录音 delay(); //延时0.5sa=0; //结束录音 delay(); //延时2s,为下一次录音做准备 P2=0x05;//录音"1",放入0x05开始的5个存储单元 a=1; delay(); a=0; delay(); P2=0x0A;//录音"2",放入0x0a开始的5个存储单元a=1; delay();a=0; delay(); P2=0x0F;//录音"3",放入0x0f开始的5个存储单元a=1; delay();a=0; delay(); P2=0x14;//录音"4",放入0x14开始的5个存储单元a=1; delay();a=0; delay(); P2=0x19;//录音"5",放入0x19开始的5个存储单元a=1; delay();a=0; delay(); P2=0x1E;//录音"6",放入0x1e开始的5个存储单元a=1; delay();a=0; delay(); P2=0x23;//录音"7",放入0x23开始的5个存储单元a=1; delay();a=0; delay(); P2=0x28;//录音"8",放入0x28开始的5个存储单元a=1; delay();a=0; delay(); P2=0x2D;//录音"9",放入0x2d开始的5个存储单元a=1; delay();a=0; delay(); P2=0x32;//录音"10",放入0x32开始的5个存储单元a=1; delay();a=0; delay(); P2=0x37; //录音"点整",放入0x37开始的5个存储单元a=1; delay();a=0; delay(); P2=0x3C; //录音"1",放入0x05开始的5个存储单元a=1; delay();a=0; delay(); P2=0x41;//录音“现在时间”,放入0x41开始的5个存储单元a=1; delay(); //延时1s delay();a=0; delay(); P2=0x4B;//录音“起床起床起床起床”a=1; delay();//一共延时2s delay(); delay(); delay(); delay(); delay();a=0; delay();}C 相关作品图片见文件夹“多功能数字电子表+说明书+王功臣+电气10-7 班”。

    点击阅读更多内容
    卖家[上传人]:888
    资质:实名认证