打印

新鲜出炉的百年RTC 呵呵

[复制链接]
3921|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
耕在此行|  楼主 | 2009-4-17 10:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
先说明下:
  1.单片机为MSP430F147
  2.使用定时中断,定时器时钟为ACLK,1s中断一次。
  3.使用了一个常数数组与一个变量数组来确定一月有多少天。内存有点费。
    年、日、时、分、秒采用BCD码,以便通讯输出。
  4.月因需与数组序号对应,所以为16进制码。通讯时需转换。

  第3条改了下:使用了一个常数数组与一个变量数组来确定一月有多少天
           改为使用了一个常数数组与一个变量来确定一月有多少天
  原来的处理方法空间与时间上都比较浪费。
  上午编完后总觉得不满意,呵呵 现在应该没什么不好的了。
void timer(void)
  {
  T.sec++;
  if( (T.sec & 0x0f) > 9)
    {
    T.sec += 6; //T.sec = (T.sec & 0xf0) + 0x10; 04.21改
    }
  if( T.sec > 0x59 )
    {
    T.sec = 0;
    T.min++;
    if( (T.min & 0x0f) > 9)
      {
      T.min += 6;//T.min = (T.min & 0xf0) + 0x10;04.21改
      }
    if( T.min > 0x59 )
      {
      T.min = 0;
      T.hour++;
      if( (T.hour & 0x0f) > 9)
        {
        T.hour += 6;//T.hour = (T.hour & 0xf0) + 0x10;04.21改
        }
      if( T.hour > 0x23 )
        {
        T.hour = 0;
        T.date++;
        if( (T.date & 0x0f) > 9)
          {
          T.date += 6;//T.date = (T.date & 0xf0) + 0x10;04.21改
          }
        if( T.date > date_num )//原为if( T.date > date_num[month] )
          {
          T.date = 1;
          T.month++;
          date_num = Date_Num[T.month];//原为date_num[T.month] = Date_Num[T.month];
          if( (T.month == 1) && ((T.year<<6) ==0) )//第2月
            {
            date_num = 0x29;//原为date_num[T.month] = 0x29;
            }
          if( T.month > 11 )
            {
            T.month = 0;
            T.year++;
            if( (T.year & 0x0f) > 9)
              {
              T.year += 6;//T.year = (T.year & 0xf0) + 0x10;04.21改
              }
            }
          }
        }
      }
    }
  }
里面有一个严重的错误,呵呵

相关帖子

沙发
古道热肠| | 2009-4-17 11:34 | 只看该作者

我还以为楼主整出阴历来了,阳历很Easy

使用特权

评论回复
板凳
耕在此行|  楼主 | 2009-4-17 13:31 | 只看该作者

呵呵 阴历很难吗?

使用特权

评论回复
地板
john_light| | 2009-4-17 17:32 | 只看该作者

农历不查表的我是没见过

使用特权

评论回复
5
耕在此行|  楼主 | 2009-4-17 19:17 | 只看该作者

阴历计算(百度来的)

历法转换
  一、节气的计算 
  先给节气进行编号,从近日点开始的第一个节气编为0,编号如下及其相应的月份如下: 
  0 小寒 腊月 6 清明 三月 12 小暑 六月 18 寒露 九月
  1 大寒 腊月 7 谷雨 三月 13 大暑 六月 19 霜降 九月
  2 立春 正月 8 立夏 四月 14 立秋 七月 20 立冬 十月
  3 雨水 正月 9 小满 四月 15 处暑 七月 21 小雪 十月
  4 惊蛰 二月 10 芒种 五月 16 白露 八月 22 大雪 冬月
  5 春分 二月 11 夏至 五月 17 秋分 八月 23 冬至 冬月
  把当天和1900年1月0日(星期日)的差称为积日,那么第y年(1900年算第0年)第x 个节气的积日是 
  F = 365.242 * y + 6.2 + 15.22 * x - 1.9 * sin(0.262 * x) 
  这个公式的误差在0.05天左右。 
  二、朔日的计算 
  从1900年开始的第m个朔日的公式是 
  M = 1.6 + 29.5306 * m + 0.4 * sin(1 - 0.45058 * m) 
  这个公式的误差在0.2天左右。 
  三、年份的确定 
  1864年1月0日是农历癸亥年,所以用当年减去1864,用10除得的余数作为年份天干的,用12除得的余数作为年份的地支,数字对应的天干和地支如下。 
  数字 0 1 2 3 4 5 6 7 8 9 10 11
  天干 甲 乙 丙 丁 戊 己 庚 辛 壬 癸
  地支 子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥 
  当年的1月0日换算为积日,可以用年份减去1900得到的年数被4整除,所得商数作为 y(D4),余数作为y(M4),y(M4)为零的年份是公历闰年,积日是 
  D(1) = 1461 * y(D4) - 1 
  y(M4)不为零的年份是公历平年,积日是 
  D(1) = 1461 * y(D4) + 365 * y(M4) 
  四、月份的确定 
  计算前一年冬至的积日F(0),并用F(0)计算冬至所在的朔月m及其朔日M(0),就可以推算冬至的农历日期,冬至所在的农历月份总是十一月。计算下一个中气F(1)和下一个朔日M(1),如果F(1)<M(1),那么该月就是上一个月的闰月,并把这个中气作为F(2),以后的中气、朔日和农历月份也这样确定。

使用特权

评论回复
6
hotpower| | 2009-4-18 16:13 | 只看该作者

干支纪年

干支纪年
  [解释]中国古代的一种纪年法。即以甲、乙、丙、丁、戊、己、庚、辛、壬、癸为十干,子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥为十二支,把干、支顺序配合。如甲子、乙丑等,经过六十年又回到甲子。周而复始,循环不已。我国农历现仍沿用干支纪年。
  干支纪年萌芽于西汉,始行于王莽,通行于东汉后期。汉章帝元和二年(公元85年),朝廷下令在全国推行干支纪年。有人认为中国在汉武帝以前用干支纪年。可是,这就是太岁纪年,用太岁所在纪年,干支表示十二辰(把黄道附一周天分为十二等分)。木星11.862年绕天一周,所以太岁约86年多走过一辰,这叫做“超辰”。在颛顼历上,西汉武帝太初元年(前104年)是太岁在丙子,太初历用超辰法改变为丁丑。汉成帝末年,由刘歆重新编订的三统历又把太初元年改变为丙子,把太始二年(前95年)从乙酉改变为丙戌。还东汉的历学者没用超辰法。所以太岁纪年和干支纪年从太始二年表面一样。
  1.干和支的含义:干支是天干,地支的合称。 
  干指天干,共有10个符号: 
  1 2 3 4 5 6 7 8 9 10 
  甲 乙 丙 丁 戊 己 庚 辛 壬 癸 
  支指地支,共有12个符号: 
  1 2 3 4 5 6 7 8 9 10 11 12 
  子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥 
  2.干和支组合后用于纪年。即:将十天干和十二地支按顺序搭配组合成干支,用于纪年。按此排法,当天干10个符号排了六轮与地支12个符号排了五轮以后,可构成60干支。续排下去又将恢复原状,周而复始,即如民间所说“六十年转甲子”。 
  二.查看不同时间段的万年历。如:1516—2060年的万年历,记着五百年的干支,一查便知。 
  六十年甲子(干支表)
  1 2 3 4 5 6 7 8 9 10
  甲子 乙丑 丙寅 丁卯 戊辰 己巳 庚午 辛未 壬申 癸酉
  11 12 13 14 15 16 17 18 19 20
  甲戌 乙亥 丙子 丁丑 戊寅 己卯 庚辰 辛己 壬午 癸未
  21 22 23 24 25 26 27 28 29 30
  甲申 乙酉 丙戌 丁亥 戊子 己丑 庚寅 辛卯 壬辰 癸巳
  31 32 33 34 35 36 37 38 39 40
  甲午 乙未 丙申 丁酉 戊戌 己亥 庚子 辛丑 壬寅 癸卯
  41 42 43 44 45 46 47 48 49 50
  甲辰 乙巳 丙午 丁未 戊申 己酉 庚戌 辛亥 壬子 癸丑
  51 52 53 54 55 56 57 58 59 60
  甲寅 乙卯 丙辰 丁巳 戊午 己未 庚申 辛酉 壬戌 癸亥
  根据“六十年甲子(干支表)”的公元年对应进行向上或朝下地反推。如:《辛亥革命》的辛亥年是1911年(48号干支),《戊戌变法》的戊戌年为35号干支,比辛亥年早13年,则“1911-13=1898”故《戊戌变法》是1898年。 
  应用公元年进行计算。应用公元年的某一年,除以60(指六十年甲子),余数小于60,再用余数减去3(干支纪年是从公元4年开始使用的),便知。 
  如2002年:2002÷60,余数为22,再22-3,得数是19,查六十年甲子(干支表)19号干支,得知是壬午年。 
  三.结合实际了解“十二地支” 
  1.用十二种动物分别与十二地支相配成为“十二生肖年”。(见下图)如凡是含有“子”的干支年,就是“鼠年”,这一年里出生的人都是属“鼠”;凡是含有“丑”的干支年就是“牛年”,这一年进而出生的人都是属“牛”。以此类推。(如下表) 
  十二生肖年 
  1 2 3 4 5 6 7 8 9 10 11 12 
  子鼠 丑牛 寅虎 卯兔 辰龙 巳蛇 午马 未羊 申猴 酉** 戌狗 亥猪 
  2. 以十二地支来表示十二时辰。 
  一日有二十四小时,而我国传统则以十二个时辰来表示,即一时辰是二小时。(如下表) 
  二十四小时和十二时辰对照表 
  子 丑 寅 卯 辰 己 
  23-01:01-03:03-05 :05-07:07-09:09-11 
  午 未 申 酉 戌 亥 
  11-13:13-15:15-17:17-19:19-21:21-23 
  四、由公元推干支记年 
  为了便于运算和使检索更加直观,借用六十干支表并按顺序加以编号成表一如下: 
  六十干支表 
  甲子0 乙丑1 丙寅2 丁卯3 戊辰4 己巳5 庚午6 辛未7 壬申8 癸酉9 
  甲戌10 乙亥11 丙子12 丁丑13 戊寅14 己卯15 庚辰16 辛巳17 壬午18 癸未19 
  甲申20 乙酉21 丙戌22 丁亥23 戊子24 己丑25 庚寅26 辛卯27 壬辰28 癸巳29 
  甲午30 乙未31 丙申32 丁酉33 戊戌34 己亥35 庚子36 辛丑37 壬寅38 癸卯39 
  甲辰40 乙巳41 丙午42 丁未43 戊申44 己酉45 庚戌46 辛亥47 壬子48 癸丑49 
  甲寅50 乙卯51 丙辰52 丁巳53 戊午54 己未55 庚申56 辛酉57 壬戌58 癸亥59 
  该表于公元前后的推算均适用,具体的方法如下: 
  1,求公元后某年(设为Y)的干支。方法是:先以Y除以60得出余数,然后再减去4,最后根据所得结果查表一中相应序数所对应的干支即为该年的干支。 
  例如求公元1911年的干支:1911÷60余数为51,减4后得47,查表一47对应的干支是辛亥,即1911年为辛亥年。由于干支纪年60年一循环,当Y÷60的余数小于4时,需借干支纪年的一个周期60之数,例如1981年除以60余数为1,直接减4不够减,加上60之后再减4等于57,查表一便知1981年为辛酉年。余可类推。 
  2,求公元前某年(设为X)的干支。方法是:先以X除以60求其余数,再用57减去所得余数,根据所得结果再查表一中对应的干支,即为该年的干支。 
  例如求公元前221年的干支:221÷60,余数是41,以57-41=16,查表一16对应的是庚辰,即公元前221年对应的干支应为庚辰。同样由于干支纪年的循环周期为60年,当余数大于57时,也需再借60。例如求公元前479年(孔子卒年)的干支:479除以60余59,用57减59不够减,加上60之后再减59等于58,查表一知该年对应的干支为壬戌。其余可以类推。 
  上述方法简便易行,只要记住表一,就完全可以不用纸笔,直接由心算推出结果。 
  五、速查干支农历纪月法 
  其方法为:若遇甲或己的年份 ,正月是丙寅;遇上乙或庚之年,正月为戊寅;遇上丙或辛之年,正月为庚寅;遇上丁或壬之年,正月为壬寅;遇上戊或癸之年,正月为甲寅。依照正月之干支,其余月份按干支推算即可。 
  例如:2006年为丙戌年,其正月为庚寅,二月为辛卯,三月为壬辰,余类推。 
  六、速查干支纪日法 
  从已知日期计算干支纪日的公式为: 
  G = 4C + [C / 4] + 5y + [y / 4] + [3 * (M + 1) / 5] + d - 3 
  Z = 8C + [C / 4] + 5y + [y / 4] + [3 * (M + 1) / 5] + d + 7 + i 
  其中 C 是世纪数减一,y 是年份后两位,M 是月份,d 是日数。1月和2月按上一年的13月和14月来算。奇数月i=0,偶数月i=6。G 除以10的余数是天干,Z 除以12的余数是地支。 
  计算时带[ ]的数表示取整。 
  例如:查2006年4月1日的干支日。 将数值代入计算公式。 
  G =4*20 + [20 / 4] + 5*06 + [06 / 4] + [3 * (4 + 1) / 5] + 1 - 3 =117 
  除以10 余数为 7 ,天干的第7位是‘庚’。 
  Z =8*20 + [20 / 4] + 5*06 + [06 / 4] + [3 * (4 + 1) / 5] + 1 + 7 + 6 =213 
  除以12 余数为 9 ,地支的第9位是‘申’。 
  答案是:2006年4月1日的干支日是庚申日。
相关链接:http://baike.baidu.com/view/187057.htm

使用特权

评论回复
7
天雨粟| | 2009-4-18 16:45 | 只看该作者

好文,收藏了

Hot老师的干支算法极具参考价值,窃以为万年历以干支纪年才古色古香,农历09年3月6日云云的怕不合适!

使用特权

评论回复
8
yewuyi| | 2009-4-18 17:24 | 只看该作者

我是来砸砖的。。。








我看都不看,直接砸砖。。。










嘿嘿,你欢迎俺砸的,可别说俺不人道。。。

使用特权

评论回复
9
ayb_ice| | 2009-4-18 17:48 | 只看该作者

我也想砸砖

使用特权

评论回复
10
耕在此行|  楼主 | 2009-4-21 19:07 | 只看该作者

呵呵

今天又优化了一点。

使用特权

评论回复
11
zhenglixin| | 2009-4-24 19:54 | 只看该作者

这种东西网上到处都是啊,楼主不要在这上面浪费时间了啊

使用特权

评论回复
12
耕在此行|  楼主 | 2009-4-25 08:49 | 只看该作者

呵呵 今天在改算法的时候又发现了一个问题。

而且是非常严重!!!!!!

使用特权

评论回复
13
McuPlayer| | 2009-4-25 15:00 | 只看该作者

楼主很低调啊

人家都动辄万年历,而楼主只是号称“百年历”而已

你们还砸砖头,尤其是那个干啥都很拉风的小叶

使用特权

评论回复
14
耕在此行|  楼主 | 2009-4-25 15:23 | 只看该作者

能做百年历,

难道万年历很难吗 不就是一万年吗 十万 百万又有何难。 呵呵 

使用特权

评论回复
15
machunshui| | 2009-4-25 16:13 | 只看该作者

支持楼主,砸砸砸!

支持楼主,砸砸砸!

使用特权

评论回复
16
long339170892| | 2009-4-25 17:53 | 只看该作者

支持

东西还是有参考价值的 

使用特权

评论回复
17
huangqi412| | 2009-4-25 18:59 | 只看该作者

呵呵,100都多了,哪个挂历会用上50年?

使用特权

评论回复
18
strang| | 2009-4-25 21:49 | 只看该作者

LS说的很实际

但是做软件的要考虑周到啊.
做产品要有它的卖点,不是吗?
要是真正的挂历用10年就最多了.
可是客户在与百年历和万年历选择的话,肯定会选择后者的.


使用特权

评论回复
19
caven| | 2009-4-29 12:13 | 只看该作者

数值进制搞错了

if( T.sec > 0x59 )
    {
    T.sec = 0;
    T.min++;

LZ,你这个判断错了吧,应该是判断60到了吗,是不是应该用十进制.
类似的都需要修改

使用特权

评论回复
20
耕在此行|  楼主 | 2009-4-29 12:59 | 只看该作者

呵呵

问题不在这里哦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

1108

帖子

0

粉丝