标题: 买的创意旋转时钟,自己添加ESP8266网络自动校时功能 附程序 [打印本页]

作者: felixsun1975    时间: 2019-3-14 15:24
标题: 买的创意旋转时钟,自己添加ESP8266网络自动校时功能 附程序
前段时间t 宝买了个创意旋转时钟

用了一段时间感觉走时不准, 打算加个自动校时功能就自己重写了单片机程序并配了个ESP8266的模块
现在终于不用再手工校对时间了,而且还有18650电池,可以充电



单片机程序
  1. #include <global.h>
  2. #include <stdio.h>
  3. #include "DS1302.h"
  4. #include "DS18B20.h"

  5. //-----------------------------------------------

  6. /* define constants */
  7. #define FOSC 12000000
  8. #define BAUD 19200           //UART baudrate

  9. bit UpdateDisp,UpdateTime,ShowTemp,CapTemp,TempChange,UpdateMsg,ShowFlag;

  10. static uint8 ss=0;
  11. static uint16 ms=0;

  12. #define CommBufSize 0x3F
  13. struct tcomm_buf{
  14.     uint8 sendBuf[CommBufSize],receBuf[CommBufSize];
  15.     uint8        receTimeOut;
  16.     uint8        sendCount;                //发送字节个数
  17.     uint8        receCount;            //接收到的字节个数
  18.     uint8        sendPosi;            //发送位置
  19. };

  20. struct tcomm_buf xdata comm1_data;
  21. /*
  22. void Delay1ms()                //@12.000MHz
  23. {
  24.         unsigned char i, j;

  25.         i = 2;
  26.         j = 239;
  27.         do
  28.         {
  29.                 while (--j);
  30.         } while (--i);
  31. }
  32. void Delayms(uint16 c)                //@12.000MHz
  33. {
  34.         while(c--)
  35.         Delay1ms();
  36. }
  37. */

  38. void Uart_Check(void);

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

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


  46. void UpdateNixie(uint8 l){
  47.     int8 tmpVal;
  48.     P2=0xFF;  //led
  49.     P3=(P3|0xF0);
  50.     P0= 0xFF;
  51.     if(ShowTemp){
  52.         switch(l){
  53.             case 0:
  54.                 tmpVal = Temp1/10;
  55.                 break;
  56.             case 1:
  57.                 tmpVal = Temp1%10;
  58.                 break;
  59.             case 2:
  60.                 tmpVal = 16;
  61.                 break;
  62.             case 3:
  63.                 tmpVal = 0x0C;
  64.                 break;
  65.         }
  66.         P0= NixieMap[tmpVal];  //Led/数码管公用IO        
  67.     }
  68.     else
  69.     {  
  70.         switch(l){
  71.             case 0:
  72.                 tmpVal =  hour/10;
  73.                 //P0= 0xC0;
  74.                 //P3=0xE0|(P3&0x0F);
  75.                 break;
  76.             case 1:
  77.                 tmpVal =  hour%10;
  78.                 //P0= 0xF9;
  79.                 //P3=0xD0|(P3&0x0F);
  80.                 break;
  81.             case 2:
  82.                 tmpVal = min/10;
  83.                 //P0= 0xA4;
  84.                 //P3=0xB0|(P3&0x0F);
  85.                 break;
  86.             case 3:
  87.                 tmpVal = min%10;
  88.                 //P0= 0xB0;
  89.                 //P3=0x70|(P3&0x0F);
  90.                 break;
  91.         }
  92.         if(l==1&&ShowFlag)
  93.             P0= NixieMap[tmpVal] & 0x7F;  //Led/数码管公用IO
  94.         else
  95.             P0= NixieMap[tmpVal];  //Led/数码管公用IO
  96.     }
  97.     P3=(~(1<<(l+4)))|(P3 & 0x0F);  //高四位数码管  P3.0 P3.1 串口  P3.2  MODE  P3.3 Plus      
  98. }

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

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

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


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

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


  161. /* Timer0 interrupt routine */
  162. void tm0_isr() interrupt 1 using 1
  163. {
  164.     UpdateDisp=1;
  165.     ShowFlag = ms<122;
  166.     if(ms++>222){
  167.         ms=0;
  168.         sec++;
  169.         switch(sec%4){
  170.             case 1:
  171.                 TempChange=1;
  172.                 break;
  173.             case 2:
  174.                 CapTemp=1;
  175.                 break;
  176.             case 3:
  177.                 //ShowTemp=1;
  178.                 break;
  179.         }
  180.         
  181.         if(sec>=60){
  182.             sec=0;
  183.             UpdateTime=1;
  184.         }
  185.         if((sec%5)>=3){
  186.             ShowTemp=1;
  187.         }
  188.         else
  189.             ShowTemp=0;
  190.     }
  191. }

  192. void WaitMs(void){
  193.     while(UpdateDisp==0);
  194. }


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

  203.     comm1_data.sendCount=0;   
  204.     comm1_data.sendPosi=0;   

  205.         UartInit();
  206.     Timer0Init();

  207.     EA = 1;                 //Open master interrupt switch

  208.     printf("STC89-90xx\r\nUart Test !\r\n");
  209.     DS1302_readtime();
  210.    
  211. //    year=18;
  212. //    month=11;
  213. //    day=2;
  214. //    hour=14;
  215. //    min=32;
  216. //    sec=0;
  217. //   
  218. //    DS1302_Write();
  219.    
  220.     //P0=0x1;   
  221.     //uint8 c=1;
  222.     while(1){
  223.         Uart_Check();
  224.         UpdateNixie(0);
  225.         WaitMs();
  226.         UpdateNixie(1);
  227.         WaitMs();
  228.         UpdateNixie(2);
  229.         WaitMs();
  230.         UpdateNixie(3);
  231.         WaitMs();
  232.         UpdateLed();
  233.         if(UpdateTime){
  234.             UpdateTime=0;
  235.             DS1302_readtime();//sec,min,hour,day,month,week,year
  236.             printf("Update Time %02d-%02d-%02d  %02d:%02d:%02d\r\n",year,month,day,hour,min,sec);
  237.         }
  238.         if(TempChange){
  239.             TempChange=0;
  240.             Start_Change();
  241.         }        
  242.         if(CapTemp){
  243.             CapTemp=0;
  244.             Read_Temperature();
  245.         }        
  246. //        if(ShowTemp){
  247. //            ShowTemp=0;
  248. //            printf("Temperature: %.1f\r\n",Temp);
  249. //        }
  250.         WaitMs();
  251.     }
  252. }


  253. /*----------------------------
  254. UART interrupt service routine
  255. ----------------------------*/
  256. void Uart_Isr() interrupt 4 using 1
  257. {
  258.         if(TI)
  259.         {
  260.                 TI = 0;
  261.                 if(comm1_data.sendPosi < comm1_data.sendCount)
  262.                 {
  263.                         SBUF = comm1_data.sendBuf[comm1_data.sendPosi++];
  264.                 }
  265.                 else
  266.                 {
  267.             comm1_data.sendPosi = 0;
  268.             comm1_data.sendCount = 0;
  269.                         comm1_data.receCount = 0;   //清接收地址偏移寄存器
  270.                 }
  271.         }
  272.         else if(RI)
  273.         {
  274.                 RI = 0;
  275.                 comm1_data.receTimeOut = 5;    //通讯超时值
  276. ……………………

  277. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

NewClock.7z (15.95 KB, 下载次数: 182)
esp8266程序(基于Arduino)
TimeNTP_ESP8266WiFi.7z (2.08 KB, 下载次数: 179)


作者: 凤的情绪    时间: 2019-3-16 09:24
楼主 这个需要连手机  用网络校准吗?那个基于安卓什么意思

作者: felixsun1975    时间: 2019-3-19 11:14
凤的情绪 发表于 2019-3-16 09:24
楼主 这个需要连手机  用网络校准吗?那个基于安卓什么意思

Arduino 不是安卓哦, 这个不需要手机的,只要有wifi就可以
作者: zikuan    时间: 2019-3-24 09:51
没有图纸吗

作者: yyhhgg    时间: 2019-5-9 14:34
没有看懂,为什么还要用单独的单片机和DS1302,8266完全可以胜任还节省器件
作者: lbq691477940    时间: 2019-5-16 13:06
你这程序外圈不会亮吧
作者: StarSky2000    时间: 2019-6-18 11:56
谢谢分享
作者: 仰望星臣    时间: 2020-6-3 21:16
谢谢分享
作者: chromalyl    时间: 2020-6-6 21:57
谢谢分享
作者: liang118038    时间: 2020-6-7 12:46
其实直接用NodeMCU就行啦,要驱动LED只要加HC595就行,根本不用用STC单片机
作者: radio0326    时间: 2020-8-12 10:56
看了半天没研究出个啥,
作者: laduo    时间: 2021-5-8 14:09
太好了,有个同样的闹钟
作者: yygdzjs    时间: 2021-5-8 18:04
看了你改动的,硬件改动不大,也合理,挺好.
我也买过  测试了一下.
1. 18650 电池 (1600MA)  升压5V   3天左右充一次电.
2. 蜂鸣器 声音(嘀嘀响  赤耳).
3. 设置时间闹钟参数时   数码管显示(有些人不一定会调) 局限性,看说明书才会吧.
4. 如果 改时钟DS3231 芯片,时间误差小,价格贵些.
5.  好的地方  花样灯  可以.
6.  好的地方 初学者练习焊接 动手能力 学习不错.


作者: woshishui22    时间: 2021-5-9 10:14
增加自动校时,是个不错的主意!
作者: 吾心悦汝    时间: 2021-6-20 12:37
yyhhgg 发表于 2019-5-9 14:34
没有看懂,为什么还要用单独的单片机和DS1302,8266完全可以胜任还节省器件

楼主是不想放弃这个时钟外圈的灯效吧
作者: pengyongnet    时间: 2023-3-23 05:28
能提供下设计资料吗
作者: 3310mad2    时间: 2023-4-4 21:41
好东西,标记一下
作者: gzgy    时间: 2024-5-5 16:09
这玩意儿误差太大,加个网络校时功能废物再利用,还不错。
作者: lxm41577    时间: 2024-5-23 17:08
楼主,能否指点一下,我制作的时钟是DS1302走时,8266网络单片机串口接收校准,它们之间如何转换,我发现DS1302是16进制,8266串口接收是十进制,我一直没搞定不知如何转换,单独的程序都可以用,请楼主不吝赐教
作者: 偷朱了    时间: 2024-5-25 12:49
哇,谢谢楼主,我也要做一个




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1