找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6466|回复: 9
收起左侧

51单片机可否实现上下五千年农历计算(非查表法)

[复制链接]
ID:67796 发表于 2014-12-6 11:39 | 显示全部楼层 |阅读模式
本帖最后由 exv 于 2014-12-6 12:58 编辑

看了论坛中几个有农历的时钟程序,无一例外使用查表法实现的,且只能查上下100年(因为DS1302只有上下一百年)。

看过莆田第十中学许剑伟老师的农历算法,可实现上下五千年农历的计算(含节气),
与主函数直接相关的C代码就有6000余行;
关于日月星辰轨道计算的代码有数十组,
每一组换算往往涉及几十个64位double。

不知道51单片机在 合理 配置的情况下,能否实现这样的计算?

如果不行,实现这一功能的最低配置是?

许剑伟老师的代码这儿就不贴了(估计也贴不下),百度下 莆田第十中学许剑伟老师 即可。

51hei人才济济,下面这段计算圆周率的代码大家应该非常熟悉,古人几十本书还没说清的一两行就搞定了:
  1. long a=10000,b,c=2800,d,e,f[2801],g;
  2. void main(){for(;b-c;)f[b++]=a/5;for(;d=0,g=c*2;c-=14,cout<<e+d/a,e=d%a)for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}
复制代码


古人制农历最多也就是算盘,难道 51单片机 真敌不过古人算盘?

另外,许老师的日历程序除了可定农历日期/节气,还可依此结合设定的经纬度换算出每天的日落日出,非常实用。

回复

使用道具 举报

ID:67992 发表于 2014-12-6 12:25 来自手机 | 显示全部楼层
不会,太高深了。算盘结果可暂记纸上,记多少都可以,容量无限大,今天记不完明天接着记,速度可以无限慢。如果比这些,51单片机还真拍马莫及。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:67796 发表于 2014-12-6 12:45 | 显示全部楼层
dgahz 发表于 2014-12-6 12:25
不会,太高深了。算盘结果可暂记纸上,记多少都可以,容量无限大,今天记不完明天接着记,速度可以无限慢。 ...

程序本身并不高深,有高中水平即能看懂(不然 莆田第十中学的学生们可就悲催了),也就是些牛顿方程什么的。

只是这么大的计算量,放在RAM有限的51单片机确实是一个麻烦,也难怪目前能见到的都是查表法实现的。

不知如果借助一个2M的EEPROM能否解决这个问题?

评分

参与人数 1威望 +50 黑币 +50 收起 理由
admin + 50 + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:67992 发表于 2014-12-6 13:40 来自手机 | 显示全部楼层
农历是怎么算出来的我真搞不懂,和牛顿有关?印象中牛顿是力学吨
回复

使用道具 举报

ID:67992 发表于 2014-12-6 13:41 来自手机 | 显示全部楼层
出社会太久,知识都丢了。
回复

使用道具 举报

ID:69706 发表于 2014-12-6 16:31 | 显示全部楼层
应该是不管用吧
回复

使用道具 举报

ID:67796 发表于 2014-12-6 16:40 | 显示全部楼层
本帖最后由 exv 于 2014-12-6 16:46 编辑

还是贴一些莆田十中许老师的代码给大家温习下相关知识:

1.算出太阳/月亮/地球的位置(牛顿力学)
2.反算太阳月亮视黄经,相等时刻定月初一
3.根据各个月初一导出整个农历,节气可从太阳黄经直接导出。

许老师的代码虽然多,有相当部分是固定不变的天文/地理参数,包括一大堆校正因子集,故而前面的帖子提出使用EEPROM作存储辅助。

既然圆周率求算都能从几十本书变为两行代码,农历又是极为常用的东西,必定有非常多人去研究,一个简洁高效能在单片机上运行的代码应该是已经有人写出过的。

下面代码是通过地球轨道方程反算太阳黄经,从而计算出各个节气。
(51hei只见到一个历法程序有节气,只是人家没给代码,不知道是不是用下面方法算出的)


  1. double qi_low(double W)
  2. {
  3.         //最大误差小于30分钟,平均5分
  4.         double t,L,v= 628.3319653318;
  5.         t =  ( W - 4.895062166 )/v; //第一次估算,误差2天以内
  6.         t -= ( 53*t*t + 334116*cos( 4.67+628.307585*t) + 2061*cos( 2.678+628.3076*t)*t )/v/10000000; //第二次估算,误差2小时以内
  7.         
  8.         L = 48950621.66 + 6283319653.318*t + 53*t*t //平黄经
  9.                 +334166 * cos( 4.669257+  628.307585*t) //地球椭圆轨道级数展开
  10.                 +3489 * cos( 4.6261  + 1256.61517*t ) //地球椭圆轨道级数展开
  11.                 +2060.6 * cos( 2.67823 +  628.307585*t ) * t  //一次泊松项
  12.                 - 994 - 834*sin(2.1824-33.75705*t); //光行差与章动修正
  13.         
  14.         t -= (L/10000000 -W )/628.332 + (32*(t+1.8)*(t+1.8)-20)/86400/36525;
  15.         return t*36525 + (double)8/24;
  16. }
复制代码


评分

参与人数 1威望 +50 黑币 +50 收起 理由
admin + 50 + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:74921 发表于 2015-3-20 11:26 | 显示全部楼层
好高深的有没有?反正我是看迷糊了
回复

使用道具 举报

ID:67796 发表于 2015-3-20 17:48 | 显示全部楼层
a719563181 发表于 2015-3-20 11:26
好高深的有没有?反正我是看迷糊了

其实,是有的问题被复杂化了。

农历本来是用来指导一年的农时,大多数时候也不需要精确到分秒。
如同买鞋子的时候最多用皮尺之类的工具量量尺寸,没人会去用游标卡尺。

这一步
1.算出太阳/月亮/地球的位置(牛顿力学)

为了得到精确的值,使用近代天文学算法(多体),耗费了大量计算资源。
现代算法是从《史记历书》演化而来,只是司马迁直接把太阳月亮假设为匀速圆周运动,通过这样一个近似,计算量极大减小,所得的历法也满足指导农时之用。

当然,现代算法也是一种学问上的严谨。日月食的时间能精确到秒(参看许老师代码)。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:199295 发表于 2017-5-11 11:01 | 显示全部楼层
很好的资料
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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