📄 lunar.lst
字号:
239 ///月份数据表
240 code uchar ri_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
241 code uint ri_code2[3]={0x111,0x130,0x14e};
C51 COMPILER V8.08 LUNAR 11/01/2012 15:19:59 PAGE 5
242 code uchar table_xingqi[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
243
244 bit get_moon_ri(uchar yue_p,uint table_addr)
245 {
246 1 uchar tenp;
247 1 switch (yue_p)
248 1 {
249 2 case 1:{tenp=nian_code[table_addr]&0x08;
250 3 if (tenp==0)return(0);else return(1);}
251 2 case 2:{tenp=nian_code[table_addr]&0x04;
252 3 if (tenp==0)return(0);else return(1);}
253 2 case 3:{tenp=nian_code[table_addr]&0x02;
254 3 if (tenp==0)return(0);else return(1);}
255 2 case 4:{tenp=nian_code[table_addr]&0x01;
256 3 if (tenp==0)return(0);else return(1);}
257 2 case 5:{tenp=nian_code[table_addr+1]&0x80;
258 3 if (tenp==0) return(0);else return(1);}
259 2 case 6:{tenp=nian_code[table_addr+1]&0x40;
260 3 if (tenp==0)return(0);else return(1);}
261 2 case 7:{tenp=nian_code[table_addr+1]&0x20;
262 3 if (tenp==0)return(0);else return(1);}
263 2 case 8:{tenp=nian_code[table_addr+1]&0x10;
264 3 if (tenp==0)return(0);else return(1);}
265 2 case 9:{tenp=nian_code[table_addr+1]&0x08;
266 3 if (tenp==0)return(0);else return(1);}
267 2 case 10:{tenp=nian_code[table_addr+1]&0x04;
268 3 if (tenp==0)return(0);else return(1);}
269 2 case 11:{tenp=nian_code[table_addr+1]&0x02;
270 3 if (tenp==0)return(0);else return(1);}
271 2 case 12:{tenp=nian_code[table_addr+1]&0x01;
272 3 if (tenp==0)return(0);else return(1);}
273 2 case 13:{tenp=nian_code[table_addr+2]&0x80;
274 3 if (tenp==0)return(0);else return(1);}
275 2 }
276 1 }
277 /*
278 函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
279 调用函数示例:Conversion(c_sun,nian_sun,yue_sun,ri_sun)
280 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
281 c_sun,nian_sun,yue_sun,ri_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
282 纪,c_sun=1为19世纪
283 调用函数后,原有数据不变,读c_moon,nian_moon,yue_moon,ri_moon得出阴历BCD数据
284 */
285 void Conversion(bit c,uchar nian,uchar yue,uchar ri)
286 { //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
287 1 uchar tenp1,tenp2,tenp3,yue_p;
288 1 uint tenp4,table_addr;
289 1 bit flag2,flag_y;
290 1 tenp1=nian/16; //BCD->hex 先把数据转换为十六进制
291 1 tenp2=nian%16;
292 1 nian=tenp1*10+tenp2;
293 1 tenp1=yue/16;
294 1 tenp2=yue%16;
295 1 yue=tenp1*10+tenp2;
296 1 tenp1=ri/16;
297 1 tenp2=ri%16;
298 1 ri=tenp1*10+tenp2;
299 1 //定位数据表地址
300 1 if(c==0)
301 1 {
302 2 table_addr=(nian+0x64-1)*0x3;
303 2 }
C51 COMPILER V8.08 LUNAR 11/01/2012 15:19:59 PAGE 6
304 1 else
305 1 {
306 2 table_addr=(nian-1)*0x3;
307 2 }
308 1 //定位数据表地址完成
309 1 //取当年春节所在的公历月份
310 1 tenp1=nian_code[table_addr+2]&0x60;
311 1 tenp1=_cror_(tenp1,5);
312 1 //取当年春节所在的公历月份完成
313 1 //取当年春节所在的公历日
314 1 tenp2=nian_code[table_addr+2]&0x1f;
315 1 //取当年春节所在的公历日完成
316 1 // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
317 1 if(tenp1==0x1)
318 1 {
319 2 tenp3=tenp2-1;
320 2 }
321 1 else
322 1 {
323 2 tenp3=tenp2+0x1f-1;
324 2 }
325 1 // 计算当年春年离当年元旦的天数完成
326 1 //计算公历日离当年元旦的天数,为了减少运算,用了两个表
327 1 //ri_code1[9],ri_code2[3]
328 1 //如果公历月在九月或前,天数会少于0xff,用表ri_code1[9],
329 1 //在九月后,天数大于0xff,用表ri_code2[3]
330 1 //如输入公历日为8月10日,则公历日离元旦天数为ri_code1[8-1]+10-1
331 1 //如输入公历日为11月10日,则公历日离元旦天数为ri_code2[11-10]+10-1
332 1 if (yue<10)
333 1 {
334 2 tenp4=ri_code1[yue-1]+ri-1;
335 2 }
336 1 else
337 1 {
338 2 tenp4=ri_code2[yue-10]+ri-1;
339 2 }
340 1 if ((yue>0x2)&&(nian%0x4==0))
341 1 { //如果公历月大于2月并且该年的2月为闰月,天数加1
342 2 tenp4+=1;
343 2 }
344 1 //计算公历日离当年元旦的天数完成
345 1 //判断公历日在春节前还是春节后
346 1 if (tenp4>=tenp3)
347 1 { //公历日在春节后或就是春节当日使用下面代码进行运算
348 2 tenp4-=tenp3;
349 2 yue=0x1;
350 2 yue_p=0x1; //yue_p为月份指向,公历日在春节前或就是春节当日yue_p指向首月
351 2 flag2=get_moon_ri(yue_p,table_addr);
352 2 //检查该农历月为大小还是小月,大月返回1,小月返回0
353 2 flag_y=0;
354 2 if(flag2==0)tenp1=0x1d; //小月29天
355 2 else tenp1=0x1e; //大小30天
356 2 tenp2=nian_code[table_addr]&0xf0;
357 2 tenp2=_cror_(tenp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月
358 2 while(tenp4>=tenp1)
359 2 {
360 3 tenp4-=tenp1;
361 3 yue_p+=1;
362 3 if(yue==tenp2)
363 3 {
364 4 flag_y=~flag_y;
365 4 if(flag_y==0)
C51 COMPILER V8.08 LUNAR 11/01/2012 15:19:59 PAGE 7
366 4 yue+=1;
367 4 }
368 3 else
369 3 yue+=1;
370 3 flag2=get_moon_ri(yue_p,table_addr);
371 3 if(flag2==0)
372 3 tenp1=0x1d;
373 3 else
374 3 tenp1=0x1e;
375 3 }
376 2 ri=tenp4+1;
377 2 }
378 1 else
379 1 { //公历日在春节前使用下面代码进行运算
380 2 tenp3-=tenp4;
381 2 if (nian==0x0)
382 2 {
383 3 nian=0x63;c=1;
384 3 }
385 2 else
386 2 nian-=1;
387 2 table_addr-=0x3;
388 2 yue=0xc;
389 2 tenp2=nian_code[table_addr]&0xf0;
390 2 tenp2=_cror_(tenp2,4);
391 2 if (tenp2==0)
392 2 yue_p=0xc;
393 2 else
394 2 yue_p=0xd; //
395 2 /*yue_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12*/
396 2 flag_y=0;
397 2 flag2=get_moon_ri(yue_p,table_addr);
398 2 if(flag2==0)
399 2 tenp1=0x1d;
400 2 else
401 2 tenp1=0x1e;
402 2 while(tenp3>tenp1)
403 2 {
404 3 tenp3-=tenp1;
405 3 yue_p-=1;
406 3 if(flag_y==0)
407 3 yue-=1;
408 3 if(yue==tenp2)
409 3 flag_y=~flag_y;
410 3 flag2=get_moon_ri(yue_p,table_addr);
411 3 if(flag2==0)
412 3 tenp1=0x1d;
413 3 else
414 3 tenp1=0x1e;
415 3 }
416 2 ri=tenp1-tenp3+1;
417 2 }
418 1 c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据
419 1 tenp1=nian/10;
420 1 tenp1=_crol_(tenp1,4);
421 1 tenp2=nian%10;
422 1 nian_moon=tenp1|tenp2;
423 1 tenp1=yue/10;
424 1 tenp1=_crol_(tenp1,4);
425 1 tenp2=yue%10;
426 1 yue_moon=tenp1|tenp2;
427 1 tenp1=ri/10;
C51 COMPILER V8.08 LUNAR 11/01/2012 15:19:59 PAGE 8
428 1 tenp1=_crol_(tenp1,4);
429 1 tenp2=ri%10;
430 1 ri_moon=tenp1|tenp2;
431 1 }
432 /*函数功能:输入BCD阳历数据,输出BCD星期数据(只允许1901-2099年)
433 调用函数示例:Conver_xingqi(c_sun,nian_sun,yue_sun,ri_sun)
434 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
435 c_sun,nian_sun,yue_sun,ri_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
436 纪,c_sun=1为19世纪
437 调用函数后,原有数据不变,读xingqi得出阴历BCD数据
438 */
439
440 /*
441 算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在
442 闰年又不到3 月份上述之和要减一天再除7
443 星期数为0
444 */
445 void Conver_xingqi(bit c,uchar nian,uchar yue,uchar ri)
446 {//c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
447 1 uchar tenp1,tenp2;
448 1 tenp1=nian/16; //BCD->hex 先把数据转换为十六进制
449 1 tenp2=nian%16;
450 1 nian=tenp1*10+tenp2;
451 1 tenp1=yue/16;
452 1 tenp2=yue%16;
453 1 yue=tenp1*10+tenp2;
454 1 tenp1=ri/16;
455 1 tenp2=ri%16;
456 1 ri=tenp1*10+tenp2;
457 1 if(c==0)
458 1 {
459 2 nian+=0x64; //如果为21世纪,年份数加100
460 2 }
461 1 tenp1=nian/0x4; //所过闰年数只算1900年之后的
462 1 tenp2=nian+tenp1;
463 1 tenp2=tenp2%0x7; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据
464 1 tenp2=tenp2+ri+table_xingqi[yue-1];
465 1 if (nian%0x4==0&&yue<3)
466 1 tenp2-=1;
467 1 xingqi=tenp2%0x7;
468 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1010 ----
CONSTANT SIZE = 624 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 10 12
IDATA SIZE = ---- ----
BIT SIZE = ---- 4
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -