原创 多功能数字钟C源程序

2008-12-29 14:23 2741 6 6 分类: MCU/ 嵌入式

#include<reg52.h>
#include <intrins.h>


#define uint unsigned int
#define uchar unsigned char


sbit fm="P3"^3;      //蜂鸣器
sbit s1=P3^4;        //s1按键,设置调时
sbit s2=P3^5;    //s2按键,加1
sbit s3=P3^6;        //s3按键,减1
sbit s4=P3^7;        //s4按键,切换显示


sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
//sbit led4=P1^3;
//sbit led5=P1^4;
//sbit led6=P1^5;
//sbit led7=P1^6;
//sbit led8=P1^7;


uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_1=0,set_4=0;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
unsigned char data dis_digit;
unsigned char code dis_code[12]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
    0x99,0x92,0x82,0xf8,0x80,0x90, 0xff,0xbf};// 4, 5, 6, 7, 8, 9, off, -, --共阳
unsigned char data dis_buf[8];
unsigned char data dis_index;


uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31};   //闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31};   //非闰年


void delay(uint);    //延时函数
void timer0();       //走时中断函数
void jishi();        //计时函数
void key_change();   //切换显示按键函数
void key_set();      //设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示的数据
void zd_clock();     //整点报时函数
void nz_clock();     //闹钟函数
uchar incone(uchar); //加1函数
uchar decone(uchar); //减1函数
void set_time();     //设置时间函数
void set_clock();    //设置闹钟函数
void set_mdw();      //设置月日星期函数



void main()          //主函数
{
IE   = 0x8a;   // 使能timer0,1 中断
TR0  = 1;
TR1  = 1;
TMOD = 0x11;     // 定时器0, 1工作模式1, 16位定时方式


dis_digit = 0xfe;
dis_index = 0;
hour=12;minu=0;sec=0; //赋初值:12点0分0秒
n_hour=8;n_minu=30;n_sec=00; //闹钟赋初值8点30分0秒
year=2008;mon=12;day=25;week=4;//年月日星期赋初值2008年12月25日星期四;
   while(1)
     {
      hs="hour/10";      //时分秒HH.MM.SS
      hg="hour"%10;
      mis="minu/10";
      mig="minu"%10;
      ss="sec/10";
      sg="sec"%10;
     
      ms="mon/10";      //月日-星期MM.DD.-W
      mg="mon"%10;
      ds="day/10";
      dg="day"%10;
      w="week";


      nhs="n"_hour/10;  //闹钟定时HH.MM.SS
      nhg="n"_hour%10;
      nms="n"_minu/10;
      nmg="n"_minu%10;
      nss="n"_sec/10;
      nsg="n"_sec%10;


      key_change();    //s4按键扫描
      key_set();       //s1按键扫描
      set_time();      //设置时间
      set_mdw();       //设置月日星期
      set_clock();     //设置闹钟


     
    
     if(set_4==0)    //正常走时显示
       {
        disp(hs,hg,mis,mig,ss,sg);
       }
     if(set_4==1)    //设置时间,LED1闪亮
       {
        disp(hs,hg,mis,mig,ss,sg);
           if(sec%2==0)
            {led2=1;led3=1;led1=~led1;}
         // else
         // {led1=1;}  
       }
      if(set_4==2)   //正常显示月日-星期
       {
        disp(ms,mg,ds,dg,11,w);
       }
     if(set_4==3)    //设置月日-星期,LED2闪亮
       {
        disp(ms,mg,ds,dg,11,w);
        if(sec%2==0)
            {led1=1;led3=1;led2=~led2;}  
       
       // else
          // {led2=1;}
       }
    
      if(set_4==4)   //正常显示定时
       {
        disp(nhs,nhg,nms,nmg,nss,nsg);
       }
      if(set_4==5)   //设置闹钟定时,LED3闪亮
       {
        disp(nhs,nhg,nms,nmg,nss,nsg);
        if(sec%2==0)
            {led1=1;led2=1;led3=~led3;}   
       
       // else
        //    {led3=1;}
       }
     
      zd_clock();    //整点报时
      nz_clock();    //闹钟
    }



}


void timer0() interrupt 1    //10ms中断函数


{
TMOD=0x01;
TH0=0xdc;       //10ms初值 晶振12M
TL0=0x00;
count++;
if(count==100)
    {
      count="0";
      sec++;
      jishi();      //调计时函数
    }
}


void jishi()      //计时函数
   {
     if(sec==60)
      {
       sec="0";
       minu++;
         if(minu==60)
           {
             minu="0";
             hour++;
               if(hour==24)
                  { hour="0";
                    day++;
                    week++;
                     if(week==8)
                       {week=1;}
                 if(year%4==0&&year%100!=0||year%400==0)     //闰年
                        {
                           if(day==table1[mon]+1)
                         {
                                day="0";
                                mon++;
                                   if(mon==13)
                                      {mon=0;year++;}
                             }
                         }
                     else                                //非闰年
                        {
                           if(day==table2[mon]+1)
                         {
                           day="0";
                           mon++;
                                  if(mon==13)
                                     {mon=0;year++;}
                         }
                        }


                  }
           }
      }
   }


void key_change()   //s4按键扫描
   {
    if(s4==0)
      {
        delay(200);
          if(s4==0)
            {
             set_4++;
             while(!s4);
                if(set_4==6)
                 {set_4=0;}
            }
      }
   }



void key_set()   //s1按键扫描
{
    if(s1==0)
      {
        delay(10);
          if(s1==0)
            {
             set_1++;
             while(!s1);
                if(set_1==3)
                 {set_1=0;}
            }
      }
}


void timer1() interrupt 3
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//    选通P2.0口数码管
// dis_buf   --- 显于缓冲区基地址 
{
 TH1 = 0xFC;
 TL1 = 0x17; 
 P2 = 0xff;       // 先关闭所有数码管
 P0 = dis_buf[dis_index];   // 显示代码传送到P0口
 P2 = dis_digit;      //
 dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管
 dis_index++;      //
 dis_index &= 0x07;   // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示的数据
{
    dis_buf[0] = dis_code[a1];  // 时/月十位
 dis_buf[1] = dis_code[a2];  // 时/月个位
 dis_buf[3] = dis_code[a3];  // 分/日十位
 dis_buf[4] = dis_code[a4];  // 分/日个位
 dis_buf[6] = dis_code[a5];  // 秒/星期十位
 dis_buf[7] = dis_code[a6];  // 秒/星期个位
 dis_buf[2] = 0xbf;      // 显示"-"
 dis_buf[5] = 0xbf;      // 显示"-"    
 
}


void zd_clock()     //整点报时函数
{
if(minu==59&&(sec==51||sec==53||sec==55||sec==57))
     {
      fm="0";
      delay(1);
      fm="1";
      delay(1);
     }
if(minu==59&&sec==59)
    {
     fm="0";
     delay(1);
     fm="1";
     delay(1);
    }
}


void nz_clock()     //闹钟函数
{
   if(hour==n_hour&&minu==n_minu&&sec==n_sec)
      if((sec%2==0)&&sec<30)
         {
           fm="0";
           delay(20);
           fm="1";
           delay(20);
         }
}


void set_time()     //设置时间函数
{
   if(set_4==1)
      {
       if(set_1==0)
        {
            hour="incone"(hour);
            if(hour==24)
              {hour=0;}
          // if(hour<0)
            // {hour=23;}
            hour="decone"(hour);
            
   
          }
       if(set_1==1)
        {
            minu="incone"(minu);
              if(minu==60)
               {minu=0;}
            // if(minu<0)
            //    {minu=59;}
            minu="decone"(minu);
            
          }
          }
}


void set_mdw()      //设置月日星期函数
{
   if(set_4==3)
      {
       if(set_1==0)
        {
           mon="incone"(mon);
            if(mon==13)
             {mon=1;}
           mon="decone"(mon);
           // if(mon==0)
           //   {mon=12;}
          }
       if(set_1==1)
        {
            day="incone"(day);
             if(day==32)
              {day=0;}
            day="decone"(day);
             // if(day==0)
              // {day=0;}
          }
       if(set_1==2)
        {
            week="incone"(week);
             if(week==8)
               {week=0;}
            week="decone"(week);
          // if(week==0)
          //    {week=7;}
          }
      }
}


void set_clock()      //设置闹钟函数
{
    if(set_4==5)
      {
       if(set_1==0)
        {
            n_hour=incone(n_hour);
              if(n_hour==24)
               {n_hour=0;}
            n_hour=decone(n_hour);
          //    if(n_hour==0)
           //     {n_hour=0;}
          }
       if(set_1==1)
        {
            n_minu=incone(n_minu);
              if(n_minu==60)
               {n_minu=0;}
            n_minu=decone(n_minu);
            // if(n_minu==0)
              // {n_minu=0;}
           }
      }


}


uchar incone(uchar n)    //加1函数
{
   if(s2==0)
    { delay(200);
      if(s2==0)
        {
         n++;   
         while(!s2);
        }
    }
return(n);
}


uchar decone(uchar m)   //减1函数
{
   if(s3==0)
    {
      delay(200);
      if(s3==0)
        {
          m--;
          while(!s3);
          if(m<0)
           {m=0;}
        }


    }


    return(m);
}



void delay(uint k)   //延时函数
{
uint i,j;
for(i=k;i>0;i--)
    for(j=80;j>0;j--);
}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条