您当前的位置: 首页 > 

仙剑情缘

暂无认证

  • 0浏览

    0关注

    333博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

仙剑情缘 发布时间:2021-10-17 16:34:58 ,浏览量:0

以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                  86400

typedef 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 
#include 
#include "rtc_module.h"

#define M_PI 3.1415926

#ifdef __cplusplus
extern "C" {
#endif

typedef 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(agM_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  sunrise_calc: ------> sunrise 06:18:30 00>  info> sunrise_calc: ------> sunset_time 18:04:52 00>  info> sunrise_calc: ------> midDayTime 12:11:41 00>  info> sunrise_calc: ------> dawnTime 05:56:01 00>  info> sunrise_calc: ------> darkness_time 18:27:22
                
关注
打赏
1658017818
查看更多评论
0.0441s