找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6976|回复: 14
收起左侧

单片机电子闹钟程序

  [复制链接]
ID:83249 发表于 2015-6-17 12:13 | 显示全部楼层 |阅读模式
//****************头文件及宏定义*******************************
#include <reg51.h>
#define   uchar  unsigned char
#define   uint   unsigned int
//****************软件延时程序*********************************
void delay(uint ii)
        { while(--ii); }
//****************定义数码管驱动码******************************
uchar duan[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,
0XBF,0XFF,0X7F}; //段选,0  1  2  3  4  5  6  7  8  9  -  灭 .
uchar  wei[]={0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};//位选,共阳,从右至左
//****************定义变量**************************************
uchar t=0,sec=0,min=0,hour=0;        //正常走时时间变量
uchar sec1=0,min1=0,hour1=0;     //时间设定值变量
uchar sec2=0,min2=0,hour2=0;     //闹钟设定值变量
uchar alarm_en=0;                //闹钟开关变量
uchar alarm_flag=0;              //闹钟定时到达标志变量
uchar p3=0,moshi=0,mov=0;        //P3口查询,模式值,调整位
//显示缓冲区,依次为正常、调时、闹钟设定、调整位带点标记
uchar temp[8],temp1[8],temp2[8],temp3[8];
//****************函数声明*************************************
void  initialize(void);          //初始化
void  show(void);                //正常走时显示
void  show1(void);               //时间设定显示
void  show2(void);               //闹钟设定显示
void  show3(void);               //调整位标记
void  show4(void);               //闹钟开关标记
void  keyscan(void);             //键盘扫描
void  add(void);                 //调时调闹钟加数程序
void  confirm(void);             //调时确认,闹钟开关
void  alarm_judge(void);         //闹钟定时到达判定
void  beep(void);                //闹钟响铃程序
//******************主函数***************************
void main()
{
   initialize();
   while(1)
       {
              keyscan();
                 alarm_judge();
                 switch(moshi)
                       {
                              case 0:show(); show4();break;         //显示正常走时
                                 case 1:show1();show3();break;    //显示设置时间
                                 case 2:show2();show3();break;    //显示闹钟时间
                           }
                 if(alarm_flag==1 && alarm_en==1)                 //定时时间到达且闹钟打开
                       {  beep(); }
           }
}
//*****************定时器初始化**************************
void initialize(void)
{
   TMOD = 0x01;
    TH0 = 0X3C;
    TL0 = 0XB0;           //50ms
    ET0 = 1;
     EA = 1;
TR0 = 1;

        P1=0X7F;         //初始化时关掉蜂鸣器
    alarm_flag=alarm_en=0;
}
//*****************定时器T0中断服务程序****************
void Timer0(void) interrupt 1
{   
   TL0 = 0XB0;
   TH0 = 0X3C;

   t++;
   if(t==20)                // (50ms*20=1s)
          { t=0;   sec++; }      
   if(sec==60)              // 秒为60,则清零,分加1
          { sec=0; min++; }
   if(min==60)              // 分为60,则清零,时加1
          { min=0; hour++;}
   if(hour==24)             // 时为24,则清零
          { hour=0;}

   if(sec1==60)  
          { sec1=0; min1++; }
   if(min1==60)  
          { min1=0; hour1++;}
   if(hour1==24)
          { hour1=0;}

   if(sec2==60)  
          { sec2=0; min2++; }
   if(min2==60)  
          { min2=0; hour2++;}
   if(hour2==24)
          { hour2=0;}
}
//******************正常时间显示程序*******************
void show(void)
{
    uchar i=0;

     temp[0]=sec%10;
        temp[1]=sec/10;
        temp[2]=10;
     temp[3]=min%10;
     temp[4]=min/10;
        temp[5]=10;
        temp[6]=hour%10;
        temp[7]=hour/10;

    for(i=0;i<8;i++)
        {
              P2=wei[i];
              P0=duan[temp[i]];
              delay(100);
        }
}
//******************调时模式显示程序*******************
void show1(void)
{
    uchar i=0;
         
     temp1[0]=sec1%10;
        temp1[1]=sec1/10;
        temp1[2]=10;
     temp1[3]=min1%10;
     temp1[4]=min1/10;
        temp1[5]=11;
        temp1[6]=hour1%10;
        temp1[7]=hour1/10;

    for(i=0;i<8;i++)
        {
              P2=wei[i];
              P0=duan[temp1[i]];
              delay(100);
        }
}

//******************闹钟设定模式显示程序*******************
void show2(void)
{
    uchar i=0;

     temp2[0]=sec2%10;
        temp2[1]=sec2/10;
        temp2[2]=11;
     temp2[3]=min2%10;
     temp2[4]=min2/10;
        temp2[5]=10;
        temp2[6]=hour2%10;
        temp2[7]=hour2/10;

    for(i=0;i<8;i++)
        {
              P2=wei[i];
              P0=duan[temp2[i]];
              delay(100);
        }
}

//******************调整位标记显示程序*******************
void show3(void)
{
     uchar movv=0;
     switch(mov)
               {
                     case 0:movv=0;        break;
                         case 1:movv=3;        break;
                         case 2:movv=6;        break;
                   }
     P2=wei[movv];
        P0=duan[12];
        delay(100);
}
//*********************闹钟开闭显示程序*******************
void show4(void)
{
   if(alarm_en==1)
     {
        P2=wei[2]+wei[5];
           P0=duan[12];  
           delay(100);
         }   
}
//******************键盘扫描程序***********************
void keyscan(void)
{
          P3=0XFF;
       p3=P3;
   if(p3==0XFF) return;

   if(p3==0XFE)                //key_mode键
      {
            delay(10);
                if(p3==0XFE)
                  {
                    moshi++;
                        if(moshi>=3) moshi=0;                       
                  }
                while(p3==0XFE)   // key_mode键按下到弹起期间
                   {
                     p3=P3;
                         switch(moshi)
                       {
                             case 0:show(); break;           //显示正常走时
                                 case 1:show1();break;    //显示设置时间
                                 case 2:show2();break;    //显示闹钟时间
                           }
                   }             
          }

   if(p3==0XFD)            //key_add键
      {
            delay(10);
                if(p3==0XFD)
                  {
                        add();
                  }

                while(p3==0XFD)    // key_add键按下到弹起期间
                   {
                         p3=P3;
                         switch(moshi)
                       {
                             case 0:show(); break;           //显示正常走时
                                 case 1:show1();break;    //显示设置时间
                                 case 2:show2();break;    //显示闹钟时间
                           }
                   }            
          }

   if(p3==0XFB)                 //key_move键
      {
            delay(10);
                if(p3==0XFB)
                  {
                         mov++;
                         if(mov>=3) mov=0;                         
                  }
                while(p3==0XFB)   // key_move键按下到弹起期间
                    {
                          p3=P3;
                          switch(moshi)
                       {
                              case 0:show(); break;           //显示正常走时
                                 case 1:show1();break;    //显示设置时间
                                 case 2:show2();break;    //显示闹钟时间
                           }
                    }            
          }

   if(p3==0XF7)            //key_confirm键
      {
            delay(10);
                if(p3==0XF7)
                  {
                        confirm();
                  }
                while(p3==0XF7)       // key_confirm键按下到弹起期间
                   {
                     p3=P3;
                         switch(moshi)
                       {
                             case 0:show(); break;           //显示正常走时
                                 case 1:show1();break;    //显示设置时间
                                 case 2:show2();break;    //显示闹钟时间
                           }
                   }             
          }
}  

//******************调时调脑钟增数程序***********************
void  add(void)
{
  //模式1,调时模式,调时增数
  if(moshi==1 && mov==0)
    {sec1++;}  
  if(moshi==1 && mov==1)
    {min1++;}
  if(moshi==1 && mov==2)
    {hour1++;}

  //模式2,闹钟设定模式,闹钟增数                
  if(moshi==2 && mov==0)
    {sec2++;}  
  if(moshi==2 && mov==1)
    {min2++;}
  if(moshi==2 && mov==2)
    {hour2++;}         
}



//******************确认键服务函数***************************
void  confirm(void)
{
  if(moshi==1)                 //模式1,调时环境下校正时间
    {
          t=TF0=0;
          sec=sec1;
      min=min1;
      hour=hour1;
      sec1=min1=hour1=0;
        }

  alarm_en++;         //开闭闹钟
  if(alarm_en>1) alarm_en=0;
}

//******************闹钟判断函数******************************
void  alarm_judge(void)
{
   if(hour==hour2 && min==min2 && sec==sec2 )         //定时到达设定标志
          { alarm_flag=1; }
   if(hour==hour2 && min==min2+1)                  //常规响铃一分钟
          { alarm_flag=0; }          
}

//******************闹钟响铃函数******************************
void  beep(void)
{
        P1=!P1;
}


评分

参与人数 2威望 +2 黑币 +51 收起 理由
1677012963 + 2 + 1 赞一个!
admin + 50 共享资料的积分奖励!

查看全部评分

回复

使用道具 举报

ID:83328 发表于 2015-6-18 09:07 | 显示全部楼层
楼猪有没有仿真图
回复

使用道具 举报

ID:69408 发表于 2015-6-20 11:52 | 显示全部楼层
不错!学习学习,有仿真图就更好了.
回复

使用道具 举报

ID:83478 发表于 2015-6-21 20:30 | 显示全部楼层
楼主这程序有点小问题啊!上电后,按下闹铃键后闹钟立马就响了。我找了一下问题可能是初次扫描时 hour==hour2 && min==min2 && sec==sec2, 导致alarm_flag=1; 因为在定义和初始化时 t=0,sec=0,min=0,hour=0;        
uchar sec1=0,min1=0,hour1=0;     
uchar sec2=0,min2=0,hour2=0;
不知道对不对!求指教~~~
回复

使用道具 举报

ID:83478 发表于 2015-6-21 20:40 | 显示全部楼层
1677012963 发表于 2015-6-21 20:30
楼主这程序有点小问题啊!上电后,按下闹铃键后闹钟立马就响了。我找了一下问题可能是初次扫描时 hour==hou ...

不好意思!!新人没多少黑币~
回复

使用道具 举报

ID:82937 发表于 2015-6-22 12:01 | 显示全部楼层
你有更详细的资料吗》?
回复

使用道具 举报

ID:83649 发表于 2015-6-22 22:11 | 显示全部楼层
赞一个
回复

使用道具 举报

ID:83478 发表于 2015-6-24 00:19 | 显示全部楼层
谦虚请教 发表于 2015-6-22 12:01
你有更详细的资料吗》?

什么意思啊?程序不都在上面立吗,注释得很详细~
回复

使用道具 举报

ID:83784 发表于 2015-6-24 14:32 | 显示全部楼层
仿真图有吗
回复

使用道具 举报

ID:83784 发表于 2015-6-24 14:32 | 显示全部楼层
需要一个 期末作品觉得你这个挺好的
回复

使用道具 举报

ID:94340 发表于 2015-11-1 20:02 | 显示全部楼层
为什么没有原理图呢
回复

使用道具 举报

ID:191450 发表于 2017-5-1 16:29 | 显示全部楼层

 楼主能分享一下原理图吗?
回复

使用道具 举报

ID:218694 发表于 2017-7-12 11:05 | 显示全部楼层
请问有原理图吗?
回复

使用道具 举报

ID:775574 发表于 2020-6-11 14:10 | 显示全部楼层
有没有仿真图?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表