视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)
2025-10-05 17:08:02 责编:小OO
文档
时钟电路图:

PCB板:

单片机程序:

/*====================================================================

  调试要求:

  1.MCU:ATS52芯片或ATC52

  2.晶振:12MHz

  功能:多功能时钟+温度计

 ====================================================================*/

#include 

#include 

#define uchar unsigned char

#define uint  unsigned int

sbit    dis_bit1=P2^7;//定义数码管控制口

sbit    dis_bit2=P2^6;//定义数码管控制口

sbit    dis_bit3=P2^4;//定义数码管控制口

sbit    dis_bit4=P2^3;//定义数码管控制口

sbit    dis_bit5=P2^1;//定义数码管控制口

sbit    dis_bit6=P2^0;//定义数码管控制口

sbit    led1_bit=P2^2;//定时LED的控制口

sbit    led2_bit=P2^5;//定时LED的控制口

sbit    s1_bit=P1^0;  //定义S1控制口

sbit    s2_bit=P1^1;  //定义S2控制口

sbit    s3_bit=P1^2;  //定义S3控制口

sbit    dq_ds18b20=P3^3;//定义控制DS18B20

sbit    speak=P3^7;   //定义蜂鸣器控制口

sbit    clk_ds1302=P3^6;//定义控制DS1302的时钟线

sbit    io_ds1302=P3^5;//定义控制DS1302的串行数据

sbit    rest_ds1302=P3^4;

#define smg_data    P0//定义数码管数据口

void  delay_3us();//3US的延时程序

void  delay_8us(uint t);//8US延时基准程序

void  delay_50us(uint t);//延时50*T微妙函数的声明

void  display1(uchar dis_data);//数码管1显示子程序

void  display2(uchar dis_data);//数码管2显示子程序

void  display3(uchar dis_data);//数码管3显示子程序

void  display4(uchar dis_data);//数码管4显示子程序

void  display5(uchar dis_data);//数码管5显示子程序

void  display6(uchar dis_data);//数码管6显示子程序

void  init_t0();//定时器0初始化函数

void  dis_led();//LED处理函数

void  judge_s1();//S1按键处理函数

void  judge_s2();//S2按键处理函数

void  judge_s3();//S3按键处理函数

void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序

void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序

void  judge_dis();//显示处理函数

void  judge_clock();//显示处理函数

void  set_ds1302();//设置时间

void  get_ds1302();//读取当前时间

void  w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据

uchar r_1byte_ds1302();//从DS1302读一个字节的数据

//***********************************************************************

//DS18B20测温函数定义

void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节 

uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据

void rest_ds18b20(void);//DS18B20复位程序

void readtemp_ds18b20(void);//读取温度 

void dis_temp();//温度显示函数

//共阳数码管断码表

const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,

                       // 0  1    2    3    4    5

                       0x82,0xf8,0x80,0x90,0x86,0x87,0xFF,

                       //6   7     8    9     E    T   B

                       0xc6,0xbf,0xff};

                        //    C      -

const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; 

uchar t0_crycle;

uchar hour_count,minute_count,second_count,msecond_count;

uchar clock_hour,clock_minute;

uchar countdown_second;

uchar countdown_hour,countdown_minute;

uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭

uchar flag1,second_flag,zancun1,zancun2,zancun3;

uchar zancun4,zancun5,zancun6,zancun7;

uchar clock_flag,countdown_flag;

uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数

uint  speak_count;

uchar templ,temph,temp_flag;

uchar  t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位

uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间

//主程序

void main()

{

    P3=0x00;

    flag1=0;    

    zancun3=0;

    msecond_minute=0;//置秒表相关参数为0

    msecond_second=0;

    msecond_msecond=0;

    speak=1;//关闭蜂鸣器

    speak_count=0;

    clock_hour=0;

    clock_minute=0;

    clock_flag=0;

    countdown_flag=0;//倒计时标志位为0

    clock_en=0;//开机时默认关闭闹钟

    init_t0();

    TR0=1;//

   // set_ds1302();//设置DS1302的初始时间

   //接下来开始编写让数码管显示的程序

    while(1)

    {

      get_ds1302();

      judge_dis();//显示处理

      judge_s1();

      judge_s2();

      judge_s3();

      judge_clock();//闹钟处理程序

    }

}

void timer0() interrupt 1

{

    TH0=(65536-50000)/256;

    TL0=(65536-50000)%256;

    t0_crycle++;

    if(t0_crycle==2)// 0.1秒

    {

      t0_crycle=0;

      msecond_flag=1;

      msecond_count++;

      if(msecond_count==10)//1秒

      { 

        msecond_count=0;

        second_flag=1;

      }    

    }

}

//**************************************************

//显示处理函数

void  judge_dis()

{     

    if(flag1==0)

    {

     if(second_flag==1)

      {

        zancun7++;

        second_flag=0;

      }

      if(zancun7<1)

      {

        if(temp_flag2==1)

        {

          readtemp_ds18b20();//读取温度  

          temp_flag2=0;

        }

        dis_temp();//温度显示函数

      }

     if(zancun7>=1)

      {

         

         temp_flag2=1;

         zancun4=hour_count&0xf0;

         zancun4>>=4;

         zancun5=minute_count&0xf0;

         zancun5>>=4;

         zancun6=second_count&0xf0;

         zancun6>>=4;

         dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_count&0x0f);

         dis_led();

         if(zancun7==5)zancun7=0;

      }

    }

    if(flag1!=0)

    {

       switch(flag1)

       {

           case 1:

                dis(5,10,11,1,12,12);//显示SET1

                led1_bit=1;

                led2_bit=1;

                break;

           case 2:

                dis(5,10,11,2,12,12);//显示SET2

                break;

           case 3:

                dis(5,10,11,3,12,12);//显示SET3

                break;

           case 4:

                dis(5,10,11,4,12,12);//显示SET4

                break;

           case 5:

                dis(5,10,11,5,12,12);//显示SET5

                break;

           case 6:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,1);

                break;

           case 7:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2);

                break;

           case 8:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3);

                break;

           case 9://进入修改时间,时间分位个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4);

                break;

           case 10://进入修改闹钟,闹钟小时十位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,1);

                break;

           case 11://进入修改闹钟,闹钟小时个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,2);

                break;

           case 12://进入修改闹钟,闹钟小时十位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,3);

                break;

           case 13://进入修改闹钟,闹钟小时个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);

                break;

           case 14://进入修改闹钟的开关

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,6);

                break;

           case 15:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,1);

                break;

           case 16:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,2);

                break;

           case 17:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,3);

                break;

           case 18:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,4);

                break;

           case 19:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,5);

                break;

           case 20:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,6);

                break;

           case 21:

                if(second_flag==1)

                {

                    second_flag=0;

                    countdown_second--;

                    if(countdown_second==255)

                    {

                        countdown_second=59;

                        countdown_minute--;

                        if(countdown_minute==255)

                        {

                            countdown_minute=59;

                            countdown_hour--;

                            if(countdown_hour==255)

                            {

                               flag1=22;

                               countdown_minute=0;

                               countdown_hour=0;

                               countdown_second=0;

                               countdown_flag=1;

                            }

                        }

                    }

                    

                }

                dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown_minute%10,countdown_second/10,countdown_second%10);//

                break;

           case 22:

                if(countdown_flag>0 && countdown_flag<7)

                {

                   speak=0;

                   if(second_flag==1)

                   {

                       second_flag=0;

                       countdown_flag++;

                   }

                }

                else 

                {

                   speak=1;

                }

                 dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown_minute%10,countdown_second/10,countdown_second%10);//

                break;

            case 23:

                dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_second%10,msecond_msecond%10,12);

                break;

            case 24:

                if(msecond_flag==1)

                {

                     msecond_flag=0;

                     msecond_msecond++;

                     if(msecond_msecond==10)

                     {

                         msecond_msecond=0; 

                         msecond_second++;

                         if(msecond_second==60)

                         {

                           msecond_second=0;

                           msecond_minute++;

                           if(msecond_minute==100)

                           {

                             msecond_minute=99;

                             flag1=23;

                           }

                         }

                     }

                }

                dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_second%10,msecond_msecond%10,12);

                break;

            case 25:

                dis(zancun3/10,zancun3%10,zancun2/10,zancun2%10,zancun1/10,zancun1%10);

                break;

            default:

                break;

        }

    }

}

//**************************************************

//S1按键处理函数

void  judge_s1()

{

    s1_bit=1;//置IO为1,准备读入收据

    if(s1_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s1_bit==0)

        {

           switch(flag1)

           {

               case 0:

               case 1:

               case 2:

               case 3:

               case 4:

               case 6:

               case 7:

               case 8:

               case 10:

               case 11:

               case 12:

               case 13:

               case 15:

               case 16:

               case 17:

               case 18:

               case 19:

                    flag1++;

                    break;

               case 9:

                    flag1=6;

                    break;

               case 14:

                    flag1=10;

                    break;

               case 20:

                    flag1=15;

                    break;

               case 5:

               case 21:

               case 22:

               case 23://系统从秒表状态复位

               case 24://系统从秒表状态复位

               case 25://系统从计数器复位

                    flag1=0;

                    break;

                default:

                    break;

           }           

           while(s1_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//**************************************************

//S2按键处理函数

void  judge_s2()

{

    s2_bit=1;//置IO为1,准备读入收据

    if(s2_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s2_bit==0)

        {

           switch (flag1)

           {

              case 1: //在显示SET1状态下按S2件,进入修改时间

                 flag1=6;

                 zancun4=hour_count&0xf0;

                 zancun4>>=4;

                 zancun6=hour_count&0x0f;

                 zancun1=zancun4*10+zancun6;

                 //zancun1=hour_count;

                 zancun5=minute_count&0xf0;

                 zancun5>>=4;

                 zancun6=minute_count&0x0f;

                 zancun2=zancun5*10+zancun6;

                 //  zancun2=minute_count;

                 break;

              case 2://在显示SET2状态下按S2,进入设置闹钟

                 zancun1=clock_hour;

                 zancun2=clock_minute;

                 flag1=10;

                 break; 

              case 6://修改时钟小时十位状态下按S2件

              case 7://修改时钟小时个位状态下按S2件

              case 8://修改时钟分钟十位状态下按S2件

              case 9://修改时钟分钟个位状态下按S2件

                 //zancun4=zancun1/10;

                 tab23[2]=zancun1/10*16+zancun1%10;

                  

                 //zancun5=zancun2&0xf0;

                 //zancun5>>=4;

                 tab23[1]=zancun2/10*16+zancun2%10;

                 hour_count=tab23[2];

                 minute_count=tab23[1];

                 second_count=0;

                 tab23[0]=0;

                 set_ds1302();//设置DS1302的初始时间

                 flag1=0;

                 break;

              case 10://修改闹钟小时十位状态下按S2

              case 11://修改闹钟小时个位状态下按S2

              case 12://修改闹钟分钟十位状态下按S2

              case 13://修改闹钟分钟个位状态下按S2

              case 14://修改闹钟使能状态下按S2

                 clock_hour=zancun1;

                 clock_minute=zancun2;

                 clock_en=zancun3;

                 flag1=0;

                 break;

              case 3:

                 flag1=15;

                 zancun1=countdown_hour;

                 zancun2=countdown_minute;

                 zancun3=countdown_second;

                 break;

              case 15:

              case 16:

              case 17:

              case 18:

              case 19:

              case 20:

                 countdown_hour=zancun1;

                 countdown_minute=zancun2;

                 countdown_second=zancun3;

                 flag1=21;

                 countdown_flag=0;

                 break;

              case 22:

                 flag1=21;

                 break;

              case 21:

                 flag1=22;

                 break;

              case 4:

                 flag1=23;//秒表暂停

                 msecond_minute=0;

                 msecond_second=0;

                 msecond_msecond=0;

                 break;

              case 23:

                 flag1=24;

                 break;

              case 24:

                 flag1=23;

                 break;

              case 5:

                 flag1=25;//进入计数器模式

                 zancun1=0;

                 zancun2=0;

                 zancun3=0;

                 break;

              default:

                 break;

                 

           }   

           while(s2_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//**************************************************

//S3按键处理函数

void  judge_s3()

{

    s3_bit=1;//置IO为1,准备读入收据

    if(s3_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s3_bit==0)

        {

           switch (flag1)

           {

             

              case 6://修改时间小时的十位数

                 zancun1+=10;

                 if(zancun1>=24)zancun1=zancun1%10;

                 break;

              case 7://修改时间小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 if(zancun1>=24)zancun1=20;

                 break;

              case 8://修改时间分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 9://修改时间分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 10://修改闹钟小时的十位数

                 zancun1+=10;

                 if(zancun1>=24)zancun1=zancun1%10;

                 break;

              case 11://修改闹钟小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 if(zancun1>=24)zancun1=20;

                 break;

              case 12://修改闹钟分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 13://修改闹钟分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 14:

                 zancun3^=1;

                 break;

              case 15://修改倒计时小时的十位数

                 zancun1+=10;

                 if(zancun1>=100)zancun1-=100;

                 break;

              case 16: //修改倒计时小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 break;

              case 17://修改倒计时分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 18: //修改倒计时分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 19://修改倒计时秒的十位数

                 zancun3+=10;

                 if(zancun3>=60)zancun3-=60;

                 break;

              case 20: //修改倒计时秒的个位数

                 zancun3=zancun3/10*10+(zancun3%10+1)%10;

                 break;

              case 21:

              case 22://

                 countdown_hour=zancun1;

                 countdown_minute=zancun2;

                 countdown_second=zancun3;

                 flag1=21;

                 break;

              case 23:

              case 24://秒表复位

                 flag1=24;

                 msecond_minute=0;

                 msecond_second=0; 

                 msecond_msecond=0;

                 break;

              case 25:

                 zancun1++;

                 if(zancun1==100)

                 {

                     zancun1=0;

                     zancun2++;

                     if(zancun2==100)

                     {

                       zancun2=0;

                       zancun3++;

                     }

                 }

                 break;

              default:

                 break;

           }   

           while(s3_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//****************************************

//显示处理函数

void  judge_clock()

{

    zancun4=hour_count&0xf0;

    zancun4>>=4;

    zancun6=hour_count&0x0f;

    zancun4*=10;

    zancun4+=zancun6;

    zancun5=minute_count&0xf0;

    zancun5>>=4;

    zancun6=minute_count&0x0f;

    zancun5*=10;

    zancun5+=zancun6;

    if(clock_hour==zancun4 && clock_minute==zancun5)

    {

         if(clock_en==1 && clock_flag==0)

         {          

              speak_count=0;//开启蜂鸣器

              clock_flag=1;

              speak_count=0;

         }

    }

    else

    {

     clock_flag=0;

    }

    if(clock_flag==1 && speak_count<400)

    {

       

        if(msecond_count<=5)

        {

           speak=0;

           speak_count++;

        }

        else

        {

          speak=1;

    

        }

    }

    else

    {

        speak=1;

    }

}

//****************************************

////闪烁显示子程序

void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san)

{    

     if(san==1)

     {

        if(msecond_count<5)

        {

           display1(s6);

        } 

     }

     else

     {

         display1(s6);

     }

     if(san==2)

     {

        if(msecond_count<5)

        {

           display2(s5);

        } 

     }

     else

     {

         display2(s5);

     }

     if(san==3)

     {

        if(msecond_count<5)

        {

           display3(s4);

        } 

     }

     else

     {

         display3(s4);

     }

     if(san==4)

     {

        if(msecond_count<5)

        {

           display4(s3);

        } 

     }

     else

     {

         display4(s3);

     }

     if(san==5)

     {

        if(msecond_count<5)

        {

           display5(s2);

        } 

     }

     else

     {

         display5(s2);

     }

     if(san==6)

     {

        if(msecond_count<5)

        {

           display6(s1);

        } 

     }

     else

     {

         display6(s1);

     }

}

//****************************************

//时钟显示程序

void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1)

{

     display1(s6);

     display2(s5);

     display3(s4); 

     display4(s3);

     display5(s2);

     display6(s1); 

}

//********************************************************************************************

void init_t0()

{

       TMOD=0x01;//设定定时器工作方式1,定时器定时50毫秒

    TH0=(65536-50000)/256;

    TL0=(65536-50000)%256;

    EA=1;//开总中断

    ET0=1;//允许定时器0中断

    t0_crycle=0;//定时器中断次数计数单元

}

//**************************************************

//LED处理函数

void  dis_led()

     if(msecond_count<5)

     {

         led1_bit=1;

         led2_bit=1;

     }

     else

     {

         led1_bit=0;

         led2_bit=0;

     }

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display6(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit6=0;//锁存数据

   delay_50us(40);

   dis_bit6=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display5(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit5=0;//锁存数据

   delay_50us(40);

   dis_bit5=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display4(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit4=0;//锁存数据

   delay_50us(40);

   dis_bit4=1;

}//***************************************************************

//功能:把数据1显示在数码管1上

void display3(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit3=0;//锁存数据

   delay_50us(40);

   dis_bit3=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display1(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit1=0;//锁存数据

   delay_50us(40);

   dis_bit1=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display2(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit2=0;//锁存数据

   delay_50us(40);

   dis_bit2=1;

}

//**************************************************************************************************

//函数名称:void delay_50US(unsigned int t)

//功能: 延时50*t(us)

void delay_50us(uint t)

{

  unsigned char j; 

  for(;t>0;t--) 

  {

    for(j=19;j>0;j--);

  }

//*******************************************************************************

//8微秒延时基准程序

void delay_8us(uint t)

{

 while(--t);

}

//*******************************************************************************

//3微秒延时程序

void delay_3us()

  ;

  ; 

}

//*******************************************************************************

//子程序功能:向DS18B20写一字节的数据

void w_1byte_ds18b20(uchar value) 

   uchar i=0; 

   for(i=0;i<8;i++)

   {

    dq_ds18b20=1;

    delay_3us();

    dq_ds18b20=0;

    delay_8us(2);

    if (value & 0x01) dq_ds18b20=1; //DQ = 1

    delay_50us(1); //延时50us 以上

    delay_8us(2);

    value>>=1;

   }

    dq_ds18b20=1; //DQ = 1

}

//读一个字节 

uchar r_1byte_ds18b20(void) 

{

  uchar i=0; 

  uchar value = 0; 

  for (i=0;i<8;i++) 

  {

   value>>=1;

   dq_ds18b20=0;// DQ_L;

   delay_3us();

   dq_ds18b20=1; //DQ_H;

   delay_8us(2);

   if(dq_ds18b20==1) value|=0x80; 

   delay_8us(6); //延时40us

  }

  dq_ds18b20=1;

  return value;

}

//;**************************************************

//ds18b20复位子程序

void rest_ds18b20(void) 

rest:delay_3us(); //稍做延时

     delay_3us();

     dq_ds18b20=1;

     delay_3us();

     dq_ds18b20=0;// DQ_L; 

     delay_50us(11);//480us     dq_ds18b20=1;//拉高总线

     delay_8us(5);

     if(dq_ds18b20==1)

     {  

       return;

     }  

     delay_50us(2); //延时90us

     if(dq_ds18b20==1)

     {

       return;

      }  

      else

      {

       goto rest;

      } 

}

//****************************************************

//读取温度 

void readtemp_ds18b20(void) 

    uchar temp32;

    rest_ds18b20();

    w_1byte_ds18b20(0xcc); //跳过读序列号的操作 

    w_1byte_ds18b20(0x44); //启动温度转换

    delay_8us(2);

    rest_ds18b20();

    w_1byte_ds18b20(0xcc); //跳过读序列号的操作 

    w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 

    templ=r_1byte_ds18b20();

    temph=r_1byte_ds18b20();

    if((temph&0xf0))//判断温度的正负性

    {

      temp_flag=0;//温度为负数标志

      temph=-temph;

      templ=-templ;

      t_x=tabl3[templ & 0x0f];//计算温度的小数

      temp32=temph & 0x0f;

      temp32<<=4;

      templ>>=4;

      temp32=temp32 | templ;

      t_b=temp32/100%10;//计算温度的百位数据

      t_s=temp32/10%10;//计算温度的十位数据

      t_g=temp32%10;//计算温度的个位数据

    }

    else//为正数

    {

      t_x=tabl3[templ & 0x0f];//计算温度的小数

      temp32=temph & 0x0f;

      temp32<<=4;

      templ>>=4;

      temp32=temp32 | templ;

      t_b=temp32/100%10;//计算温度的百位数据

      t_s=temp32/10%10;//计算温度的十位数据

      t_g=temp32%10;//计算温度的个位数据

      temp_flag=1;

     }

}

void dis_temp()//温度显示函数

{

     if(temp_flag=1)

     {

        if(t_b==0)

       {

         dis(12,12,t_s,t_g,13,12);

       }

       else

       {

         dis(12,t_b,t_s,t_g,13,12);

       }

     }

     else

     {

        dis(14,t_b,t_s,t_g,13,12);

     }

}

//;##############################################################################

//;子程序名:w_1byte_ds1302

//;功能:    向DS1302写一个字节的数据

void w_1byte_ds1302(uchar t)

{

  uchar i;

  for(i=0;i<8;i++)

  {

    if(t & 0x01)

     {io_ds1302=1;}

    else

     {io_ds1302=0;}

    clk_ds1302=1;

    delay_3us();

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    delay_3us();

    t>>=1;

  }  

}

//;########################################################################

//;子程序名:r_1byte_ds1302()

//;功能:    从DS1302读一个字节的数据

uchar r_1byte_ds1302()

  uchar i,temp11=0;

  io_ds1302=1;//置IO为1,准备读入数据

  for(i=0;i<8;i++)

  {

    temp11>>=1;

    if(io_ds1302) temp11 |= 0x80;

    clk_ds1302=1;

    delay_3us();

    delay_3us();

    clk_ds1302=0;

    delay_3us();

  } 

  return(temp11);

}  

//;#################################################################################

//;子程序名:setbds1302

//;功能:   设置DS1302初始时间,并启动计时

void set_ds1302()

  uchar i,j;

  rest_ds1302=0;

  delay_3us();

  clk_ds1302=0;

  delay_3us();

  rest_ds1302=1;

  delay_3us();

  w_1byte_ds1302(0x8e);//写控制命令字

  delay_3us();

  w_1byte_ds1302(0x00);//写保护关闭

  clk_ds1302=1;

  delay_3us();

  rest_ds1302=0;

  for(i=0,j=0x80;i<7;i++,j+=2)

  {

    rest_ds1302=0;

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    rest_ds1302=1;

    delay_3us();

    w_1byte_ds1302(j);

    delay_3us();

    w_1byte_ds1302(tab23[i]);

    delay_3us();

    delay_3us();

    clk_ds1302=1;

    delay_3us();

    rest_ds1302=0;

    delay_3us();

    delay_3us();

  }

  rest_ds1302=0;

  delay_3us();

  clk_ds1302=0;

  delay_3us();

  rest_ds1302=1;

  delay_3us();

  w_1byte_ds1302(0x8e);

  delay_3us();

  w_1byte_ds1302(0x80);

  clk_ds1302=1;

  delay_3us();

  rest_ds1302=0;

  delay_3us();

}  

//;#################################################################-------

//;子程序名:get1302

void get_ds1302()

   uchar temp11[7],i,j;

   for(i=0;i<7;i++)

   {temp11[i]=0;}

   for(i=0,j=0x81;i<7;i++,j+=2)

   {  

    rest_ds1302=0;

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    rest_ds1302=1;

    delay_3us();

    w_1byte_ds1302(j);

    temp11[i]=r_1byte_ds1302();

    delay_3us();

    clk_ds1302=1;

    delay_3us();

    rest_ds1302=0;

    delay_3us();

  }

  if(temp11[0]!=0xff)

  {second_count=temp11[0];}

  if(temp11[1]!=0xff)// 数据验证

  {minute_count=temp11[1];}

  if(temp11[2]!=0xff)//数据验证

  {hour_count=temp11[2];}

 // date=temp[3];

  //month=temp[4];

 // week=temp[5];

  //year=temp[6];

} /*====================================================================

  调试要求:

  1.MCU:ATS52芯片或ATC52

  2.晶振:12MHz

  功能:多功能时钟+温度计

 ====================================================================*/

#include 

#include 

#define uchar unsigned char

#define uint  unsigned int

sbit    dis_bit1=P2^7;//定义数码管控制口

sbit    dis_bit2=P2^6;//定义数码管控制口

sbit    dis_bit3=P2^4;//定义数码管控制口

sbit    dis_bit4=P2^3;//定义数码管控制口

sbit    dis_bit5=P2^1;//定义数码管控制口

sbit    dis_bit6=P2^0;//定义数码管控制口

sbit    led1_bit=P2^2;//定时LED的控制口

sbit    led2_bit=P2^5;//定时LED的控制口

sbit    s1_bit=P1^0;  //定义S1控制口

sbit    s2_bit=P1^1;  //定义S2控制口

sbit    s3_bit=P1^2;  //定义S3控制口

sbit    dq_ds18b20=P3^3;//定义控制DS18B20

sbit    speak=P3^7;   //定义蜂鸣器控制口

sbit    clk_ds1302=P3^6;//定义控制DS1302的时钟线

sbit    io_ds1302=P3^5;//定义控制DS1302的串行数据

sbit    rest_ds1302=P3^4;

#define smg_data    P0//定义数码管数据口

void  delay_3us();//3US的延时程序

void  delay_8us(uint t);//8US延时基准程序

void  delay_50us(uint t);//延时50*T微妙函数的声明

void  display1(uchar dis_data);//数码管1显示子程序

void  display2(uchar dis_data);//数码管2显示子程序

void  display3(uchar dis_data);//数码管3显示子程序

void  display4(uchar dis_data);//数码管4显示子程序

void  display5(uchar dis_data);//数码管5显示子程序

void  display6(uchar dis_data);//数码管6显示子程序

void  init_t0();//定时器0初始化函数

void  dis_led();//LED处理函数

void  judge_s1();//S1按键处理函数

void  judge_s2();//S2按键处理函数

void  judge_s3();//S3按键处理函数

void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序

void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序

void  judge_dis();//显示处理函数

void  judge_clock();//显示处理函数

void  set_ds1302();//设置时间

void  get_ds1302();//读取当前时间

void  w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据

uchar r_1byte_ds1302();//从DS1302读一个字节的数据

//***********************************************************************

//DS18B20测温函数定义

void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节 

uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据

void rest_ds18b20(void);//DS18B20复位程序

void readtemp_ds18b20(void);//读取温度 

void dis_temp();//温度显示函数

//共阳数码管断码表

const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,

                       // 0  1    2    3    4    5

                       0x82,0xf8,0x80,0x90,0x86,0x87,0xFF,

                       //6   7     8    9     E    T   B

                       0xc6,0xbf,0xff};

                        //    C      -

const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; 

uchar t0_crycle;

uchar hour_count,minute_count,second_count,msecond_count;

uchar clock_hour,clock_minute;

uchar countdown_second;

uchar countdown_hour,countdown_minute;

uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭

uchar flag1,second_flag,zancun1,zancun2,zancun3;

uchar zancun4,zancun5,zancun6,zancun7;

uchar clock_flag,countdown_flag;

uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数

uint  speak_count;

uchar templ,temph,temp_flag;

uchar  t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位

uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间

//主程序

void main()

{

    P3=0x00;

    flag1=0;    

    zancun3=0;

    msecond_minute=0;//置秒表相关参数为0

    msecond_second=0;

    msecond_msecond=0;

    speak=1;//关闭蜂鸣器

    speak_count=0;

    clock_hour=0;

    clock_minute=0;

    clock_flag=0;

    countdown_flag=0;//倒计时标志位为0

    clock_en=0;//开机时默认关闭闹钟

    init_t0();

    TR0=1;//

   // set_ds1302();//设置DS1302的初始时间

   //接下来开始编写让数码管显示的程序

    while(1)

    {

      get_ds1302();

      judge_dis();//显示处理

      judge_s1();

      judge_s2();

      judge_s3();

      judge_clock();//闹钟处理程序

    }

}

void timer0() interrupt 1

{

    TH0=(65536-50000)/256;

    TL0=(65536-50000)%256;

    t0_crycle++;

    if(t0_crycle==2)// 0.1秒

    {

      t0_crycle=0;

      msecond_flag=1;

      msecond_count++;

      if(msecond_count==10)//1秒

      { 

        msecond_count=0;

        second_flag=1;

      }    

    }

}

//**************************************************

//显示处理函数

void  judge_dis()

{     

    if(flag1==0)

    {

     if(second_flag==1)

      {

        zancun7++;

        second_flag=0;

      }

      if(zancun7<1)

      {

        if(temp_flag2==1)

        {

          readtemp_ds18b20();//读取温度  

          temp_flag2=0;

        }

        dis_temp();//温度显示函数

      }

     if(zancun7>=1)

      {

         

         temp_flag2=1;

         zancun4=hour_count&0xf0;

         zancun4>>=4;

         zancun5=minute_count&0xf0;

         zancun5>>=4;

         zancun6=second_count&0xf0;

         zancun6>>=4;

         dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_count&0x0f);

         dis_led();

         if(zancun7==5)zancun7=0;

      }

    }

    if(flag1!=0)

    {

       switch(flag1)

       {

           case 1:

                dis(5,10,11,1,12,12);//显示SET1

                led1_bit=1;

                led2_bit=1;

                break;

           case 2:

                dis(5,10,11,2,12,12);//显示SET2

                break;

           case 3:

                dis(5,10,11,3,12,12);//显示SET3

                break;

           case 4:

                dis(5,10,11,4,12,12);//显示SET4

                break;

           case 5:

                dis(5,10,11,5,12,12);//显示SET5

                break;

           case 6:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,1);

                break;

           case 7:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2);

                break;

           case 8:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3);

                break;

           case 9://进入修改时间,时间分位个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4);

                break;

           case 10://进入修改闹钟,闹钟小时十位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,1);

                break;

           case 11://进入修改闹钟,闹钟小时个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,2);

                break;

           case 12://进入修改闹钟,闹钟小时十位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,3);

                break;

           case 13://进入修改闹钟,闹钟小时个位闪烁

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);

                break;

           case 14://进入修改闹钟的开关

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,6);

                break;

           case 15:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,1);

                break;

           case 16:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,2);

                break;

           case 17:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,3);

                break;

           case 18:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,4);

                break;

           case 19:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,5);

                break;

           case 20:

                dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,6);

                break;

           case 21:

                if(second_flag==1)

                {

                    second_flag=0;

                    countdown_second--;

                    if(countdown_second==255)

                    {

                        countdown_second=59;

                        countdown_minute--;

                        if(countdown_minute==255)

                        {

                            countdown_minute=59;

                            countdown_hour--;

                            if(countdown_hour==255)

                            {

                               flag1=22;

                               countdown_minute=0;

                               countdown_hour=0;

                               countdown_second=0;

                               countdown_flag=1;

                            }

                        }

                    }

                    

                }

                dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown_minute%10,countdown_second/10,countdown_second%10);//

                break;

           case 22:

                if(countdown_flag>0 && countdown_flag<7)

                {

                   speak=0;

                   if(second_flag==1)

                   {

                       second_flag=0;

                       countdown_flag++;

                   }

                }

                else 

                {

                   speak=1;

                }

                 dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown_minute%10,countdown_second/10,countdown_second%10);//

                break;

            case 23:

                dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_second%10,msecond_msecond%10,12);

                break;

            case 24:

                if(msecond_flag==1)

                {

                     msecond_flag=0;

                     msecond_msecond++;

                     if(msecond_msecond==10)

                     {

                         msecond_msecond=0; 

                         msecond_second++;

                         if(msecond_second==60)

                         {

                           msecond_second=0;

                           msecond_minute++;

                           if(msecond_minute==100)

                           {

                             msecond_minute=99;

                             flag1=23;

                           }

                         }

                     }

                }

                dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_second%10,msecond_msecond%10,12);

                break;

            case 25:

                dis(zancun3/10,zancun3%10,zancun2/10,zancun2%10,zancun1/10,zancun1%10);

                break;

            default:

                break;

        }

    }

}

//**************************************************

//S1按键处理函数

void  judge_s1()

{

    s1_bit=1;//置IO为1,准备读入收据

    if(s1_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s1_bit==0)

        {

           switch(flag1)

           {

               case 0:

               case 1:

               case 2:

               case 3:

               case 4:

               case 6:

               case 7:

               case 8:

               case 10:

               case 11:

               case 12:

               case 13:

               case 15:

               case 16:

               case 17:

               case 18:

               case 19:

                    flag1++;

                    break;

               case 9:

                    flag1=6;

                    break;

               case 14:

                    flag1=10;

                    break;

               case 20:

                    flag1=15;

                    break;

               case 5:

               case 21:

               case 22:

               case 23://系统从秒表状态复位

               case 24://系统从秒表状态复位

               case 25://系统从计数器复位

                    flag1=0;

                    break;

                default:

                    break;

           }           

           while(s1_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//**************************************************

//S2按键处理函数

void  judge_s2()

{

    s2_bit=1;//置IO为1,准备读入收据

    if(s2_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s2_bit==0)

        {

           switch (flag1)

           {

              case 1: //在显示SET1状态下按S2件,进入修改时间

                 flag1=6;

                 zancun4=hour_count&0xf0;

                 zancun4>>=4;

                 zancun6=hour_count&0x0f;

                 zancun1=zancun4*10+zancun6;

                 //zancun1=hour_count;

                 zancun5=minute_count&0xf0;

                 zancun5>>=4;

                 zancun6=minute_count&0x0f;

                 zancun2=zancun5*10+zancun6;

                 //  zancun2=minute_count;

                 break;

              case 2://在显示SET2状态下按S2,进入设置闹钟

                 zancun1=clock_hour;

                 zancun2=clock_minute;

                 flag1=10;

                 break; 

              case 6://修改时钟小时十位状态下按S2件

              case 7://修改时钟小时个位状态下按S2件

              case 8://修改时钟分钟十位状态下按S2件

              case 9://修改时钟分钟个位状态下按S2件

                 //zancun4=zancun1/10;

                 tab23[2]=zancun1/10*16+zancun1%10;

                  

                 //zancun5=zancun2&0xf0;

                 //zancun5>>=4;

                 tab23[1]=zancun2/10*16+zancun2%10;

                 hour_count=tab23[2];

                 minute_count=tab23[1];

                 second_count=0;

                 tab23[0]=0;

                 set_ds1302();//设置DS1302的初始时间

                 flag1=0;

                 break;

              case 10://修改闹钟小时十位状态下按S2

              case 11://修改闹钟小时个位状态下按S2

              case 12://修改闹钟分钟十位状态下按S2

              case 13://修改闹钟分钟个位状态下按S2

              case 14://修改闹钟使能状态下按S2

                 clock_hour=zancun1;

                 clock_minute=zancun2;

                 clock_en=zancun3;

                 flag1=0;

                 break;

              case 3:

                 flag1=15;

                 zancun1=countdown_hour;

                 zancun2=countdown_minute;

                 zancun3=countdown_second;

                 break;

              case 15:

              case 16:

              case 17:

              case 18:

              case 19:

              case 20:

                 countdown_hour=zancun1;

                 countdown_minute=zancun2;

                 countdown_second=zancun3;

                 flag1=21;

                 countdown_flag=0;

                 break;

              case 22:

                 flag1=21;

                 break;

              case 21:

                 flag1=22;

                 break;

              case 4:

                 flag1=23;//秒表暂停

                 msecond_minute=0;

                 msecond_second=0;

                 msecond_msecond=0;

                 break;

              case 23:

                 flag1=24;

                 break;

              case 24:

                 flag1=23;

                 break;

              case 5:

                 flag1=25;//进入计数器模式

                 zancun1=0;

                 zancun2=0;

                 zancun3=0;

                 break;

              default:

                 break;

                 

           }   

           while(s2_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//**************************************************

//S3按键处理函数

void  judge_s3()

{

    s3_bit=1;//置IO为1,准备读入收据

    if(s3_bit==0)//判断是否有按键按下

    {

        delay_50us(1);// 延时,去除机械抖动

        if(s3_bit==0)

        {

           switch (flag1)

           {

             

              case 6://修改时间小时的十位数

                 zancun1+=10;

                 if(zancun1>=24)zancun1=zancun1%10;

                 break;

              case 7://修改时间小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 if(zancun1>=24)zancun1=20;

                 break;

              case 8://修改时间分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 9://修改时间分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 10://修改闹钟小时的十位数

                 zancun1+=10;

                 if(zancun1>=24)zancun1=zancun1%10;

                 break;

              case 11://修改闹钟小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 if(zancun1>=24)zancun1=20;

                 break;

              case 12://修改闹钟分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 13://修改闹钟分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 14:

                 zancun3^=1;

                 break;

              case 15://修改倒计时小时的十位数

                 zancun1+=10;

                 if(zancun1>=100)zancun1-=100;

                 break;

              case 16: //修改倒计时小时的个位数

                 zancun1=zancun1/10*10+(zancun1%10+1)%10;

                 break;

              case 17://修改倒计时分钟的十位数

                 zancun2+=10;

                 if(zancun2>=60)zancun2-=60;

                 break;

              case 18: //修改倒计时分钟的个位数

                 zancun2=zancun2/10*10+(zancun2%10+1)%10;

                 break;

              case 19://修改倒计时秒的十位数

                 zancun3+=10;

                 if(zancun3>=60)zancun3-=60;

                 break;

              case 20: //修改倒计时秒的个位数

                 zancun3=zancun3/10*10+(zancun3%10+1)%10;

                 break;

              case 21:

              case 22://

                 countdown_hour=zancun1;

                 countdown_minute=zancun2;

                 countdown_second=zancun3;

                 flag1=21;

                 break;

              case 23:

              case 24://秒表复位

                 flag1=24;

                 msecond_minute=0;

                 msecond_second=0; 

                 msecond_msecond=0;

                 break;

              case 25:

                 zancun1++;

                 if(zancun1==100)

                 {

                     zancun1=0;

                     zancun2++;

                     if(zancun2==100)

                     {

                       zancun2=0;

                       zancun3++;

                     }

                 }

                 break;

              default:

                 break;

           }   

           while(s3_bit==0)

           {

              judge_dis();

           }//等待按键释放 

        }

    }

}

//****************************************

//显示处理函数

void  judge_clock()

{

    zancun4=hour_count&0xf0;

    zancun4>>=4;

    zancun6=hour_count&0x0f;

    zancun4*=10;

    zancun4+=zancun6;

    zancun5=minute_count&0xf0;

    zancun5>>=4;

    zancun6=minute_count&0x0f;

    zancun5*=10;

    zancun5+=zancun6;

    if(clock_hour==zancun4 && clock_minute==zancun5)

    {

         if(clock_en==1 && clock_flag==0)

         {          

              speak_count=0;//开启蜂鸣器

              clock_flag=1;

              speak_count=0;

         }

    }

    else

    {

     clock_flag=0;

    }

    if(clock_flag==1 && speak_count<400)

    {

       

        if(msecond_count<=5)

        {

           speak=0;

           speak_count++;

        }

        else

        {

          speak=1;

    

        }

    }

    else

    {

        speak=1;

    }

}

//****************************************

////闪烁显示子程序

void  dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san)

{    

     if(san==1)

     {

        if(msecond_count<5)

        {

           display1(s6);

        } 

     }

     else

     {

         display1(s6);

     }

     if(san==2)

     {

        if(msecond_count<5)

        {

           display2(s5);

        } 

     }

     else

     {

         display2(s5);

     }

     if(san==3)

     {

        if(msecond_count<5)

        {

           display3(s4);

        } 

     }

     else

     {

         display3(s4);

     }

     if(san==4)

     {

        if(msecond_count<5)

        {

           display4(s3);

        } 

     }

     else

     {

         display4(s3);

     }

     if(san==5)

     {

        if(msecond_count<5)

        {

           display5(s2);

        } 

     }

     else

     {

         display5(s2);

     }

     if(san==6)

     {

        if(msecond_count<5)

        {

           display6(s1);

        } 

     }

     else

     {

         display6(s1);

     }

}

//****************************************

//时钟显示程序

void  dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1)

{

     display1(s6);

     display2(s5);

     display3(s4); 

     display4(s3);

     display5(s2);

     display6(s1); 

}

//********************************************************************************************

void init_t0()

{

       TMOD=0x01;//设定定时器工作方式1,定时器定时50毫秒

    TH0=(65536-50000)/256;

    TL0=(65536-50000)%256;

    EA=1;//开总中断

    ET0=1;//允许定时器0中断

    t0_crycle=0;//定时器中断次数计数单元

}

//**************************************************

//LED处理函数

void  dis_led()

     if(msecond_count<5)

     {

         led1_bit=1;

         led2_bit=1;

     }

     else

     {

         led1_bit=0;

         led2_bit=0;

     }

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display6(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit6=0;//锁存数据

   delay_50us(40);

   dis_bit6=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display5(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit5=0;//锁存数据

   delay_50us(40);

   dis_bit5=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display4(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit4=0;//锁存数据

   delay_50us(40);

   dis_bit4=1;

}//***************************************************************

//功能:把数据1显示在数码管1上

void display3(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit3=0;//锁存数据

   delay_50us(40);

   dis_bit3=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display1(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit1=0;//锁存数据

   delay_50us(40);

   dis_bit1=1;

}

//***************************************************************

//功能:把数据1显示在数码管1上

void display2(uchar dis_data)

{  

   smg_data=tabl1[dis_data];//送显示断码

   dis_bit2=0;//锁存数据

   delay_50us(40);

   dis_bit2=1;

}

//**************************************************************************************************

//函数名称:void delay_50US(unsigned int t)

//功能: 延时50*t(us)

void delay_50us(uint t)

{

  unsigned char j; 

  for(;t>0;t--) 

  {

    for(j=19;j>0;j--);

  }

//*******************************************************************************

//8微秒延时基准程序

void delay_8us(uint t)

{

 while(--t);

}

//*******************************************************************************

//3微秒延时程序

void delay_3us()

  ;

  ; 

}

//*******************************************************************************

//子程序功能:向DS18B20写一字节的数据

void w_1byte_ds18b20(uchar value) 

   uchar i=0; 

   for(i=0;i<8;i++)

   {

    dq_ds18b20=1;

    delay_3us();

    dq_ds18b20=0;

    delay_8us(2);

    if (value & 0x01) dq_ds18b20=1; //DQ = 1

    delay_50us(1); //延时50us 以上

    delay_8us(2);

    value>>=1;

   }

    dq_ds18b20=1; //DQ = 1

}

//读一个字节 

uchar r_1byte_ds18b20(void) 

{

  uchar i=0; 

  uchar value = 0; 

  for (i=0;i<8;i++) 

  {

   value>>=1;

   dq_ds18b20=0;// DQ_L;

   delay_3us();

   dq_ds18b20=1; //DQ_H;

   delay_8us(2);

   if(dq_ds18b20==1) value|=0x80; 

   delay_8us(6); //延时40us

  }

  dq_ds18b20=1;

  return value;

}

//;**************************************************

//ds18b20复位子程序

void rest_ds18b20(void) 

rest:delay_3us(); //稍做延时

     delay_3us();

     dq_ds18b20=1;

     delay_3us();

     dq_ds18b20=0;// DQ_L; 

     delay_50us(11);//480us     dq_ds18b20=1;//拉高总线

     delay_8us(5);

     if(dq_ds18b20==1)

     {  

       return;

     }  

     delay_50us(2); //延时90us

     if(dq_ds18b20==1)

     {

       return;

      }  

      else

      {

       goto rest;

      } 

}

//****************************************************

//读取温度 

void readtemp_ds18b20(void) 

    uchar temp32;

    rest_ds18b20();

    w_1byte_ds18b20(0xcc); //跳过读序列号的操作 

    w_1byte_ds18b20(0x44); //启动温度转换

    delay_8us(2);

    rest_ds18b20();

    w_1byte_ds18b20(0xcc); //跳过读序列号的操作 

    w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 

    templ=r_1byte_ds18b20();

    temph=r_1byte_ds18b20();

    if((temph&0xf0))//判断温度的正负性

    {

      temp_flag=0;//温度为负数标志

      temph=-temph;

      templ=-templ;

      t_x=tabl3[templ & 0x0f];//计算温度的小数

      temp32=temph & 0x0f;

      temp32<<=4;

      templ>>=4;

      temp32=temp32 | templ;

      t_b=temp32/100%10;//计算温度的百位数据

      t_s=temp32/10%10;//计算温度的十位数据

      t_g=temp32%10;//计算温度的个位数据

    }

    else//为正数

    {

      t_x=tabl3[templ & 0x0f];//计算温度的小数

      temp32=temph & 0x0f;

      temp32<<=4;

      templ>>=4;

      temp32=temp32 | templ;

      t_b=temp32/100%10;//计算温度的百位数据

      t_s=temp32/10%10;//计算温度的十位数据

      t_g=temp32%10;//计算温度的个位数据

      temp_flag=1;

     }

}

void dis_temp()//温度显示函数

{

     if(temp_flag=1)

     {

        if(t_b==0)

       {

         dis(12,12,t_s,t_g,13,12);

       }

       else

       {

         dis(12,t_b,t_s,t_g,13,12);

       }

     }

     else

     {

        dis(14,t_b,t_s,t_g,13,12);

     }

}

//;##############################################################################

//;子程序名:w_1byte_ds1302

//;功能:    向DS1302写一个字节的数据

void w_1byte_ds1302(uchar t)

{

  uchar i;

  for(i=0;i<8;i++)

  {

    if(t & 0x01)

     {io_ds1302=1;}

    else

     {io_ds1302=0;}

    clk_ds1302=1;

    delay_3us();

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    delay_3us();

    t>>=1;

  }  

}

//;########################################################################

//;子程序名:r_1byte_ds1302()

//;功能:    从DS1302读一个字节的数据

uchar r_1byte_ds1302()

  uchar i,temp11=0;

  io_ds1302=1;//置IO为1,准备读入数据

  for(i=0;i<8;i++)

  {

    temp11>>=1;

    if(io_ds1302) temp11 |= 0x80;

    clk_ds1302=1;

    delay_3us();

    delay_3us();

    clk_ds1302=0;

    delay_3us();

  } 

  return(temp11);

}  

//;#################################################################################

//;子程序名:setbds1302

//;功能:   设置DS1302初始时间,并启动计时

void set_ds1302()

  uchar i,j;

  rest_ds1302=0;

  delay_3us();

  clk_ds1302=0;

  delay_3us();

  rest_ds1302=1;

  delay_3us();

  w_1byte_ds1302(0x8e);//写控制命令字

  delay_3us();

  w_1byte_ds1302(0x00);//写保护关闭

  clk_ds1302=1;

  delay_3us();

  rest_ds1302=0;

  for(i=0,j=0x80;i<7;i++,j+=2)

  {

    rest_ds1302=0;

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    rest_ds1302=1;

    delay_3us();

    w_1byte_ds1302(j);

    delay_3us();

    w_1byte_ds1302(tab23[i]);

    delay_3us();

    delay_3us();

    clk_ds1302=1;

    delay_3us();

    rest_ds1302=0;

    delay_3us();

    delay_3us();

  }

  rest_ds1302=0;

  delay_3us();

  clk_ds1302=0;

  delay_3us();

  rest_ds1302=1;

  delay_3us();

  w_1byte_ds1302(0x8e);

  delay_3us();

  w_1byte_ds1302(0x80);

  clk_ds1302=1;

  delay_3us();

  rest_ds1302=0;

  delay_3us();

}  

//;#################################################################-------

//;子程序名:get1302

void get_ds1302()

   uchar temp11[7],i,j;

   for(i=0;i<7;i++)

   {temp11[i]=0;}

   for(i=0,j=0x81;i<7;i++,j+=2)

   {  

    rest_ds1302=0;

    delay_3us();

    clk_ds1302=0;

    delay_3us();

    rest_ds1302=1;

    delay_3us();

    w_1byte_ds1302(j);

    temp11[i]=r_1byte_ds1302();

    delay_3us();

    clk_ds1302=1;

    delay_3us();

    rest_ds1302=0;

    delay_3us();

  }

  if(temp11[0]!=0xff)

  {second_count=temp11[0];}

  if(temp11[1]!=0xff)// 数据验证

  {minute_count=temp11[1];}

  if(temp11[2]!=0xff)//数据验证

  {hour_count=temp11[2];}

 // date=temp[3];

  //month=temp[4];

 // week=temp[5];

  //year=temp[6];

下载本文

显示全文
专题