基于51单片机的数字钟和音乐播放.docx
《基于51单片机的数字钟和音乐播放.docx》由会员分享,可在线阅读,更多相关《基于51单片机的数字钟和音乐播放.docx(35页珍藏版)》请在冰豆网上搜索。
基于51单片机的数字钟和音乐播放
原理图:
程序代码:
#ifndefDEF_H
#defineDEF_H
#defineTIME_MODEL1
#defineMUSIC_MODEL1
#definePROMPT_QUIT0
#defineALARM_SET_QUIT4
#defineTIME_SET_QUIT4
#defineCALENDAR_SET_QUIT5
#defineIN_ALARM_MODEL4
#defineOUT_ALARM_MODEL5
#defineLED_ON1
#defineLED_OFF0
#defineFM_ON0
#defineFM_OFF1
#defineQUIT_ALARM1
#defineNULL0
#defineALARM_PROMPT1
#defineONE_SECOND20
#defineSTART_CHOOSE1
#defineTIME_PROMPT0
#endif
/***************************************************
*****作品:
多功能LED电子钟*****************
*****芯片:
STC89C52**************
*****编译器:
KEIL**************
*****创建者:
JAKY***************
*****创作时间:
2010年12月4日***************
*****************************************************/
/**************************************************************
(1)能显示年、月、日、时、分、秒(通常显示时、分、秒);
(2)能对年、月、日、时、分、秒进行预置;
(3)具有定时功能,定时时间到声光报告。
(4)音乐播放功能(附赠功能)
(5)开机时按"+"进入时钟模式"-"进入音乐模式
**************************************************************/
////////////////////////////////////////////
/*****更新时间2010年12月6日******/
////////////////////////////////////////////
#include
#include"def.h"
#include
#defineucharunsignedchar
#defineuintunsignedint
constcharalarmPromptOut=2;
constcharalarmUp=1;
constcharalarmSet=4;
ucharcodecalendar[]="2010-12-04SAT";
ucharcodetime[]="time12:
30:
30";
ucharcodealarm[]="setalarm!
";
ucharcodealarm_default[]="00:
00:
00";
ucharcodeweek[]="MONTUSWENTHUFRISATSUN";
ucharcodetable[]="0123456789";
ucharcodetime_up[]="BABYTIMEUP!
";
ucharcodeprompt1[]="+:
playclock!
";
ucharcodeprompt2[]="-:
playmusic!
";
ucharcodemusic_prompt[]="PLAYMUSIC!
";
ucharcodemusic_prompt1[]="zhunipingan";
ucharcodeSONG[]={
//祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00
};
/********************
1602控制位
********************/
sbitrs=P1^2;
sbitrw=P1^1;
sbiten=P1^0;
sbitset_time=P3^2;
sbitset_add=P3^0;
sbitset_sub=P3^1;
sbitset_alarm=P3^3;
sbitset_calendar=P3^5;
sbitSpeak=P2^7;//蜂鸣器
sbitLED=P2^6;//LED
charsec,min,hour,day,month,year,DD;
uchari,t,w,k,j=13;
charcalendar_num,time_num,alarm_num;
charalarm_sec,alarm_min,alarm_hour;
bitclock_flag,music_flag,prompt_flag,YAD;
ucharalarm_flag;
ucharCount,exit_flag;
//////////////////////////////////////////////////////////////////
voidDelay_xMs(uintx);//延时子程序
voidPlay_Song(uchari);//播放音乐控制程序
voiddelay(ucharn);//延时函数n个毫秒
voidwrite_com(ucharcom);//1602写指令函数
voidwrite_da(uchardate);//1602写数据函数
voidwrite_data(ucharz,ucharx,uchartemp);//z行x位置写入temp
voiddisplay();//时间显示函数
voidalarm_set(void);//闹钟设定函数
voidamend(void);//日历时间闹钟调整函数
voidYMD();//天数计算函数
voidclock(void);//日历、时间计算函数
voidinit();//系统初始化函数
/////////////////////////////////////////////////////////////////
/*************************************
*****函数名:
main()
*****功能:
程序入口
*****输入:
无
*****输出:
无
*************************************/
voidmain(void)
{
init();
///////开机提示选择时钟模式或者音乐模式
while(prompt_flag)
{
for(i=0;i<16;i++){
write_data(0,i,prompt1[i]);
delay
(1);
}
for(i=0;i<16;i++){
write_data(1,i,prompt2[i]);
delay
(1);
}
amend();
if(prompt_flag==TIME_PROMPT)
{
for(i=0;i<16;i++){
write_data(0,i,calendar[i]);
delay
(1);
}
for(i=0;i<16;i++){
write_data(1,i,time[i]);
delay
(1);
}
}
}
while
(1)
{
///////////////时钟模式//////////////////////////
while(clock_flag){
if(!
(time_num||calendar_num)&&(alarm_flag==OUT_ALARM_MODEL)&&(exit_flag!
=alarmUp))
{
display();
}
amend();
if((alarm_sec==sec)&&(t==3)){//定时时间到
if(alarm_min==min){
if(alarm_hour==hour){
write_com(0x01);
for(i=0;i<16;i++)
{
write_data(0,i,time_up[i]);
delay
(1);
}
exit_flag=alarmUp;//退出闹钟到得标志位
YAD=QUIT_ALARM;//退出闹钟提示标志位
LED=LED_ON;//LED亮
Speak=FM_ON;//蜂鸣器响
}
}
}
if(YAD==QUIT_ALARM){
if(exit_flag==alarmPromptOut){//按+-键退出
YAD=NULL;
LED=LED_OFF;
Speak=FM_OFF;
write_com(0x01);
delay
(2);
for(i=0;i<16;i++){
write_data(0,i,calendar[i]);
delay
(1);
}
for(i=0;i<16;i++){
write_data(0,i,calendar[i]);
delay
(1);
}
for(i=0;i<16;i++){
write_data(1,i,time[i]);
delay
(1);
}
}
}
}
/////////////////////////////////////////////////////////
while(music_flag){///////进入音乐模式
for(i=0;i<16;i++){
write_data(0,i,music_prompt[i]);
delay
(2);
}
for(i=0;i<16;i++){
write_data(1,i,music_prompt1[i]);
delay
(2);
}
TR1=1;
Play_Song(0);
}
}
}
/**************************************
*****函数名:
time0()
*****功能:
50ms产生一次中断,精准计时
*****输入:
无
*****输出:
无
***************************************/
voidtime0(void)interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t++;
clock();
}
/********************************************************************
*名称:
Time0_Int()
*功能:
定时器中断,中断中实现Count加一
*输入:
无
*输出:
无
**********************************************************************/
voidtime1()interrupt3
{
TH1=0xDC;
TL1=0x00;
Count++;//长度加11
}
/********************************************************************
*名称:
Delay_xMs()
*功能:
延时子程序,经过软件调试,测得延时程序大概为55us.
*输入:
x
*输出:
无
***********************************************************************/
voidDelay_xMs(uintx)
{
uinti,j;
for(i=0;i{
for(j=0;j<3;j++);
}
}
/********************************************************************
*名称:
Play_Song()
*功能:
播放蜂鸣器控制程序
*输入:
i(选择播放哪首歌曲,0为“祝你平安”,1为“路边的野花你不要采”
*输出:
无
***********************************************************************/
voidPlay_Song(uchari)
{
ucharTemp1,Temp2;
uintAddr;
Count=0;//中断计数器清0
Addr=i*217;
while
(1)
{
Temp1=SONG[Addr++];
if(Temp1==0xFF)//休止符
{
TR1=0;
Delay_xMs(100);
}
elseif(Temp1==0x00)//歌曲结束符
{
return;
}
else
{
Temp2=SONG[Addr++];
TR1=1;
while
(1)
{
Speak=~Speak;
Delay_xMs(Temp1);
if(Temp2==Count)
{
Count=0;
break;
}
}
}
}
}
/*****************************************
*****函数名:
delay()
*****功能:
延时经测试小于40的对应毫秒
*****输入:
ucharn
*****输出:
无
******************************************/
voiddelay(ucharn)
{
ucharx,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
/******************************************
*****函数名:
write_com()
*****功能:
写指令
*****输入:
charcom
*****输出:
无
******************************************/
voidwrite_com(ucharcom)
{
rs=0;
rw=0;
en=1;
P0=com;
delay
(2);
en=0;
}
/*******************************************
*****函数名:
write_da()
*****功能:
写入数据
*****输入:
data
*****输出:
无
*******************************************/
voidwrite_da(uchardate)
{
rs=1;
rw=0;
en=1;
P0=date;
delay
(2);
en=0;
}
/**************************************************
*****函数名:
write_data()
*****功能:
在指定位置输入指定数据
*****输入:
ucharz,ucharx,uchartemp
*****输出:
无
**************************************************/
voidwrite_data(ucharz,ucharx,uchartemp)
{
if(z==0)
{
write_com(0x80+x);
}
else
{
write_com(0xc0+x);
}
write_da(temp);
}
/**************************************************
*****函数名:
display()
*****功能:
显示日历和实时时间
*****输入:
无
*****输出:
无
*************************************************/
voiddisplay_sec()
{
write_data(1,13,table[sec%10]);
delay
(1);
write_data(1,12,table[sec/10]);
delay
(1);
}
voiddisplay_min()
{
write_data(1,10,table[min%10]);
delay
(1);
write_data(1,9,table[min/10]);
delay
(1);
}
voiddisplay_hour()
{
write_data(1,7,table[hour%10]);
delay
(1);
write_data(1,6,table[hour/10]);
delay
(1);
}
voiddisplay_day()
{
write_data(0,9,table[day%10]);
delay
(1);
write_data(0,8,table[day/10]);
delay
(1);
}
voiddisplay_month()
{
write_data(0,6,table[month%10]);
delay
(1);
write_data(0,5,table[month/10]);
delay
(1);
}
voiddisplay_year()
{
write_data(0,3,table[year%10]);
delay
(1);
write_data(0,2,table[year/10]);
delay
(1);
}
voiddisplay_week()
{
for(k=3*w;k<3*w+3;k++)
{
write_data(0,j++,week[k]);
delay
(1);
}
j=13;
}
voiddisplay_alarm_sec()
{
write_data(1,11,table[alarm_sec%10]);
delay
(1);
write_data(1,10,table[alarm_sec/10]);
delay
(1);
}
voiddisplay_alarm_min()
{
write_data(1,8,table[alarm_min%10]);
delay
(1);
write_data(1,7,table[alarm_min/10]);
delay
(1);
}
voiddisplay_alarm_hour()
{
write_data(1,5,table[alarm_hour%10]);
delay
(1);
write_data(1,4,table[alarm_hour