#include "config.h"
#include
#include
float code degreesToRadians = 3.1416 /180.0000;
float code radiansToDegrees = 180.0000 /3.1416;
float code degreeMinutesToDecimal = 1.0000 /60.0000;
float code degreeSecondsToDecimal = 1.0000 /3600.0000;
sbit run=P0^0;
bit input_East,input_South;
float input_Longitude,input_Latitude,input_Elevation,input_Month,input_Date,input_Year,input_TimeZone;//原始需要数据
int chu,luo;//结果
u8 chu1,chu2,luo1,luo2;//结果转为小时、分钟
//角度计算用
float solarHourAngle,GHA,UT,inputHoursAfterMidnight,timeHours,timeMinutes,altitudeAngle,preAzimuthAngle,hourAngle,inputMinutesAfterMidnight,solarMinutesAfterMidnight;
//本地函数
float NormalizeTo360 (theThing) {
return (theThing - floor (theThing / 360.0) * 360);
}
float NormalizeTo180 (theThing) {
theThing = NormalizeTo360 (theThing);
if (theThing > 180) { theThing = theThing - 360; }
return (theThing);
}
void compute (void) {
float signedLongitude,signedLatitude,meridian,longitudeMeridianDifference,correctedYear,correctedMonth; //计算用转换数据
float t,G,C,L,alpha,obliquity,declination,eotAdjustment,clockTimeToLSOTAdjustment,sunRiseSetLSoTMinutes; //计算用中间数据
if (input_Latitude == 0) { input_Latitude = 0.000000001; }
if (input_Longitude == 0) { input_Longitude = 0.000000001; }
signedLongitude = input_Longitude;
if (input_East == 1) signedLongitude *= -1; // [1] = 东, [0] = 西
signedLatitude = input_Latitude;
if (input_South == 1) signedLatitude *= -1; // [0] = 北, [1] = 南
// 修复经度 > 180 deg
if (signedLongitude > 180) {
signedLongitude = signedLongitude - 360;
}
// 修复经度< -180 deg
if (signedLongitude < -180) {
signedLongitude = signedLongitude + 360;
}
// 当地标准时间子午线
meridian = input_TimeZone * -15;
// 如果太多与时区经度不同的警报
longitudeMeridianDifference = signedLongitude - meridian;
if ((longitudeMeridianDifference > 30) || (longitudeMeridianDifference < -30)) {
//alert ("所选择的时区与所在位置差距较大!");
}
// 计算通用时间
if (input_Month > 2) {
correctedYear = input_Year;
correctedMonth = input_Month - 3;
}
else {
correctedYear = input_Year - 1;
correctedMonth = input_Month + 9;
}
t = (input_Date + floor (30.6 * correctedMonth + 0.5) + floor (365.25 * (correctedYear - 1976)) - 8707.5) / 36525.0;
G = 357.528 + 35999.05 * t;
G = NormalizeTo360 (G);
C = (1.915 * sin (G * degreesToRadians)) + (0.020 * sin (2.0 * G * degreesToRadians));
L = 280.460 + (36000.770 * t) + C;
L = NormalizeTo360 (L);
alpha = L - 2.466 * sin (2.0 * L * degreesToRadians) + 0.053 * sin (4.0 * L * degreesToRadians);
obliquity = 23.4393 - 0.013 * t;
declination = atan (tan (obliquity * degreesToRadians) * sin (alpha * degreesToRadians)) * radiansToDegrees;
eotAdjustment = (L - C - alpha) / 15.0;
clockTimeToLSOTAdjustment = ((signedLongitude - meridian) / 15.0) - eotAdjustment; // 以小时为单位
sunRiseSetLSoTMinutes = radiansToDegrees * acos ( -1.0 * (sin (signedLatitude * degreesToRadians) * sin (declination * degreesToRadians) - sin ((-0.8333 - 0.0347 * sqrt (input_Elevation)) * degreesToRadians)) / cos (signedLatitude * degreesToRadians) / cos (declination * degreesToRadians)) * 4;
//日出时间
chu=12 * 60 - sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60);
//日落时间
luo=12 * 60 + sunRiseSetLSoTMinutes + (clockTimeToLSOTAdjustment * 60);
chu1=(int)chu/60;
chu2=(int)chu%60;
luo1=(int)luo / 60;
luo2=(int)luo % 60;
//以下用于计算太阳角度
inputHoursAfterMidnight=timeHours + timeMinutes / 60.0;
inputMinutesAfterMidnight = timeHours * 60.0 + timeMinutes;
solarMinutesAfterMidnight = inputMinutesAfterMidnight - (clockTimeToLSOTAdjustment * 60.0);
if (solarMinutesAfterMidnight < 0) {
solarMinutesAfterMidnight += 24 * 60;
}
if (solarMinutesAfterMidnight >= 24 * 60) {
solarMinutesAfterMidnight -= 24 * 60;
}
UT = inputHoursAfterMidnight - input_TimeZone;
GHA = UT * 15 - 180 - C + L - alpha;
GHA = NormalizeTo360 (GHA);
solarHourAngle = GHA - signedLongitude;
solarHourAngle = NormalizeTo180 (solarHourAngle);
//小时角数据 hourAngle
hourAngle = (solarMinutesAfterMidnight - (12 * 60)) / 4;
//计算偏差数据 declination
declination = atan (tan (obliquity * degreesToRadians) * sin (alpha * degreesToRadians)) * radiansToDegrees;
//高度角计算 altitudeAngle 水平为0
altitudeAngle = radiansToDegrees * asin ((sin (signedLatitude* degreesToRadians)*sin (declination*degreesToRadians)) -(cos (signedLatitude* degreesToRadians) *cos (declination* degreesToRadians)*cos ((solarHourAngle + 180) * degreesToRadians)));
//方位角计算 preAzimuthAngle 南为0
preAzimuthAngle = radiansToDegrees * acos ((cos (declination* degreesToRadians)*((cos (signedLatitude * degreesToRadians)*tan (declination* degreesToRadians))+(sin (signedLatitude * degreesToRadians)*cos ((solarHourAngle + 180)* degreesToRadians)))) /cos (altitudeAngle * degreesToRadians))-180;
if ((preAzimuthAngle * hourAngle) < 0) {
preAzimuthAngle *= -1;
}
}
void main (void) {
//日起日落提供的参数
input_Longitude=114.41; //经度
input_East=1;//东经1,西经0
input_Latitude=36.93;//维度
input_South=0;//北纬0,南纬1
input_Year=2017;
input_Month=1;
input_Date=1;
input_TimeZone=8; //时区参数
input_Elevation=0;//海拔
//太阳角度计算用参数
timeHours=0;
timeMinutes=50;
run=1;
run=0;
compute();
run=1;
run=0;
run=1;
run=0;
run=1;
run=0;
while(1){
run=0;
compute();
run=1;
}
}