打印

51单片机实现的音乐闹钟程序代码

[复制链接]
5908|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
songzhige|  楼主 | 2010-12-19 10:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 songzhige 于 2010-12-20 10:06 编辑

功能描述:产品可以显示时间和日期,时间格式为 hh mm ss  日期格式为 yy.mm.dd
                时间和日期轮流显示。 时间显示5S 日期显示3S。
                可以设置5个闹铃,闹铃音乐可以设置两种:毛驴和童年。
                 三个按键对时间和闹铃进行设置,六个LED进行显示。
                计时采用DS1307。继电时间不丢失,设置过的闹铃也不丢失。
                闹铃音乐由单片机的两个定时器去产生频率实现。

部分程序如下:
//*************************************************
//************************************************
//***********************************************
//程序名:DS1307 时钟程序
//功能描述:用六个八段LED 轮流显示时间
//          和日期。有6个闹钟。上电时从DS1307中读出
//          当前时间、日期、闹钟。
//
//
//
//
//
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define LED P2
#define LEDBit P0
#define nop  _nop_()
#define LightCount  40
#define LightMax    80
sbit SCL=P3^1;
sbit SDA=P3^0;
sbit ModeKey=P1^0;
sbit UpKey=P1^1;
sbit DownKey=P1^2;
sbit Speak=P3^6;
code uchar LCD_NUM[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //0x25,
//uchar  Clock[]={0x88,0x88,0x88};
code uint    Music_Sound_Long1[]={4,8,4,8,8,4,8,4,4,4,                     /*童年*/
                                   8,4,8,4,4,4,4,4,16,4,
           4,8,4,4,4,4,4,8,4,4,
           4,8,4,4,4,4,4,4,16,4,
           4,8,4,4,4,4,4,8,4,4,
           4,8,4,4,4,4,4,4,16,4,
           8,4,8,4,4,4,8,8,4,4,
           4,4,4,4,4,4,4,4,4,16,
           4,8,4,8,8,4,8,4,4,4,
           8,4,8,4,4,4,4,4,16,4,
           8,4,8,8,4,8,4,4,4,8,
           4,8,4,4,4,4,4,16,0},
              Music_Sound_Long2[]={4,4,4,4,4,4,4,4,4,4,           /*小毛驴*/
                          4,4,16,4,4,4,4,4,4,4,
           4,4,4,4,4,8,4,4,4,4,
           4,4,4,4,4,4,4,4,4,16,
           4,4,4,4,2,2,2,2,4,4,
           4,4,4,4,16,0},
     Music_Sound_Tone1[]={379,379,379,379,425,477,477,477,425,477,
                       568,637,637,637,568,637,425,379,477,719,  
                       637,637,719,637,568,568,506,568,568,568,
        637,477,477,477,477,568,477,568,637,719,
        637,637,719,637,568,568,506,568,568,568,
        637,477,477,477,477,568,568,477,851,318,
        318,318,318,379,425,477,477,568,477,568,
        477,425,425,425,425,425,477,379,425,425,
        379,379,379,379,425,477,477,477,425,477,
        568,637,637,637,568,637,425,379,477,379,
        379,379,379,425,477,477,477,425,477,568,
        637,637,637,568,637,425,379,477,0},         /*童年*/
  Music_Sound_Tone2[]={956,956,956,719,637,637,637,637,568,568,     /*小毛驴*/
                       568,477,637,716,716,716,568,719,719,719,
        719,851,851,851,851,637,637,956,956,956,
        719,637,637,637,637,568,568,568,477,637,
        716,716,716,568,719,719,719,719,719,719,
        851,851,851,719,956,0};

uchar  DS1307[27]={0};
//00 为秒,01为分,02为时
//10 为日,11为月,12为年
//20 为闹钟控制,21为分,22为时。
//30 为闹钟控制,31为分,32为时。
//40 为闹钟控制,41为分,42为时。
// 同上  
// 同上
//闹钟控制十位为闹钟数
//闹钟控制个位为选择闹钟声音程序
//个位为零关闭闹钟
uchar  DisplayArr[8][3]={0};

//*********************************
void Beep(void);
void DiplayClock(uchar *);
//void UsuaDisPlay(uchar *);
void Delay(uint Count);
void DiplayDelay(void);

void Start(void);
void Stop(void);
void ack(bit);
bit cack(void);

void Send8bit(unsigned char);  // 高字节位先传 字节最低位1为读,0为写
unsigned char Read8bit(void);
void SendWord(unsigned char,unsigned char);
unsigned char ReadWord(unsigned char);
void ReadDS1307(uchar);
//**************************
void ModeButten(void);
void UpButten(void);
void DownButten(void);
//********************
//函数名:INC
//功能:加1函数
void INC(void);
unsigned char Inc(uchar);
unsigned char Dec(uchar);
void Ring(void);
//*********************************
uchar Mode=0;    //Mode=0 轻按UP、Down为查看时间、日期、闹钟
                 //Mode=1
uchar Read=0;    //Read==1为读DS1307
uchar Juge=0;      //闪烁位数
uchar DisplyMode;
uchar Light;
uchar Black;
uchar DisplayLoop;
uchar RingFlag;
uchar  Sound_Long_Count;
uint Period;
/*********************  音乐频率中断  ******************************************/
void Music_Tone()interrupt 3 using 2
{
   
Speak=!Speak;
TL1=(65536-Period)&0xff;
TH1=(65536-Period)>>8;
TF1=0;
}
/**********************  10ms中断变量  ***************************************/
void Music_Long()interrupt 1  using 3
{

if(Sound_Long_Count!=0)Sound_Long_Count--;
TL0=(65536-10000)&0xff;
TH0=(65536-10000)>>8;
TF0=0;
/* TL2=(65536-10000)&0xff;
TH2=(65536-10000)>>8;
TF2=0;
*/
}      
//***********************************
main()
{
uchar i,j,Loop;
    uchar  RingMinBuffer;
uchar  RingHouBuffer;
uchar  RingMinBufferOld=0xff;
uchar RingTimeLong;
TMOD=0x11;         /*开定时器0,工作在方式3模式下*/
// TH0=TL0=0x6;      /*置定时器初值*/
TL0=(65536-10000)&0xff;
TH0=(65536-10000)>>8;
IE=0xca;          /*允许定时器中断*/
// ET2=1;
//**************************************************88
//**************************************************
   
/*
     for(i=0;i<6;i++)
     {
        Stop();
          Start();
             Send8bit(0xD0);
        if(cack()==1)continue;
        Send8bit(0x08+i*0x03);
     if(cack()==1)continue;
     Send8bit(i*0x10+0x10);
     if(cack()==1)continue;
     
     Stop();
      }
*/
    ReadDS1307(26);
for(DisplyMode=0;DisplyMode<8;DisplyMode++)
    {
    INC();
    }
DisplyMode=0;
    ReadDS1307(26);
        for(i=0,Loop=0;i<8;i++)
     for(j=0;j<3;j++,Loop++)
         {
          if(Loop==3)Loop++;
       if(Loop==7)Loop++;
          DisplayArr[j]=DS1307[Loop];
      }
   for(i=2;i<8;i++)
      for(j=0;j<3;j++)
      {
          switch(j)
            {
                    case 0:  DisplayArr[j]&=0x73;break;   //开关闹钟
        case 1:  DisplayArr[j]&=0x7F;break;    //分钟
        case 2:  DisplayArr[j]&=0x3F;break;
            }
      }
  
   DisplayArr[1][0]&=0x3F;     //日期
   DisplayArr[1][1]&=0x1F;  //月份

   Speak=0;
while(1)
   {
       //DisplayClock(6,Clock);
   
  //DiplayClock(Clock);
        //  DiplayClock(DisplayArr[DisplyMode]);
  //Juge=1;
   
     DiplayClock(DisplayArr[DisplyMode]);
//*****************************************************************111
//读出的数存入单片机中,
     if(Read==1)
       {
              ReadDS1307(26);
    Read=0;
     }
   else  ReadDS1307(6);

     DiplayClock(DisplayArr[DisplyMode]);
        for(i=0,Loop=0;i<8;i++)
     for(j=0;j<3;j++,Loop++)
         {
          if(Loop==3)Loop++;
       if(Loop==7)Loop++;
          DisplayArr[j]=DS1307[Loop];
       DiplayClock(DisplayArr[DisplyMode]);
      }
//******************************************************************111
//******************************************************************222
//读出的数格式化
   for(i=2;i<8;i++)
      for(j=0;j<3;j++)
      {
          switch(j)
            {
                    case 0:  DisplayArr[j]&=0x73;break;   //开关闹钟
        case 1:  DisplayArr[j]&=0x7F;break;    //分钟
        case 2:  DisplayArr[j]&=0x3F;break;
        default :
        
                            DiplayClock(DisplayArr[DisplyMode]);
            }
        DiplayClock(DisplayArr[DisplyMode]);
      }
  
   DisplayArr[1][0]&=0x3F;     //日期
   DisplayArr[1][1]&=0x1F;  //月份
//********************************************************************222
  
     DiplayClock(DisplayArr[DisplyMode]);
//  Beep();
  ModeButten();
  DownButten();
  UpButten();
     
     DiplayClock(DisplayArr[DisplyMode]);
//**********************************************333
//日期时间交替显示程序
            if(Juge==0)
   DisplayLoop++;
   if(DisplayLoop>10)DisplyMode=0;
   if(DisplayLoop>60)
     {
       DisplyMode=1;
    DisplayLoop=0;
      }
//***********************************************333
   
           
//************************************************444
//闹钟程序比较
          if(Juge==0)
     {  
             for(i=2;i<8;i++)
        {
             DiplayClock(DisplayArr[DisplyMode]);
              
           if(DisplayArr[0]&0x0F==0)continue;
        if(DisplayArr[1]!=DisplayArr[0][1])continue;
           RingMinBuffer=DisplayArr[1];
        if(RingMinBufferOld==RingMinBuffer)continue;
        if(DisplayArr[2]!=DisplayArr[0][2])continue;
               
        if(RingFlag==0)RingMinBufferOld=0xff;
           RingFlag=DisplayArr[0]&0x0F;
           
      }
   }
//************************************************444
              ModeButten();
          DownButten();
          UpButten();   
   DiplayClock(DisplayArr[DisplyMode]);
   RingTimeLong=0;
   switch (RingFlag)
      {
          case 1:
               {
             DisplyMode=0;
          i=0;
                               while(DisplayArr[0][1]==RingMinBuffer)        /*是否响闹铃1程序*/
                                    {
          /*  if(DisplayArr[0][1]!=RingMinBuffer)
               {
              RingMinBuffer=DisplayArr[0][1];
              RingTimeLong++;
             }
           */
           RingMinBufferOld=RingMinBuffer;
            if(Music_Sound_Long1==0)
            {
                 DiplayClock(DisplayArr[DisplyMode]);
                 i=0;
                      }
                     Sound_Long_Count=Music_Sound_Long1;/*****/
                     Period=Music_Sound_Tone1;
                     TL1=(65536-Period)&0xff;
                     TH1=(65536-Period)>>8;
      
                     DiplayClock(DisplayArr[DisplyMode]);
                     i++;
      
                     if(RingFlag==1)
               {
               TR1=1;
               TR0=1;
            }
                     while(Sound_Long_Count!=0)
            {
                 DiplayClock(DisplayArr[DisplyMode]);
              ModeButten();
            
              
                                            DownButten();
                                         UpButten();
              DiplayClock(DisplayArr[DisplyMode]);
              if(RingFlag==0)
                 {
              
                Sound_Long_Count=0;
              }
      
            }
            TR1=0;
            TR0=0;
                     
        }
        RingMinBufferOld=0xff;
         }
               break;
       case 2:
           {
              i=0;
        DisplyMode=0;
                       while(DisplayArr[0][1]==RingMinBuffer)             /*是否响闹铃2程序*/
                 {
         /*  if(DisplayArr[0][1]!=RingMinBuffer)
               {
              RingMinBuffer=DisplayArr[0][1];
              RingTimeLong++;
             }
         */
          RingMinBufferOld=RingMinBuffer;
          if(Music_Sound_Long2==0)
          {
                       DiplayClock(DisplayArr[DisplyMode]);
              i=0;
                    }
                   Sound_Long_Count=Music_Sound_Long2;
                   Period=Music_Sound_Tone2;
                   TL1=(65536-Period)&0xff;
                   TH1=(65536-Period)>>8;
        //           Display();
          i++;
          if(RingFlag==2)
             {
               TR1=1;
               TR0=1;
          }
                   while(Sound_Long_Count!=0)
          {
                     DiplayClock(DisplayArr[DisplyMode]);
           ModeButten();
         
         
                                   DownButten();
                                UpButten();
           DiplayClock(DisplayArr[DisplyMode]);
           if(RingFlag==0)
               {
              Sound_Long_Count=0;
         
            }
          }
          TR1=0;
          TR0=0;
        }
       RingMinBufferOld=0xff;      
        }
       break;
                default: break;
      }
       /**/
   }

}
//*******************************
//void Ring(void)
//{
//   uchar i,j;
//}
//*******************************
//void Beep(void)
//{
//       uchar j,k;
//  for(j=0;j<17;j++)
//    {
//      Speak=1;
//   for(k=0;k<200;k++);
//   Speak=0;
//   for(k=0;k<200;k++);
   
//       }
//}
//********************************
void DownButten(void)
{
  bit Flag;
  //DiplayClock(Clock);
   uchar Buffer;
  DiplayClock(DisplayArr[DisplyMode]);
  DownKey=1;
  Flag=DownKey;
  if(Flag==0)
    {
        //DiplayClock(Clock);
     //DiplayClock(Clock);
     //DiplayClock(Clock);
   
     DiplayClock(DisplayArr[DisplyMode]);
   DisplayLoop=0;
         DownKey=1;
        Flag=DownKey;
         while(Flag==0)
            {
               TR0=0;
      TR1=0;
      if( RingFlag!=0) RingFlag=0;
         //DiplayClock(Clock);
         //DiplayClock(Clock);
      DiplayClock(DisplayArr[DisplyMode]);
      if(Mode==1)
        {
             Read=1;
            switch (DisplyMode)
             {
           case  0 :             //时间
                     {
       转载http://www.songzhige.com/post/265.html

相关帖子

沙发
shiwilson| | 2010-12-19 11:55 | 只看该作者
这么长的代码,看得我懵懵的

使用特权

评论回复
板凳
Messia| | 2010-12-20 08:38 | 只看该作者
图挂了,转帖子也要敬业些啊..把图弄出来起码

使用特权

评论回复
地板
ytfdhb| | 2010-12-20 13:22 | 只看该作者
走过路过,学习一下~~

使用特权

评论回复
5
scutzhh| | 2010-12-20 13:28 | 只看该作者
太长了!没劲!看都不想看!

使用特权

评论回复
6
冯冯冯冯| | 2010-12-20 15:31 | 只看该作者
有没有硬件图啊,嘿嘿想试试看你的程序。顺便在你这儿试试我学的新招式

使用特权

评论回复
7
qwqwqw2008| | 2010-12-31 18:59 | 只看该作者
不错,学习了:lol :victory:

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

190

帖子

3

粉丝