找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9638|回复: 6
收起左侧

ESP8266-nonos-sdk实现的实时时钟

[复制链接]
ID:206163 发表于 2017-5-30 21:10 | 显示全部楼层 |阅读模式
使用ESP8266-nonos-sdk 实现的实时时钟
0.png

源程序:
  1. /* main.c -- MQTT client example
  2. *
  3. * Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Redis nor the names of its contributors may be used
  15. * to endorse or promote products derived from this software without
  16. * specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "ets_sys.h"
  31. #include "driver/uart.h"
  32. #include "osapi.h"
  33. #include "debug.h"
  34. #include "gpio.h"
  35. #include "user_interface.h"
  36. #include "mem.h"
  37. #include "c_types.h"
  38. #include "math.h"

  39. #include "red_avoidance.h"
  40. #include "at24c.h"
  41. #include "my_mqtt.h"
  42. #include "ds3231.h"
  43. #include "time.h"
  44. #include "motor.h"
  45. #include "oled.h"
  46. //#define ESSID                "ALARM-CLOCK"
  47. //#define PASSWORD        "password"
  48. #define ESSID                "essid"
  49. #define PASSWORD        "password"

  50. os_timer_t rssi_timer;
  51. os_timer_t SetdsTimer,ShowdsTime;
  52. os_timer_t motor_call_timer;

  53. //时间各要素存储变量,从0起,分别为秒、分、时、星期几、每月的几日、月、年,以及温度整数部分和小数部分的一位存储变量
  54. uint8 inttemp[1],floattemp[1];

  55. //定义字符串变量存贮从sntp真实时间中截取到的秒、分、时、星期几、每月的几日、月、年
  56. char* chsec,chmin,chhour,chwday,chmday,chmon,chyear;

  57. struct tm timedate;

  58. char distance[16] = {0};
  59. double doub_distance = 0;

  60. uint8 motor_flag = 0, motor_stop_flag = 0;

  61. void ICACHE_FLASH_ATTR
  62. alarm_run_go()
  63. {
  64. //        static uint8 static_f=0;
  65. //        red_flag = red_read();
  66. //        if(red_flag && static_f)
  67. //        {
  68. //                motor_turn_left();
  69. //                static_f=0;
  70. //        }
  71. //        else
  72. //        {
  73. //                if (!static_f)
  74. //                {
  75. //                        motor_go_ahead();
  76. //                        static_f=1;
  77. //                }
  78. //        }
  79.         motor_go_ahead();
  80. }

  81. void ICACHE_FLASH_ATTR
  82. alarm_run_black()
  83. {
  84. //        static uint8 static_f=0;
  85. //        if(red_flag && static_f)
  86. //        {
  87. //                motor_turn_right();
  88. //                static_f=0;
  89. //        }
  90. //        else
  91. //        {
  92. //                if (!static_f)
  93. //                {
  94. //                        motor_go_back();
  95. //                        static_f=1;
  96. //                }
  97. //        }
  98.         motor_go_back();
  99. }

  100. void ICACHE_FLASH_ATTR
  101. motor_call_cb()
  102. {
  103.         static uint8 flag = 0;
  104.         uint8 red_flag = red_read();
  105.         if (motor_flag == 0)
  106.         {
  107.                 motor_stop();
  108.                 motor_flag = 4;
  109.         }
  110.         else if (motor_flag == 1)
  111.         {
  112.                 alarm_run_go();
  113.                 motor_flag = 3;
  114.         }
  115.         else if (motor_flag == 2)
  116.         {
  117.                 if ( doub_distance - 0.2 > 0.01)
  118.                 {
  119.                         alarm_run_black();
  120.                 }
  121.                 else
  122.                 {
  123.                         motor_flag = 0;
  124.                 }
  125.         }
  126.         else if (motor_flag == 3)
  127.         {
  128.                 if (motor_stop_flag)
  129.                 {
  130.                         motor_flag = 4;
  131.                 }
  132.                 else
  133.                 {
  134.                         if (red_flag)
  135.                         {
  136.                                 motor_turn_left();
  137.                                 flag = 1;
  138.                         }
  139.                         else
  140.                         {
  141.                                 if (flag)
  142.                                         motor_flag = 1;
  143.                                 flag = 0;
  144.                         }
  145.                 }
  146.         }
  147.         else
  148.         {
  149.                 os_timer_disarm(&motor_call_timer);
  150.         }

  151. }



  152. void get_rssi_timer_cb();
  153. //当前时间及温度显示回调函数
  154. static  void ICACHE_FLASH_ATTR TimeShow()
  155. {
  156.         char sen_str[125] = {0};
  157.         static uint8 alarm_flag = 0, alarm_flag2 = 0, alarm_flag3 = 0;
  158.         //获取当前时间及温度整数和小数部分s
  159.         //system_uart_de_swap();
  160.         if(ds3231_getTime(&timedate))
  161.         {
  162.                 ds3231_getTempInteger(inttemp);
  163.                 ds3231_getTempFloat(floattemp);
  164.                 os_sprintf(sen_str, "20%02d,%02d,%02d  %d", timedate.tm_year,timedate.tm_mon,timedate.tm_mday, timedate.tm_wday);
  165.                 OLED_ShowStr(2, 0, sen_str, 1);
  166.                 get_rssi_timer_cb();
  167.                 //如果温度整数部分小于128,则为正温度,否则为负温度 ,因为其分辨率为0.25,所以小数部分要乘以个0.25
  168.                 if(inttemp[0]<128)
  169.                         os_sprintf(sen_str, "%02d.%02dC", inttemp[0],floattemp[0]*25);
  170.                         //os_sprintf(sen_str, "(%02d,%02d,%02d,%02d,%02d,%02d,%d,%02d.%02d,%4s)",timedate.tm_year,timedate.tm_mon,timedate.tm_mday,timedate.tm_hour,timedate.tm_min,timedate.tm_sec,timedate.tm_wday,inttemp[0],floattemp[0]*25, distance);
  171.                 else
  172.                         os_sprintf(sen_str, "%02d.%02dC", inttemp[0]-128,floattemp[0]*25);
  173.                         //os_sprintf(sen_str, "(%02d,%02d,%02d,%02d,%02d,%2d,%d,%02d.%02d,%4s)",timedate.tm_year,timedate.tm_mon,timedate.tm_mday,timedate.tm_hour,timedate.tm_min,timedate.tm_sec,timedate.tm_wday,inttemp[0]-128,floattemp[0]*25, distance);
  174.                 OLED_ShowStr(90, 0, sen_str, 1);
  175.                 //uart0_sendStr(sen_str);
  176.                 os_sprintf(sen_str, "%02d:%02d:%02d",timedate.tm_hour,timedate.tm_min,timedate.tm_sec);
  177.                 OLED_ShowStr(30, 3, sen_str, 2);
  178.                 os_sprintf(sen_str, "%4sm",distance);
  179.                 OLED_ShowStr(50, 5, sen_str, 2);
  180.         //        // 产生闹钟信号 持续1min
  181.                 if (alarm_if_time_arri(timedate.tm_hour, timedate.tm_min, timedate.tm_wday))
  182.                 {
  183.                         if (! alarm_flag2)
  184.                         {
  185.                                 os_printf("time arrive\n");
  186.                                 motor_stop_flag  = 0;
  187.                                 motor_flag = 1;
  188.                                 os_timer_disarm(&motor_call_timer);
  189.                                 os_timer_setfn(&motor_call_timer, motor_call_cb, NULL);
  190.                                 os_timer_arm(&motor_call_timer, 100, 1);
  191.                                 alarm_flag2 = 1;
  192.                         }
  193.                 }
  194.                 else
  195.                 {
  196.                         motor_flag = 2;
  197.                         alarm_flag = 0;
  198.                         if (motor_flag == 4 || motor_flag == 0)
  199.                         {
  200.                                 alarm_flag2 = 0;
  201.                                 os_timer_disarm(&motor_call_timer);
  202.                         }
  203.                 }
  204. //                闹铃时间到 且当前没有其他到达的闹铃时间
  205. //                if (alarm_flag && !alarm_flag2)
  206. //                {
  207. //                        alarm_run_go();
  208. //                        alarm_flag2 = 1;
  209. //                        alarm_flag3 = 1;
  210. //                }
  211. //                if (!alarm_flag && alarm_flag2)
  212. //                        motor_stop();
  213. //                if (alarm_flag3 && !alarm_flag)
  214. //                {
  215. //                        if ((doub_distance - 0.2) > 0.01)
  216. //                                alarm_run_black();
  217. //                        else
  218. //                        {
  219. //                                motor_stop();
  220. //                                alarm_flag3 = 0;
  221. //                        }
  222. //                }

  223.         }
  224.         else
  225.                 os_printf("get time error\n");
  226.         //system_uart_swap();
  227. }

  228. //获取当前网络时钟,并设置到DS3231中
  229. static  void ICACHE_FLASH_ATTR SetDsTime()
  230. {
  231.         uint32_t time = sntp_get_current_timestamp();

  232.         if(time>0)
  233.         {
  234.                 os_timer_disarm(&SetdsTimer);
  235.             os_printf("time:%d\r\n",time);
  236.             os_printf("date:%s\r\n",sntp_get_real_time(time));//传入time参数给sntp_get_real_time

  237.                 char* tttt="Wed Dec 07 16:34:45 2016";

  238.             os_strcpy(tttt,sntp_get_real_time(time));

  239.                 //因为后期使用的os_strncpy函数不能自动将字符串中的\0字符串结束符号一并拷贝进来,所以这里根据年月日的长度构造函数,并初始化后各位有\0符号,不至于函数崩溃
  240.                 char chsec[3]={""};
  241.                 char chmin[3]={""};
  242.                 char chhour[3]={""};
  243.                 char chwday[4]={""};
  244.                 char chmday[3]={""};
  245.                 char chmon[4]={""};
  246.                 char chyear[5]={""};

  247.             //待截取字符串指针名即为字符串的起始地址,移动多少个后即为第I位的起始地址,也就是截取的起点
  248.                 os_strncpy(chsec,tttt+17,2);
  249.             os_strncpy(chmin,tttt+14,2);
  250.             os_strncpy(chhour,tttt+11,2);
  251.             os_strncpy(chwday,tttt,3);
  252.             os_strncpy(chmday,tttt+8,2);
  253.             os_strncpy(chmon,tttt+4,3);
  254.             os_strncpy(chyear,tttt+20,4);

  255.             os_printf("\r\nSubdate:%s,%s,%s,%s,%s,%s-----%s\r\n",chyear,chmon,chmday,chhour,chmin,chsec,chwday);//传入time参数给sntp_get_real_time

  256.             //赋值给时间设置变量
  257.             timedate.tm_year=(chyear[2]-48)*10+(chyear[3]-48);

  258.             if(strcmp(chmon,"Jan")==0)
  259.                     timedate.tm_mon=1;
  260.             else if(strcmp(chmon,"Feb")==0)
  261.                     timedate.tm_mon=2;
  262.             else if(strcmp(chmon,"Mar")==0)
  263.                     timedate.tm_mon=3;
  264.             else if(strcmp(chmon,"Apr")==0)
  265.                     timedate.tm_mon=4;
  266.             else if(strcmp(chmon,"May")==0)
  267.                     timedate.tm_mon=5;
  268.             else if(strcmp(chmon,"Jun")==0)
  269.                     timedate.tm_mon=6;
  270.             else if(strcmp(chmon,"Jul")==0)
  271.                     timedate.tm_mon=7;
  272.             else if(strcmp(chmon,"Aug")==0)
  273.                     timedate.tm_mon=8;
  274.             else if(strcmp(chmon,"Sep")==0)
  275.                     timedate.tm_mon=9;
  276.             else if(strcmp(chmon,"Oct")==0)
  277.                     timedate.tm_mon=10;
  278.             else if(strcmp(chmon,"Nov")==0)
  279.                     timedate.tm_mon=11;
  280.             else if(strcmp(chmon,"Dec")==0)
  281.                     timedate.tm_mon=12;

  282.             timedate.tm_mday=(chmday[0]-48)*10+(chmday[1]-48);
  283.             timedate.tm_hour=(chhour[0]-48)*10+(chhour[1]-48);
  284.             timedate.tm_min=(chmin[0]-48)*10+(chmin[1]-48);
  285.             timedate.tm_sec=(chsec[0]-48)*10+(chsec[1]-48);

  286.             if(strcmp(chwday,"Mon")==0)
  287.                     timedate.tm_wday=1;
  288.             else if(strcmp(chwday,"Tue")==0)
  289.                     timedate.tm_wday=2;
  290.             else if(strcmp(chwday,"Wed")==0)
  291.                     timedate.tm_wday=3;
  292.             else if(strcmp(chwday,"Thu")==0)
  293.                     timedate.tm_wday=4;
  294.             else if(strcmp(chwday,"Fri")==0)
  295.                     timedate.tm_wday=5;
  296.             else if(strcmp(chwday,"Sat")==0)
  297.                     timedate.tm_wday=6;
  298.             else if(strcmp(chwday,"Sun")==0)
  299.                     timedate.tm_wday=7;

  300.             os_printf("\r\nSet Time:%d,%d,%d,%d,%d,%d-----%d\r\n",timedate.tm_year,timedate.tm_mon,timedate.tm_mday,timedate.tm_hour,timedate.tm_min,timedate.tm_sec,timedate.tm_wday);

  301.             ds3231_setTime(timedate);
  302.         }

  303. }


  304. void ICACHE_FLASH_ATTR
  305. printFloat(float val, char *buff) {
  306.    char smallBuff[16];
  307.    int val1 = (int) val;
  308.    unsigned int val2;
  309.    if (val < 0) {
  310.       val2 = (int) (-1000.0 * val) % 1000;
  311.    } else {
  312.       val2 = (int) (1000.0 * val) % 1000;
  313.    }
  314.    if (val2 < 10) {
  315.       os_sprintf(smallBuff, "%i.0%u", val1, val2);
  316.    } else {
  317.       os_sprintf(smallBuff, "%i.%u", val1, val2);
  318.    }
  319.    os_strncpy(buff, smallBuff, 16);
  320. }

  321. void ICACHE_FLASH_ATTR
  322. get_rssi_timer_cb()
  323. {
  324.         static double last_d;
  325.         sint8 rssi =  wifi_station_get_rssi();
  326.         double d = pow(10, (-rssi -74.0)/ (30.0));
  327.         if (last_d > 0.01)
  328.         {
  329.                 doub_distance = last_d * 0.3 + d;
  330.         }
  331.         else
  332.         {
  333.                 doub_distance = d;
  334.         }
  335.         printFloat(doub_distance, distance);
  336.         last_d = doub_distance;
  337. }

  338. void wifiConnectCb(uint8_t status)
  339. {
  340.         if(status == STATION_GOT_IP){
  341.             //联网后初始化SNTP
  342.                 sntp_init();
  343.                 //启动mqtt连接
  344.                 mqtt_Start();
  345.                 // 20s 获取一次网络时间并更新DS3231的时间。
  346.                 os_timer_disarm(&SetdsTimer);
  347.                 os_timer_setfn(&SetdsTimer, SetDsTime, NULL);
  348.                 os_timer_arm(&SetdsTimer, 20000, 1);
  349.                 // 1s 采集一次距离信息
  350.                 os_timer_setfn(&rssi_timer, get_rssi_timer_cb, NULL);
  351.                 os_timer_arm(&rssi_timer, 1000, 1);
  352.         } else {
  353.                 INFO("Wifi: DisConnected\r\n");
  354.         }
  355. }

  356. void GPIO_INTER(void)
  357. {
  358.         uint16 gpio_status = 0;
  359.         gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);//判断io口状态
  360.         ETS_GPIO_INTR_DISABLE();//关闭中断


  361.         if(GPIO_INPUT_GET(2) == 0)
  362.         {
  363.                 os_printf("触发中断\r\n");
  364.                 motor_stop();
  365.                 motor_stop_flag = 1;
  366.         }
  367.         os_delay_us(10000);
  368.         GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);//清中断标志
  369.         ETS_GPIO_INTR_ENABLE();//打开中断

  370. }
  371. void key_stop_gpio2_init()
  372. {
  373.         PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2);
  374.         GPIO_DIS_OUTPUT(GPIO_ID_PIN(2));
  375.         ETS_GPIO_INTR_DISABLE();
  376.         gpio_pin_intr_state_set(GPIO_ID_PIN(2),GPIO_PIN_INTR_NEGEDGE);
  377.         ETS_GPIO_INTR_ATTACH(GPIO_INTER,NULL);

  378.         ETS_GPIO_INTR_ENABLE();
  379. }

  380. void user_init(void)
  381. {
  382.         uart_init(115200, 115200);
  383. //        UART_SetPrintPort(UART1);

  384.         // 红外初始化
  385.         red_avoidance_init();
  386.         key_stop_gpio2_init();

  387.         motor_init();
  388.         motor_stop();
  389.         os_delay_us(600);
  390.         //Esp8266的I2c引脚接口初始化函数
  391.         i2c_master_gpio_init();

  392.         os_timer_disarm(&ShowdsTime);
  393.         os_timer_setfn(&ShowdsTime, TimeShow, NULL);
  394.         os_timer_arm(&ShowdsTime, 1000, 1);
  395.         //reload_at24c();        //加载闹钟数据
  396.         //设置SNTP服务器
  397.         sntp_setservername(0,"ntp.sjtu.edu.cn");
  398.     sntp_setservername(1,"s1a.time.edu.cn");
  399.     sntp_setservername(2,"2h.time.edu.c");
  400.     //延时3秒,待初始化完成
  401.         os_delay_us(80000);

  402.         //设置DS3231控制寄存器的CONV位为1,将温度强制转为数字码
  403.         ds3231_setConv(0x20);
  404.         OLED_Init();
  405.         OLED_Fill(0x00);

  406.         mqtt_Init();

  407. //        已经自动连接了wifi
  408.         if (wifi_station_get_connect_status() == STATION_GOT_IP)
  409.                 wifiConnectCb(STATION_GOT_IP);
  410.         else
  411.                 WIFI_Connect(ESSID, PASSWORD, wifiConnectCb);
  412. }

  413. uint32 ICACHE_FLASH_ATTR
  414. user_rf_cal_sector_set(void)
  415. {
  416.     enum flash_size_map size_map = system_get_flash_size_map();
  417.     uint32 rf_cal_sec = 0;

  418.     switch (size_map) {
  419.         case FLASH_SIZE_4M_MAP_256_256:
  420.             rf_cal_sec = 128 - 5;
  421.             break;

  422.         case FLASH_SIZE_8M_MAP_512_512:
  423.             rf_cal_sec = 256 - 5;
  424.             break;

  425.         case FLASH_SIZE_16M_MAP_512_512:
  426.         case FLASH_SIZE_16M_MAP_1024_1024:
  427.             rf_cal_sec = 512 - 5;
  428.             break;

  429.         case FLASH_SIZE_32M_MAP_512_512:
  430.         case FLASH_SIZE_32M_MAP_1024_1024:
  431.             rf_cal_sec = 1024 - 5;
  432.             

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

下载:
ESP8266_NONOS_SDK-ALL2.rar (16.96 MB, 下载次数: 62)

评分

参与人数 2黑币 +2 收起 理由
yetsky + 1 很给力!
simonliu009 + 1 很给力!

查看全部评分

回复

使用道具 举报

ID:177855 发表于 2017-6-30 17:43 | 显示全部楼层
好,下来学习。。。。。
回复

使用道具 举报

ID:184406 发表于 2018-7-26 23:07 | 显示全部楼层
这个不错,不过我更想弄一个不需要RTC模块的
回复

使用道具 举报

ID:393745 发表于 2018-9-4 21:45 | 显示全部楼层
好,下来学习。。。。。
回复

使用道具 举报

ID:141149 发表于 2019-3-3 20:20 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:582638 发表于 2019-7-11 22:29 | 显示全部楼层
supported
回复

使用道具 举报

ID:163049 发表于 2020-1-26 02:16 | 显示全部楼层
谢楼主
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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