以NRF52 MCU平台实现,先实现UTC及要本时间等转换函数

#ifndef __RTC_MODULE_H__
#define __RTC_MODULE_H__
#include "time.h"
#include "stdbool.h"
#include "stdint.h"
#include "sdk_config.h"
#include "nrf_atomic.h"#pragma anon_unions#ifdef __cplusplus
extern "C" {#endif#define INIT_UTC                     (1609502400)
#define ONE_DAY_UTC                  86400typedef struct{int tm_sec;   /* seconds after the minute, 0 to 60(0 - 60 allows for the occasional leap second) */int tm_min;   /* minutes after the hour, 0 to 59 */int tm_hour;  /* hours since midnight, 0 to 23 */int tm_mday;  /* day of the month, 1 to 31 */int tm_mon;   /* months since January, 0 to 11 */int tm_year;  /* years since 1900 */int tm_wday;  /* days since Sunday, 0 to 6 */int tm_yday;  /* days since January 1, 0 to 365 */int tm_isdst; /* Daylight Savings Time flag */union {       /* ABI-required extra fields, in a variety of types */struct {int __extra_1, __extra_2;};struct {long __extra_1_long, __extra_2_long;};struct {char *__extra_1_cptr, *__extra_2_cptr;};struct {void *__extra_1_vptr, *__extra_2_vptr;};};
}rtc_time_t;extern int8_t time_zone;
extern uint8_t g_sync_utc_flag;uint32_t utc_inc_one(void);
uint32_t rtcm_get_sys_utc(void);
void rtcm_set_sys_utc(uint32_t tmp_utc);
void rtcm_read_sys_time(rtc_time_t *tmp_rtc);
void rtcm_secs_to_date_time(uint32_t t, rtc_time_t *p_time);
void utc_to_local_time(uint32_t utc,rtc_time_t *pTime);
void local_time_to_utc(uint32_t *utc,rtc_time_t *pTime);#ifdef __cplusplus
}
#endif#endif

#include "rtc_module.h"
#include "main.h"
#include "nrfx.h"/***********************************************************************
*                               macro define
************************************************************************
*/#define NRF_LOG_MODULE_NAME rtc_module
#if ANT_HRM_LOG_ENABLED
#define NRF_LOG_LEVEL       3
#define NRF_LOG_INFO_COLOR  3
#else // ANT_HRM_LOG_ENABLED
#define NRF_LOG_LEVEL       0
#endif // ANT_HRM_LOG_ENABLED
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();uint8_t g_sync_utc_flag;
int8_t time_zone = 8;        // 时区static nrf_atomic_u32_t sys_utc = INIT_UTC;/*************************************************************************
**  function name:  rtcm_get_sys_utc
**  description:    get the system utc
**  input para:
**
**  return:         return the system utc
**************************************************************************/
uint32_t rtcm_get_sys_utc(void)
{uint32_t utc = nrf_atomic_u32_fetch_or(&sys_utc,0);return utc;
}
/**
* @brieaf utc原子操作加1
*/
uint32_t utc_inc_one(void)
{return nrf_atomic_u32_add(&sys_utc,1);
}
/*************************************************************************
**  function name:  rtcm_set_sys_utc
**  description:    set the system utc
**  input para:
**
**  return:
**************************************************************************/
void rtcm_set_sys_utc(uint32_t tmp_utc)
{ uint32_t utc = nrf_atomic_u32_store(&sys_utc,tmp_utc);NRF_LOG_INFO("=========Set_time=%d",sys_utc);
}
/*************************************************************************
**  function name:  rtcm_read_sys_time
**  description:    read the system rtc
**  input para:     tmp_rtc--the rtc you want to read
**
**  return:
**************************************************************************/
void rtcm_read_sys_time(rtc_time_t *tmp_rtc)
{//rtc_secs_to_date_time(sys_utc+(u32_t)8*3600, tmp_rtc);uint32_t utc = nrf_atomic_u32_fetch_or(&sys_utc,0);  utc_to_local_time(utc, tmp_rtc);
}/**
* @brieaf 本地时间转UTC
*/
void local_time_to_utc(uint32_t *utc,rtc_time_t *pTime)
{struct tm p;    memcpy(&p,pTime,sizeof(struct tm));p.tm_year -= 1900;p.tm_mon -= 1;*utc =mktime(&p);
}/**
* @brieaf utc转本地时间
*/
void utc_to_local_time(uint32_t utc,rtc_time_t *pTime)
{struct tm *p;  p = localtime(&utc); p->tm_year += 1900;p->tm_mon++;memcpy(pTime,p,sizeof(struct tm));
}

计算日出日落相关函数

#ifndef __BSP_SUNRISE_CALC_H
#define __BSP_SUNRISE_CALC_H
#include <math.h>
#include <stdio.h>
#include "rtc_module.h"#define M_PI 3.1415926#ifdef __cplusplus
extern "C" {#endiftypedef struct TAG_SUNRISE
{double sunrise_time;   // 日出double sunset_time;    // 日落double midDayTime;  //中天时间double dawnTime;   //天亮时间double darkness_time;   //天黑时间
}SUNRISE_TIME_T;void calc_sunrise_info(uint32_t utc,double lo,double la,int32_t zone);/*** @brieaf 获取日出时间*/void get_sunrise_string(char *timestr);/*** @brieaf 获取日落时间*/void get_sunset_string(char *timestr);/*** @brieaf 获取中天时间*/void get_midDayTime_string(char *timestr);/*** @brieaf 获取天亮时间*/void get_dawnTime_string(char *timestr);/*** @brieaf 获取天黑时间*/void get_darkness_time_string(char *timestr);#ifdef __cplusplus
}
#endif#endif
#include "BSP_sunrise_calc.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"#define NRF_LOG_MODULE_NAME sunrise_calc
#define NRF_LOG_LEVEL       3
#define NRF_LOG_INFO_COLOR  4
#define NRF_LOG_DEBUG_COLOR 3
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();static double RAD = 180.0 * 3600 /M_PI;static SUNRISE_TIME_T s_sun_time;/************************** 儒略日的计算** @param y 年** @param M 月** @param d 日** @param h 小时** @param m 分** @param s秒** @return int
***************************/
static double timeToDouble(int y, int M, double d)
{//        double A=0;double B=0;double jd=0;//设Y为给定年份,M为月份,D为该月日期(可以带小数)。//若M > 2,Y和M不变,若 M =1或2,以Y–1代Y,以M+12代M,换句话说,如果日期在1月或2月,则被看作是在前一年的13月或14月。//对格里高利历有 :A = INT(Y/100)   B = 2 - A + INT(A/4)//对儒略历,取 B = 0//JD = INT(365.25(Y+4716))+INT(30.6001(M+1))+D+B-1524.5 (7.1)B=-13;jd=floor(365.25 * (y + 4716))+ floor(30.60001 * (M + 1)) +B+ d- 1524.5;return jd;}/***************************** @param t 儒略世纪数** @return 太阳黄经
*****************************/
static double sunHJ(double t)
{double j;t = t + (32.0 * (t + 1.8) * (t + 1.8) - 20) / 86400.0 / 36525.0;// 儒略世纪年数,力学时j = 48950621.66 + 6283319653.318 * t + 53 * t * t - 994 + 334166 *cos(4.669257 + 628.307585 * t) + 3489 * cos(4.6261 + 1256.61517 * t) + 2060.6 * cos(2.67823 + 628.307585 * t) * t;return (j / 10000000);
}static double mod(double num1, double num2)
{num2 = fabs(num2);// 只是取决于Num1的符号return num1 >= 0 ?(num1 - (floor(num1 / num2)) * num2 ): ((floor(fabs(num1) / num2)) * num2 - fabs(num1));
}
/********************************* 保证角度∈(-π,π)** @param ag* @return ag
***********************************/
static double degree(double ag)
{ag = mod(ag, 2 * M_PI);if(ag<=-M_PI){ag=ag+2*M_PI;}else if(ag>M_PI){ag=ag-2*M_PI;}return ag;
}/************************************* @param date  儒略日平午** @param lo    地理经度** @param la    地理纬度** @param tz    时区** @return 太阳升起时间
*************************************/static double sunRiseTime(double date, double lo, double la, double tz){double t,j,sinJ,cosJ,gst,E,a,D,cosH0,cosH1,H0,H1,H;date = date - tz;// 太阳黄经以及它的正余弦值t = date / 36525;j = sunHJ(t);// 太阳黄经以及它的正余弦值sinJ = sin(j);cosJ = cos(j);// 其中2*M_PI*(0.7790572732640 + 1.00273781191135448*jd)恒星时(子午圈位置)gst = 2 * M_PI * (0.779057273264 + 1.00273781191135 * date) + (0.014506 + 4612.15739966 * t + 1.39667721 * t * t) / RAD;E = (84381.406 - 46.836769 * t) / RAD; // 黄赤交角a = atan2(sinJ * cos(E), cosJ);// '太阳赤经D = asin(sin(E) * sinJ); // 太阳赤纬cosH0 = (sin(-50 * 60 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); // 日出的时角计算,地平线下50分cosH1 = (sin(-6 * 3600 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); // 天亮的时角计算,地平线下6度,若为航海请改为地平线下12度// 严格应当区分极昼极夜,本程序不算if (cosH0 >= 1 || cosH0 <= -1){return -0.5;// 极昼}H0 = -acos(cosH0); // 升点时角(日出)若去掉负号 就是降点时角,也可以利用中天和升点计算H1 = -acos(cosH1);H = gst - lo - a; // 太阳时角s_sun_time.midDayTime = date - degree(H) / M_PI / 2 + tz; // 中天时间s_sun_time.dawnTime = date - degree(H - H1) / M_PI / 2 + tz;// 天亮时间return date - degree(H - H0) / M_PI / 2 + tz; // 日出时间,函数返回值
}static void doubleToStr(double time,char *str)
{double t;int h,m,s;t = time + 0.5;t = (t - (int) t) * 24;h = (int) t;t = (t - h) * 60;m = (int) t;t = (t - m) * 60;s = (int) t;sprintf(str,"%02d:%02d:%02d",h,m,s);
}//########################################################################################################################/**
* @brieaf 计算日落,日出,中天,天亮,天黑时间
* @param[in] utc - 当前时间utc
* @param[in] lo -  经度
* @param[in] la - 纬度
* @param[in] zone - 时区
*/void calc_sunrise_info(uint32_t utc,double lo,double la,int32_t zone){rtc_time_t time;utc_to_local_time(utc,&time);double jd = -lo/180*M_PI;double wd = la/180*M_PI;  double richu = timeToDouble(time.tm_year,time.tm_mon,time.tm_mday) - 2451544.5;for (uint32_t i = 0; i < 10; i++){richu = sunRiseTime(richu, jd, wd, zone/24.0);// 逐步逼近法算10次}s_sun_time.sunrise_time = richu;s_sun_time.sunset_time = s_sun_time.midDayTime + s_sun_time.midDayTime - richu;s_sun_time.darkness_time = s_sun_time.midDayTime + s_sun_time.midDayTime-s_sun_time.dawnTime;}/*** @brieaf 获取日出时间*/void get_sunrise_string(char *timestr){doubleToStr(s_sun_time.sunrise_time,timestr);NRF_LOG_INFO("------> sunrise %s",timestr);}/*** @brieaf 获取日落时间*/void get_sunset_string(char *timestr){doubleToStr(s_sun_time.sunset_time,timestr);NRF_LOG_INFO("------> sunset_time %s",timestr);}/*** @brieaf 获取中天时间*/void get_midDayTime_string(char *timestr){doubleToStr(s_sun_time.midDayTime,timestr);NRF_LOG_INFO("------> midDayTime %s",timestr);}/*** @brieaf 获取天亮时间*/void get_dawnTime_string(char *timestr){doubleToStr(s_sun_time.dawnTime,timestr);NRF_LOG_INFO("------> dawnTime %s",timestr);}/*** @brieaf 获取天黑时间*/void get_darkness_time_string(char *timestr){doubleToStr(s_sun_time.darkness_time,timestr);NRF_LOG_INFO("------> darkness_time %s",timestr);}

调用calc_sunrise_info函数计算

calc_sunrise_info(1633750052,113.9167f,22.6446,8);
  • 调用获取结果函数
  char buf[40];get_sunrise_string(buf);get_sunset_string(buf);get_midDayTime_string(buf);get_dawnTime_string(buf);get_darkness_time_string(buf);
  • 运行结果
    <00> info> sunrise_calc: ------> sunrise 06:18:30
    00>
    <00> info> sunrise_calc: ------> sunset_time 18:04:52
    00>
    <00> info> sunrise_calc: ------> midDayTime 12:11:41
    00>
    <00> info> sunrise_calc: ------> dawnTime 05:56:01
    00>
    <00> info> sunrise_calc: ------> darkness_time 18:27:22

基于GPS经纬度和当地时间计算日落日出时间实现相关推荐

  1. 计算日落日出时间算法与代码

    算法: 怎样用经纬度计算日出日落的时间 下面是一种随经纬度变化的日出日落时间计算方法,我成功运用在一智能路灯控制器中,希望对需要的朋友有帮助. 已知:日出日落时太阳的位置h=-0.833°,要计算地的 ...

  2. C语言 根据经纬度如何获取日落日出时间

    代码参考 利用日期.经纬度求日出日落时间 C语言程序代码_百度知道 源代码有几次错误,已经改成可以使用的C版本,计算结果和查询网站的结果会有1分钟左右的误差. 测试网站地址日出日落时间查询 - 国旗标 ...

  3. 基于GPS与经纬度距离计算

    基于GPS与经纬度距离计算 # -*- coding:utf-8 -*- # /usr/bin/pythonimport warnings warnings.filterwarnings(" ...

  4. mysql 计算gps坐标距离_mysql、sqlserver和php计算GPS经纬度坐标距离

    摘要:mysql.sqlserver.oracle和php计算GPS经纬度坐标距离 mysql计算GPS经纬度距离DELIMITER $$ CREATEDEFINER=`root`@`localhos ...

  5. APP Inventor中如何利用GPS经纬度计算GPS距离、速度、方向

         最近有空时研究了一下MIT APP InVentor,这是一个原来google验室的项目,目的是为了给Andriod APP的开发者提供一种简便快捷的开发模式,但后来该项目被停止,2012年 ...

  6. Swift - 计算运动距离的功能实现(分别基于GPS、计步器)

    一.基本介绍 有时我们需要计算从 A 点移动到 B 点的距离,或者开发一个计算跑步公里数的 APP.即点击开始统计后,可以实时计算出跑过的路程长度.这个功能通常有两种实现方法:一种是基于 GPS 定位 ...

  7. 基于GPS的嵌入式公交自动报站系统的研究

    基于GPS的嵌入式公交自动报站系统的研究 时间:2009-08-15 01:54:48  来源:   前,国内各大城市的无人售票公交车大都采用半自动报站系统,即通过人工干预语音信箱进行语音报站,和传统 ...

  8. 基于GPS/北斗卫星技术的无盲区车辆调度系统

    基于GPS/北斗卫星技术的无盲区车辆调度系统 现代车辆调度系统是一种集全球卫星定位技术(GPS).地理信息技术(GIS)和现代通信技术于一体的高科技项目.它将移动目标的动态位置(经度与纬度).时间和状 ...

  9. 5G NR — 基于 GPS 的时间同步

    目录 文章目录 目录 基于 GPS 的同步 基于 GPS 的同步 在 3G.4G 蜂窝网络中,卫星接收机嵌入在 NodeB.BBU 中.这些控制器利用一天中的时间信息,通过无线电波传送到 UE.并获取 ...

最新文章

  1. 区块链行业报告|从交易流程到Token经济的全方位解析
  2. ant编辑java忽略注释_java – Ant警告:隐式编译的文件不受注释处理
  3. Linux下GCC的安装,GCC链接外部库
  4. RocketMQ消息重试机制
  5. 正则表达式30分钟入门教程(转)
  6. B端SaaS产品工作流程
  7. C语言课后习题(14)
  8. 表空间(tableSpace) 段(segment) 盘区(extent) 块(block) 关系
  9. 一个API方式存取日志文件的模块[VB]
  10. linux下输入法安装设置及中文字体安装
  11. 在C#中IEnumerable与IEnumerator
  12. JavaWeb POI 导出Excel
  13. json日期格式转换为正常格式
  14. 激光导航AGV的停车精度受环境变化的影响有多大?
  15. 第三次个人作业——关于K米(Andorid)的案例分析
  16. java 案例(售卖橙子)
  17. 太强了!!!GNN + PLM→CIKM'22最佳论文
  18. 阜阳有儿童计算机编程吗,终于明白儿童有必要学编程吗
  19. 常用 XSS Payload
  20. 阿里云AMD服务器ECS计算型c6a实例CPU网络性能评测

热门文章

  1. C语言中,1U<<29的意思
  2. 19 个强大、有趣、又好玩的 Linux 命令!
  3. 精美图标大全_40个精美表情符号和笑脸图标包
  4. Bootstrap栅格布局
  5. JS和CSS的引入/写入位置应该放在哪里?
  6. 如何布置环境?自己这边打版了,后台怎么打版才能创建活动?
  7. python期货程序化交易高手心得_11位顶级高手谈期货心得
  8. mansory自适应label高度
  9. [GridView]解决js-xlsx导出Excel时数字太长变为科学计数的问题
  10. 【机房收费系统】日、周结账单