前段时间t 宝买了个创意旋转时钟
image.png
用了一段时间感觉走时不准, 打算加个自动校时功能就自己重写了单片机程序并配了个ESP8266的模块
现在终于不用再手工校对时间了,而且还有18650电池,可以充电
image.png
正面

image.png
背面


单片机程序

  • #include <global.h>
  • #include <stdio.h>
  • #include "DS1302.h"
  • #include "DS18B20.h"

  • //-----------------------------------------------

  • /* define constants */
  • #define FOSC 12000000
  • #define BAUD 19200           //UART baudrate

  • bit UpdateDisp,UpdateTime,ShowTemp,CapTemp,TempChange,UpdateMsg,ShowFlag;

  • static uint8 ss=0;
  • static uint16 ms=0;

  • #define CommBufSize 0x3F
  • struct tcomm_buf{
  •     uint8 sendBuf[CommBufSize],receBuf[CommBufSize];
  •     uint8        receTimeOut;
  •     uint8        sendCount;                //发送字节个数
  •     uint8        receCount;            //接收到的字节个数
  •     uint8        sendPosi;            //发送位置
  • };

  • struct tcomm_buf xdata comm1_data;
  • /*
  • void Delay1ms()                //@12.000MHz
  • {
  •         unsigned char i, j;

  •         i = 2;
  •         j = 239;
  •         do
  •         {
  •                 while (--j);
  •         } while (--i);
  • }
  • void Delayms(uint16 c)                //@12.000MHz
  • {
  •         while(c--)
  •         Delay1ms();
  • }
  • */

  • void Uart_Check(void);

  • void UpdateLed(void){
  •     P3= P3|0xF0;  //高四位数码管  P3.1 P3.2 串口  P3.2  MODE  P3.3 Plus
  •     P2=0xFF;
  •     P0=~(1<<(sec%8));  //Led/数码管公用IO
  •     P2=~(1<<(sec/8));  //led
  • }

  • const uint8 NixieMap[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x9C,0xFF};


  • void UpdateNixie(uint8 l){
  •     int8 tmpVal;
  •     P2=0xFF;  //led
  •     P3=(P3|0xF0);
  •     P0= 0xFF;
  •     if(ShowTemp){
  •         switch(l){
  •             case 0:
  •                 tmpVal = Temp1/10;
  •                 break;
  •             case 1:
  •                 tmpVal = Temp1%10;
  •                 break;
  •             case 2:
  •                 tmpVal = 16;
  •                 break;
  •             case 3:
  •                 tmpVal = 0x0C;
  •                 break;
  •         }
  •         P0= NixieMap[tmpVal];  //Led/数码管公用IO
  •     }
  •     else
  •     {
  •         switch(l){
  •             case 0:
  •                 tmpVal =  hour/10;
  •                 //P0= 0xC0;
  •                 //P3=0xE0|(P3&0x0F);
  •                 break;
  •             case 1:
  •                 tmpVal =  hour%10;
  •                 //P0= 0xF9;
  •                 //P3=0xD0|(P3&0x0F);
  •                 break;
  •             case 2:
  •                 tmpVal = min/10;
  •                 //P0= 0xA4;
  •                 //P3=0xB0|(P3&0x0F);
  •                 break;
  •             case 3:
  •                 tmpVal = min%10;
  •                 //P0= 0xB0;
  •                 //P3=0x70|(P3&0x0F);
  •                 break;
  •         }
  •         if(l==1&&ShowFlag)
  •             P0= NixieMap[tmpVal] & 0x7F;  //Led/数码管公用IO
  •         else
  •             P0= NixieMap[tmpVal];  //Led/数码管公用IO
  •     }
  •     P3=(~(1<<(l+4)))|(P3 & 0x0F);  //高四位数码管  P3.0 P3.1 串口  P3.2  MODE  P3.3 Plus
  • }

  • //void UartInit(void)                //115200bps@22.1184MHz
  • //{
  • //        PCON |= 0x80;                //使能波特率倍速位SMOD
  • //        SCON = 0x50;                //8位数据,可变波特率
  • //        AUXR &= 0xBF;                //定时器1时钟为Fosc/12,即12T
  • //        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  • //        TMOD &= 0x0F;                //清除定时器1模式位
  • //        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
  • //        TL1 = 0xFF;                //设定定时初值
  • //        TH1 = 0xFF;                //设定定时器重装值
  • //        ET1 = 0;                //禁止定时器1中断
  • //        TR1 = 1;                //启动定时器1
  • //    ES=1;
  • //}

  • //void UartInit(void)                //19200bps@22.1184MHz
  • //{
  • //        PCON &= 0x7F;                //波特率不倍速
  • //        SCON = 0x50;                //8位数据,可变波特率
  • //        AUXR &= 0xBF;                //定时器1时钟为Fosc/12,即12T
  • //        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  • //        TMOD &= 0x0F;                //清除定时器1模式位
  • //        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
  • //        TL1 = 0xFD;                //设定定时初值
  • //        TH1 = 0xFD;                //设定定时器重装值
  • //        ET1 = 0;                //禁止定时器1中断
  • //        TR1 = 1;                //启动定时器1
  • //    ES=1;
  • //}

  • void UartInit(void)                //9600bps@22.1184MHz
  • {
  •         PCON &= 0x7F;                //波特率不倍速
  •         SCON = 0x50;                //8位数据,可变波特率
  •         AUXR &= 0xBF;                //定时器1时钟为Fosc/12,即12T
  •         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  •         TMOD &= 0x0F;                //清除定时器1模式位
  •         TMOD |= 0x20;                //设定定时器1为8位自动重装方式
  •         TL1 = 0xFA;                //设定定时初值
  •         TH1 = 0xFA;                //设定定时器重装值
  •         ET1 = 0;                //禁止定时器1中断
  •         TR1 = 1;                //启动定时器1
  •     ES=1;
  • }


  • //void Timer0Init(void)                //1毫秒@22.1184MHz
  • //{
  • //        AUXR &= 0x7F;                //定时器时钟12T模式
  • //        TMOD &= 0xF0;                //设置定时器模式
  • //        TL0 = 0x00;                //设置定时初值
  • //        TH0 = 0xB8;                //设置定时初值
  • //        TF0 = 0;                //清除TF0标志
  • //        TR0 = 1;                //定时器0开始计时
  • //    ET0 = 1;                        //enable timer0 interrupt
  • //}

  • void Timer0Init(void)                //25毫秒@22.1184MHz
  • {
  •         AUXR &= 0x7F;                //定时器时钟12T模式
  •         TMOD &= 0xF0;                //设置定时器模式
  •         TL0 = 0x00;                //设置定时初值
  •         TH0 = 0x4C;                //设置定时初值
  •         TF0 = 0;                //清除TF0标志
  •         TR0 = 1;                //定时器0开始计时
  •     ET0 = 1;                        //enable timer0 interrupt
  • }


  • /* Timer0 interrupt routine */
  • void tm0_isr() interrupt 1 using 1
  • {
  •     UpdateDisp=1;
  •     ShowFlag = ms<122;
  •     if(ms++>222){
  •         ms=0;
  •         sec++;
  •         switch(sec%4){
  •             case 1:
  •                 TempChange=1;
  •                 break;
  •             case 2:
  •                 CapTemp=1;
  •                 break;
  •             case 3:
  •                 //ShowTemp=1;
  •                 break;
  •         }

  •         if(sec>=60){
  •             sec=0;
  •             UpdateTime=1;
  •         }
  •         if((sec%5)>=3){
  •             ShowTemp=1;
  •         }
  •         else
  •             ShowTemp=0;
  •     }
  • }

  • void WaitMs(void){
  •     while(UpdateDisp==0);
  • }


  • void main()
  • {
  •     P0=0xFF;  //Led/数码管公用IO
  •     P1=0xFF;  // 蜂鸣器  P1.0 18B20  P1.1 P1.2 P1.3  DS1302
  •     P2=0xFF;  //led
  •     P3=0xFF;  //高四位数码管  P3.0 P3.1 串口  P3.2  MODE  P3.3 Plus
  •     ShowFlag = 0;
  •     ShowTemp = 0;

  •     comm1_data.sendCount=0;
  •     comm1_data.sendPosi=0;

  •         UartInit();
  •     Timer0Init();

  •     EA = 1;                 //Open master interrupt switch

  •     printf("STC89-90xx\r\nUart Test !\r\n");
  •     DS1302_readtime();

  • //    year=18;
  • //    month=11;
  • //    day=2;
  • //    hour=14;
  • //    min=32;
  • //    sec=0;
  • //
  • //    DS1302_Write();

  •     //P0=0x1;
  •     //uint8 c=1;
  •     while(1){
  •         Uart_Check();
  •         UpdateNixie(0);
  •         WaitMs();
  •         UpdateNixie(1);
  •         WaitMs();
  •         UpdateNixie(2);
  •         WaitMs();
  •         UpdateNixie(3);
  •         WaitMs();
  •         UpdateLed();
  •         if(UpdateTime){
  •             UpdateTime=0;
  •             DS1302_readtime();//sec,min,hour,day,month,week,year
  •             printf("Update Time %02d-%02d-%02d  %02d:%02d:%02d\r\n",year,month,day,hour,min,sec);
  •         }
  •         if(TempChange){
  •             TempChange=0;
  •             Start_Change();
  •         }
  •         if(CapTemp){
  •             CapTemp=0;
  •             Read_Temperature();
  •         }
  • //        if(ShowTemp){
  • //            ShowTemp=0;
  • //            printf("Temperature: %.1f\r\n",Temp);
  • //        }
  •         WaitMs();
  •     }
  • }


  • /*----------------------------
  • UART interrupt service routine
  • ----------------------------*/
  • void Uart_Isr() interrupt 4 using 1
  • {
  •         if(TI)
  •         {
  •                 TI = 0;
  •                 if(comm1_data.sendPosi < comm1_data.sendCount)
  •                 {
  •                         SBUF = comm1_data.sendBuf[comm1_data.sendPosi++];
  •                 }
  •                 else
  •                 {
  •             comm1_data.sendPosi = 0;
  •             comm1_data.sendCount = 0;
  •                         comm1_data.receCount = 0;   //清接收地址偏移寄存器
  •                 }
  •         }
  •         else if(RI)
  •         {
  •                 RI = 0;
  •                 comm1_data.receTimeOut = 5;    //通讯超时值
  • ……………………