太阳高度角与方位角计算程序-stm32G070-ESP32 arduino- python(下)
1.太阳高度角与方位角计算程序-stm32G070-ESP32 arduino- python(下)
2.STM32G070串口接收GPS北斗模块数据3.调试串口通过USB串口接收GPS北斗模块数据和数据说明+ ESP32的 Arduino接收与解析GPRMC报文程序4.太阳高度角与方位角计算程序-stm32G070(上)按照UTC时间和经度、维度计算太阳高度度角、方位角等信息。
/* #纬度 latitude 北半球正 -90 ~ 90度 #经度 altitude 东半球正 -180 ~ 180度 #太阳真时 apparent_solar_time #太阳时角 solar_hour_angle -180~180度 #计算赤纬角 solar_declination_angle -23.45 ~ 23.45度 #计算高度角 solar_altitude_angle -90~90度 #太阳方位角 solar_azimuth_angle -180~ 180度 #太阳天顶角 solar_zenith_angle 0 -180度 #太阳升起时角solar_hour_angle_sunrise -180~0度 */ #ifndef __solar_position_algorithm_header #define __solar_position_algorithm_header #include "stm32g0xx_hal.h" typedef struct { //----------------------INPUT VALUES------------------------ int16_t year; //UTC输入: 4-digit year, valid range: 0 to 6000, error code: 1 int16_t month; //UTC输入: 2-digit month, valid range: 1 to 12, error code: 2 int16_t day; //UTC输入: 2-digit day, valid range: 1 to 31, error code: 3 int16_t hour; //UTC输入: Observer local hour, valid range: 0 to 24, error code: 4 int16_t minute; //UTC输入: Observer local minute, valid range: 0 to 59, error code: 5 int16_t second; //UTC输入: Observer local second, valid range: 0 to 59, error code: 6 int16_t timezone; //输入: 当地Observer time zone (negative west of Greenwich) // valid range: -18 to 18 hours, error code: 7 float longitude; // 输入:当地经度Observer longitude (negative west of Greenwich) // valid range: -180 to 180 degrees, error code: 8 float latitude; // 输入:当地纬度Observer latitude (negative south of equator) // valid range: -90 to 90 degrees, error code: 9 //---------------------OUTPUT VALUES------------------------ int16_t ndays; //UTC时间,从元旦(含)计,全年第几天 float mean_solar_time; //输出:当地平太阳时, 由hhmmss计算,单位 分钟 float error_time; //时差:当地真太阳时与平太阳时之差,单位 分钟 float apparent_solar_time; //输出:当地太阳真时 0-24,单位 分钟 float solar_hour_angle; //输出:当地太阳时角 -180~180度 float solar_declination_angle; //输出:当地赤纬角 -23.45 ~ 23.45度 float solar_altitude_angle; //输出:当地太阳高度角 -90~90度 float solar_azimuth_angle; //输出:当地太阳方位角 -180~ 180度 float solar_hour_angle_sunrise;//输出:当地升起时刻的太阳时角-180~0度 } spa_data; //Calculate SPA output values (in structure) based on input values passed in structure uint8_t sunpos_cal(spa_data *spa); // 根据日期算天数 uint8_t date2days_cal(spa_data *spa); // 根据天数算日期 uint8_t days2date_cal(spa_data *spa); // 输入和输出数据打印 void sunpos_print(spa_data *spa); #endif
#include <timeformat.h> #include <sunPosition.h> #include <math.h> #define PI 3.14159265f #include <rtthread.h> /* 打印结果使用 */ #include <string.h> #include <stdio.h> #include <stdlib.h> //字符串和数值间转换 //正数范围(3.402823466e+38F) //负数范围(1.175494351e-38F) // double的范围 //正数范围(1.7976931348623158e+308) //负数范围(2.2250738585072014e-308) // 计算 平太阳时 // INPUT: // Beijing_time 北京标准时间, 单位:分钟 // longitude_beijing 北京标准时间经度,单位:度 // longitude_location 当地时间经度,东半球正,单位:度 // latitude_locaiton 当地时间维度,北半球正,单位:度 // OUTPUT: 时差,单位:分钟 float mean_solar_time_cal(float Beijing_time,float longitude_beijing,float longitude_location,float latitude_locaiton) {/*计算设备所在地的平太阳时*/ float mean_solar_time; if(latitude_locaiton>=0) { mean_solar_time = Beijing_time - 4*(longitude_beijing-longitude_location); } else { mean_solar_time = Beijing_time + 4*(longitude_beijing-longitude_location); } return mean_solar_time; } // 不用北京时间,直接由UTC时间hhmmss计算当地平太阳时 // INPUT: // utc_minutes UTC标准时间,由当天的hhmmss计算得到 单位:分钟 // longitude_location 当地时间经度,东半球正,单位:度 // OUTPUT: 当地平太阳时,单位:分钟 float local_mean_solar_time_cal(float utc_minutes,float longitude_location) {/*计算设备所在地的平太阳时*/ float mean_solar_time; if(longitude_location>=0) { mean_solar_time = utc_minutes - 4*(0-longitude_location); } else { mean_solar_time = utc_minutes + 4*(0-longitude_location); } return mean_solar_time; } // 计算 平太阳时+ET=真太阳 // INPUT: 当年第几天,从元旦计,1~365 // OUTPUT: 时差,单位:分钟 float time_error(double nday) {/*计算设备所在地的平太阳时*/ float gama_big; float ET; gama_big = 2*PI*(nday-1)/365; ET = 0.01719f+0.428145f*cos(gama_big); ET=ET-7.3520484f*sin(gama_big); ET=ET-3.349758f*cos(gama_big*2); ET=ET-9.371988f*sin(gama_big*2); return ET; } // FUN: 计算真太阳时 单位:分钟 // INPUT: // mean_solar_time 单位:分钟 // error_time 单位:分钟 // OUTPUT: apparent_solar_time 单位:分钟 float apparent_solar_time_cal(const float mean_solar_time,const float error_time) {/*计算设备所在地的真太阳时*/ float apparent_solar_time; apparent_solar_time = mean_solar_time + error_time; return apparent_solar_time; } // FUN: 计算真太阳时 单位:分钟 // INPUT: // mean_solar_time 单位:分钟 // error_time 单位:分钟 // OUTPUT: apparent_solar_time 单位:分钟 float solar_hour_angle_cal(float apparent_solar_time) {/*计算设备所在地的时间角度*/ float temp; temp = (apparent_solar_time-12*60)*15.00f/60; return temp; } // FUN: 计算当天赤纬角度 // INPUT: nday 当年第几天,从元旦计,1~365 // OUTPUT: solar_declination_angle,单位:度 float solar_declination_angle_cal(float nday) {/*计算当天赤纬角度*/ double solar_declination_angle; solar_declination_angle = 23.45f *sin(2*PI*(284+nday)/365); return solar_declination_angle; } // FUN: 计算当天日升高度角度 // INPUT: // latitude 纬度 度 // solar_declination_angle 赤纬角 度 // OUTPUT: solar_declination_angle,单位:度 float solar_hour_angle_sunrise_cal(float latitude, float solar_declination_angle) {/*计算计算当天日升高度角度*/ float solar_hour_angle_sunrise; /*计算余弦值*/ solar_hour_angle_sunrise = sin(PI*latitude/180)*sin(PI*solar_declination_angle/180); solar_hour_angle_sunrise = solar_hour_angle_sunrise/( cos(PI*latitude/180)*cos(PI*solar_declination_angle/180) ); if(solar_hour_angle_sunrise>1)//#截断误差处理 solar_hour_angle_sunrise=1; if(solar_hour_angle_sunrise<-1)//#截断误差处理 solar_hour_angle_sunrise=-1; /*计算角度值*/ solar_hour_angle_sunrise = (-acos(-solar_hour_angle_sunrise)*180/PI); return solar_hour_angle_sunrise; } // FUN: 计算太阳高度角度 // INPUT: // latitude 当地纬度, 单位:度 // solar_declination_angle 当天赤纬角, 单位:度 // solar_hour_angle 当地太阳时角, 单位:度 // OUTPUT: solar_declination_angle,单位:度 float solar_altitude_angle_cal(float latitude,float solar_declination_angle,float solar_hour_angle) {/*计算太阳高度角度*/ float item1,item2; float total; float solar_altitude_angle; item1=sin(PI*latitude/180)*sin(PI*solar_declination_angle/180); item2=cos(PI*latitude/180)*cos(PI*solar_declination_angle/180)*cos(PI*solar_hour_angle/180); total = item1+item2; if(total<-1)//#截断误差处理 total=-1; if(total>1)//#截断误差处理 total=1; solar_altitude_angle=asin(total)*180/PI; return solar_altitude_angle; } // FUN: 计算太阳方位角度 // INPUT: // latitude 当地纬度, 单位:度 // solar_declination_angle 当天赤纬角, 单位:度 // solar_hour_angle 当地太阳时角, 单位:度 // solar_altitude_angle 当地太阳高度角, 单位:度 // OUTPUT: solar_declination_angle,单位:度 float solar_azimuth_angle_cal(float latitude,float solar_declination_angle,float solar_hour_angle,float solar_altitude_angle) {/*计算太阳方位角度*/ float sin_azimuth; float cos_azimuth; float azimuth; sin_azimuth = cos(solar_declination_angle*PI/180); sin_azimuth = sin_azimuth*sin(solar_hour_angle*PI/180); sin_azimuth = sin_azimuth/cos(solar_altitude_angle*PI/180); cos_azimuth = sin(solar_altitude_angle*PI/180); cos_azimuth = cos_azimuth*sin(latitude*PI/180); cos_azimuth = cos_azimuth-sin(solar_declination_angle*PI/180); cos_azimuth = cos_azimuth /cos(solar_altitude_angle*PI/180); cos_azimuth = cos_azimuth/cos(latitude*PI/180); if(cos_azimuth>1) cos_azimuth=1; if(cos_azimuth<-1) cos_azimuth=-1; if(sin_azimuth<=0) azimuth=-acos(cos_azimuth )*180/PI; if(sin_azimuth>0) azimuth= acos(cos_azimuth )*180/PI; return azimuth; } // 输入合法性检查 uint8_t validate_inputs(spa_data *spa) { if ((spa->year < -2000) || (spa->year > 6000)) return 1; if ((spa->month < 1 ) || (spa->month > 12 )) return 2; if ((spa->day < 1 ) || (spa->day > 31 )) return 3; if ((spa->hour < 0 ) || (spa->hour > 24 )) return 4; if ((spa->minute < 0 ) || (spa->minute > 59 )) return 5; if ((spa->second < 0 ) || (spa->second > 59 )) return 6; if ((spa->hour == 24 ) && (spa->minute > 0 )) return 5; if ((spa->hour == 24 ) && (spa->second > 0 )) return 6; if (( spa->timezone > 18 ) || (spa->timezone <- 18) ) return 8; if (( spa->longitude > 180 ) || (spa->longitude <- 180)) return 9; if (( spa->latitude > 180 ) || (spa->latitude <- 180)) return 10; return 0; } // 根据日期,算天数 uint8_t date2days_cal(spa_data *spa) { const uint8_t Leap_Year_month_days[] ={31,29,31,30,31,30,31,31,30,31,30,31}; const uint8_t Ordinary_Year_month_days[]={31,28,31,30,31,30,31,31,30,31,30,31}; uint8_t Is_Leap_Year; uint16_t index; uint16_t ndays; /*计算从元旦计,天数*/ Is_Leap_Year=IsLeapYear(spa->year);//判断是否为闰年 ndays =0; for(index=1;index< spa->month;index++) { if(Is_Leap_Year==1) ndays= ndays + Leap_Year_month_days[index-1]; else ndays= ndays + Ordinary_Year_month_days[index-1]; } spa->ndays=ndays; return 0; } // 根据天数算日期 uint8_t days2date_cal(spa_data *spa) { const uint8_t Leap_Year_month_days[] ={31,29,31,30,31,30,31,31,30,31,30,31}; const uint8_t Ordinary_Year_month_days[]={31,28,31,30,31,30,31,31,30,31,30,31}; uint8_t Is_Leap_Year; uint16_t index; uint16_t ndays; /*计算从元旦计,天数*/ Is_Leap_Year=IsLeapYear(spa->year);//判断是否为闰年 ndays=0; for(index=1;index<= 12;index++) { if(Is_Leap_Year==1) { if((ndays< spa->ndays)&&(spa->ndays <= ndays + Leap_Year_month_days[index-1])) { spa->month = index; spa->day = spa->ndays-ndays; break; } ndays = ndays+ Leap_Year_month_days[index-1]; } else { if((ndays< spa->ndays)&&(spa->ndays <= ndays + Ordinary_Year_month_days[index-1])) { spa->month = index; spa->day = spa->ndays-ndays; break; } ndays= ndays + Ordinary_Year_month_days[index-1]; } } return 0; } // 计算Sun Position // 2023-4-3日: 修改,由UTC计算太阳平时 uint8_t sunpos_cal(spa_data *spa) { uint8_t ret; int16_t local_ndays; float utc_minutes; ret =0; ret= validate_inputs(spa); if(ret!=0) return ret; /*由UTC时间计算当地当天平太阳时*/ utc_minutes = spa->hour*60+spa->minute + spa->second/60.0f; utc_minutes= local_mean_solar_time_cal(utc_minutes,spa->longitude); if(utc_minutes>1440)// 24h* 60m,day不同 { utc_minutes=utc_minutes-1440; local_ndays=spa->ndays +1; local_ndays = local_ndays %(365+1); } if(utc_minutes<0) // 24h* 60m,day不同 { utc_minutes=utc_minutes+1440;// 24h* 60m local_ndays=spa->ndays +354; // 周期内 减1 local_ndays = local_ndays %(365+1); } spa->mean_solar_time = utc_minutes; /*计算当天当地时差(真太阳时-平太阳时)*/ spa->error_time = time_error(local_ndays); /*计算当天当地真太阳时*/ spa->apparent_solar_time =apparent_solar_time_cal(spa->mean_solar_time,spa->error_time); /*计算当天当地太阳时角*/ spa->solar_hour_angle = solar_hour_angle_cal(spa->apparent_solar_time); /*计算当天当地赤纬角*/ spa->solar_declination_angle=solar_declination_angle_cal(local_ndays); /*计算当时当地高度角*/ spa->solar_altitude_angle = solar_altitude_angle_cal(spa->latitude,spa->solar_declination_angle,spa->solar_hour_angle); /*计算当时当地方位角*/ spa->solar_azimuth_angle =solar_azimuth_angle_cal(spa->latitude,spa->solar_declination_angle,spa->solar_hour_angle,spa->solar_altitude_angle); /*计算当天当地日升角*/ spa->solar_hour_angle_sunrise = solar_hour_angle_sunrise_cal(spa->latitude, spa->solar_declination_angle); return 0; } // 打印结果 // 2023-4-3日: 增加 void sunpos_print(spa_data *spa) { char msg[64]; rt_kprintf("太阳位置@ %s %s:%d\r\n",__FILE__, __FUNCTION__, __LINE__);//当前行所在文件名、函数名、第**行代码 rt_kprintf("UTC TIME: \r\n"); rt_kprintf("year %d ",spa->year); //UTC输入: 4-digit year, valid range: 0 to 6000, error code: 1 rt_kprintf("month %d ",spa->month); //UTC输入: 2-digit month, valid range: 1 to 12, error code: 2 rt_kprintf("day %d ",spa->day); //UTC输入: 2-digit day, valid range: 1 to 31, error code: 3 rt_kprintf("hour %d ",spa->hour); //UTC输入: Observer local hour, valid range: 0 to 24, error code: 4 rt_kprintf("minute %d ",spa->minute); //UTC输入: Observer local minute, valid range: 0 to 59, error code: 5 rt_kprintf("second %d ",spa->second); //UTC输入: Observer local second, valid range: 0 to 59, error code: 6 rt_kprintf("timezone %d ",spa->timezone); //输入: 当地Observer time zone (negative west of Greenwich) // valid range: -18 to 18 hours, error code: 7 rt_kprintf("\r\n LOCATION: \r\n"); sprintf(msg, "longitude %f ",spa->longitude);// 输入:当地经度Observer longitude (negative west of Greenwich) // valid range: -180 to 180 degrees, error code: 8 rt_kprintf("\r\n %s",msg); sprintf(msg, "latitude %f ",spa->latitude); // 输入:当地纬度Observer latitude (negative south of equator) // valid range: -90 to 90 degrees, error code: 9 rt_kprintf("\r\n %s",msg); //---------------------OUTPUT VALUES------------------------ rt_kprintf("\r\n ndays %d ",spa->ndays); //UTC时间,从元旦(含)计,全年第几天 sprintf(msg, "\r\n mean_solar_time %f ",spa->mean_solar_time); //输出:当地平太阳时, 由hhmmss计算,单位 分钟 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n error_time %f ",spa->error_time); //时差:当地真太阳时与平太阳时之差,单位 分钟 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n apparent_solar_time %f ",spa->apparent_solar_time); //输出:当地太阳真时 0-24,单位 分钟 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n solar_hour_angle %f ",spa->solar_hour_angle); //输出:当地太阳时角 -180~180度 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n solar_declination_angle %f ",spa->solar_declination_angle); //输出:当地赤纬角 -23.45 ~ 23.45度 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n solar_altitude_angle %f ",spa->solar_altitude_angle); //输出:当地太阳高度角 -90~90度 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n solar_azimuth_angle; %f ",spa->solar_azimuth_angle); //输出:当地太阳方位角 -180~ 180度 rt_kprintf("\r\n %s",msg); sprintf(msg, "\r\n solar_hour_angle_sunrise %f ",spa->solar_hour_angle_sunrise);//输出:当地升起时刻的太阳时角-180~0度 rt_kprintf("\r\n %s",msg); rt_kprintf("\r\n "); }
上述程序使用了自己编制的时间格式转换程序。如下:
#ifndef TIMEFORMAT_H #define TIMEFORMAT_H #include "stm32g0xx_hal.h" /*完成UTC与当地时间转换*/ typedef struct dateTime { uint32_t time;// BCD码 hhmmss(时分秒) uint32_t date;// BCD码 ddmmyy(日月年) } DateTime_Type; void UTC2Local(DateTime_Type *p_DateTime_Type,int32_t timeZone); void Local2UTC(DateTime_Type *p_DateTime_Type,int32_t timeZone); uint8_t Bcd2ToByte(uint8_t Value); uint8_t ByteToBcd2(uint8_t Value); uint32_t Date2Days( uint8_t year, uint8_t month, uint8_t day);//返回总天数 uint8_t Days2Date( int32_t days,uint8_t year, uint8_t* month, uint8_t* day); uint8_t IsLeapYear(int16_t year);// 判断是否为闰年 /*算例*/ // test_dateTime.time = 0x00042436;// BCD码 hhmmss(时分秒) // test_dateTime.date = 0x00010109;// BCD码 ddmmyy(日月年) // UTC2Local(&test_dateTime,-8); // Local2UTC(&test_dateTime,-8); #endif
#include <timeformat.h> /** * @brief Convert from 2 digit BCD to Binary. * @param Value BCD value to be converted * @retval Converted word */ uint8_t Bcd2ToByte(uint8_t Value) { uint32_t tmp; tmp = (((uint32_t)Value & 0xF0U) >> 4U) * 10U; return (uint8_t)(tmp + ((uint32_t)Value & 0x0FU)); } /** * @brief Convert from Binary to 2 digit BCD . * @param Value BCD value to be converted * @retval Converted word */ uint8_t ByteToBcd2(uint8_t Value) { uint16_t tmp1,tmp2; tmp1 =(uint16_t)Value; tmp2 = tmp1/10; tmp2 = tmp2<<4U; tmp2= tmp2&0x00F0; tmp1 = tmp1%10; return (uint8_t)( tmp1+tmp2); } /** * @brief IsLeapYear * @param year to be judged * @retval Is_Leap_Year */ // 判断是否为闰年 uint8_t IsLeapYear(int16_t year) { uint8_t Is_Leap_Year; Is_Leap_Year=0x00; if((year%4==0)&&(year%100 != 0)) Is_Leap_Year=0x01;//闰年 else { if(year%400==0) Is_Leap_Year=0x01;//闰年 } return Is_Leap_Year; } /** * @brief Date2Days * @param year, month,day 整数 * @retval days */ uint32_t Date2Days( uint8_t year, uint8_t month, uint8_t day) { const uint8_t Leap_Year_month_days[] ={31,29,31,30,31,30,31,31,30,31,30,31}; const uint8_t Ordinary_Year_month_days[]={31,28,31,30,31,30,31,31,30,31,30,31}; uint8_t Is_Leap_Year; uint32_t totalDays; uint8_t i; if((year<=0)||(year>100)) return 0; if((month<=0)||(month>12)) return 0; Is_Leap_Year = IsLeapYear(year); if(Is_Leap_Year==0x01){ if((day<=0)||(day>Leap_Year_month_days[month-1]) ) return 0; } else{ if((day<=0)||(day>Ordinary_Year_month_days[month-1])) return 0; } totalDays =0; for(i=0;i<month-1;i++) { if(Is_Leap_Year==0x01){ totalDays += Leap_Year_month_days[i]; } else{ totalDays += Ordinary_Year_month_days[i]; } } totalDays +=day; return totalDays; } /** * @brief Days2Date * @param days(不多于当年天数),year * @retval month,day 整数 */ uint8_t Days2Date( int32_t days,uint8_t year, uint8_t* month, uint8_t* day) { const uint8_t Leap_Year_month_days[] ={31,29,31,30,31,30,31,31,30,31,30,31}; const uint8_t Ordinary_Year_month_days[]={31,28,31,30,31,30,31,31,30,31,30,31}; uint8_t Is_Leap_Year; uint32_t totalDays; uint8_t i; if((year<=1)||(year>100)) return 1; Is_Leap_Year = IsLeapYear(year); if(Is_Leap_Year==0x01) { if( days >366){ return 2; } } else { if( days >365){ return 2; } } totalDays =0; for(i=0;i<12;i++){ if(Is_Leap_Year==0x01){ totalDays += Leap_Year_month_days[i]; if((days<=totalDays)&&( days+ Leap_Year_month_days[i]>totalDays ) ) { *month = i+1;//判断出当前月 break; } } else{ totalDays += Ordinary_Year_month_days[i]; if((days<=totalDays)&&( days+ Ordinary_Year_month_days[i]>totalDays ) ) { *month = i+1;//判断出当前月 break; } } } totalDays =0; for(i=0;i<*month-1;i++) { if(Is_Leap_Year==0x01){ totalDays += Leap_Year_month_days[i]; } else{ totalDays += Ordinary_Year_month_days[i]; } } *day = days- totalDays;// 计算出当月第几日 return 0; } /** * @brief Convert from UTC BCD to LOCAL. * @param time Zone, 东半球正 * @retval Converted word * uint32_t time;//GPS模块 BCD码 hhmmss(时分秒) * uint32_t date;//GPS模块 BCD码 ddmmyy(日月年) */ void UTC2Local(DateTime_Type *p_DateTime_Type,int32_t timeZone) { uint8_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; int32_t temp; int32_t totalMinutes; uint16_t totalDays; uint8_t Is_Leap_Year; temp = p_DateTime_Type->date%256; year = Bcd2ToByte(temp); temp = p_DateTime_Type->date/256; temp = temp%256; month = Bcd2ToByte(temp); temp = p_DateTime_Type->date/(256*256); temp = temp%256; day = Bcd2ToByte(temp); temp = p_DateTime_Type->time%256; second = Bcd2ToByte(temp); temp = p_DateTime_Type->time/256; temp = temp%256; minute = Bcd2ToByte(temp); temp = p_DateTime_Type->time/(256*256); temp = temp%256; hour = Bcd2ToByte(temp); totalDays = Date2Days( year, month, day); totalMinutes = (totalDays-1)*24*60; totalMinutes = totalMinutes+ hour*60 + minute; totalMinutes = totalMinutes + 4*15*timeZone;// 以分钟为单位,计算当地时间 if(totalMinutes < 0) { Is_Leap_Year= IsLeapYear( year-1); if(Is_Leap_Year==0x01){ totalMinutes = totalMinutes + 366*24*60; } else { totalMinutes = totalMinutes + 365*24*60; } year = year -1; goto next_UTC2Local; } if(totalMinutes > 0) { Is_Leap_Year= IsLeapYear( year); if(Is_Leap_Year==0x01){ if(totalMinutes> 366*24*60){ totalMinutes = totalMinutes - 366*24*60; year = year+1; } } else { if(totalMinutes> 365*24*60){ totalMinutes = totalMinutes - 365*24*60; year = year+1; } } } next_UTC2Local: totalDays = totalMinutes/(24*60)+1; totalMinutes = totalMinutes%(24*60); hour = totalMinutes/60; minute = totalMinutes%60; Days2Date( totalDays,year, &month, &day); year = ByteToBcd2(year); month = ByteToBcd2(month); day = ByteToBcd2(day); hour = ByteToBcd2(hour); minute= ByteToBcd2(minute); second= ByteToBcd2(second); p_DateTime_Type->date = year + (month<<8) + (day<<16);//GPS模块 BCD码 ddmmyy(日月年) p_DateTime_Type->time = (hour<<16) + (minute<<8) +second ;//GPS模块 BCD码 hhmmss(时分秒) } /** * @brief Convert from LOCAL to UTC. * @param timeZone, 东半球正 * @retval Converted word */ void Local2UTC(DateTime_Type *p_DateTime_Type,int32_t timeZone) { uint8_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; int32_t temp; int32_t totalMinutes; uint16_t totalDays; uint8_t Is_Leap_Year; temp = p_DateTime_Type->date%256; year = Bcd2ToByte(temp); temp = p_DateTime_Type->date/256; temp = temp%256; month = Bcd2ToByte(temp); temp = p_DateTime_Type->date/(256*256); temp = temp%256; day = Bcd2ToByte(temp); temp = p_DateTime_Type->time%256; second = Bcd2ToByte(temp); temp = p_DateTime_Type->time/256; temp = temp%256; minute = Bcd2ToByte(temp); temp = p_DateTime_Type->time/(256*256); temp = temp%256; hour = Bcd2ToByte(temp); totalDays = Date2Days( year, month, day); totalMinutes = (totalDays-1)*24*60; totalMinutes = totalMinutes+ hour*60 + minute; totalMinutes = totalMinutes - 4*15*timeZone;// 以分钟为单位,计算UTC时间 if(totalMinutes < 0) { Is_Leap_Year= IsLeapYear( year-1); if(Is_Leap_Year==0x01){ totalMinutes = totalMinutes + 366*24*60; } else { totalMinutes = totalMinutes + 365*24*60; } year = year -1; goto next_Local2UTC; } if(totalMinutes > 0) { Is_Leap_Year= IsLeapYear( year); if(Is_Leap_Year==0x01){ if(totalMinutes> 366*24*60){ totalMinutes = totalMinutes - 366*24*60; year = year+1; } } else { if(totalMinutes> 365*24*60){ totalMinutes = totalMinutes - 365*24*60; year = year+1; } } } next_Local2UTC: totalDays = totalMinutes/(24*60)+1; totalMinutes = totalMinutes%(24*60); hour = totalMinutes/60; minute = totalMinutes%60; Days2Date( totalDays,year, &month, &day); year = ByteToBcd2(year); month = ByteToBcd2(month); day = ByteToBcd2(day); hour = ByteToBcd2(hour); minute= ByteToBcd2(minute); second= ByteToBcd2(second); p_DateTime_Type->date = year + (month<<8) + (day<<16);//GPS模块 BCD码 ddmmyy(日月年) p_DateTime_Type->time = (hour<<16) + (minute<<8) + second ; //GPS模块 BCD码 hhmmss(时分秒) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)