多功能数字电子表 总结报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子技术综合设计
总结报告
姓名:王功臣、刘聪学号: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 <reg52.h>
#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<reg52.h>
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.5s
a=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 班”。