|
這是網上公歷轉農歷的程序,看起來還是很流行的,基本思路是將一年里農歷的相關信息用32位二進制記錄(實際用24位),這樣就建立了一個表格,表格的內容就是一年里農歷的密碼,只要在程序里進行相關運算就可以把這些密碼解出來,也就可以得到每一天所對應的農歷算出來!
具體的算法我也不是很看得懂,我只是隨便拿了幾天代到程序里一步步算了一下,結果是正確的,現在在單片機和DS1337里運行還算正常,農歷是對的!
我用的是12864帶字庫的液晶,相關數據多存在AT24C16里,但表格沒有存入EEPROM,因為存入后讀出轉換農歷里有錯,所以暫時放一下!
表格有二百年的農歷,我只用了五十年(2000~2049),想加就加表格就可以了,請不要問我公式,我也不知道,我是直接拿來用的。我只是從網上找到的,好像還是C++,VC++的程序吧!管他,都帶C應該可以用的!
電路圖就不能傳了,傳張結果圖吧!因為是用線拉的,還沒有做成板,到時畫圖做板再說吧!
uint MonthAdd[12]={0,31,59,90,120,151,181,212,243,273,304,334};
void chek_table(uint num)
{
switch(num-2000)
{
case 0: llsu=0x0C9645;break;//2000
case 1: llsu=0x4D4AB8;break;//2001
case 2: llsu=0x0D4A4C;break;//2002
case 3: llsu=0x0DA541;break;//2003
case 4: llsu=0x25AAB6;break;//2004
case 5: llsu=0x056A49;break;//2005
case 6: llsu=0x7AADBD;break;//2006
case 7: llsu=0x025D52;break;//2007
case 8: llsu=0x092D47;break;//2008
case 9: llsu=0x5C95BA;break;//2009
case 10: llsu=0x0A954E;break;//2010
case 11: llsu=0x0B4A43;break;//2011
case 12: llsu=0x4B5537;break;//2012
case 13: llsu=0x0AD54A;break;//2013
case 14: llsu=0x955ABF;break;//2014
case 15: llsu=0x04BA53;break;//2015
case 16: llsu=0x0A5B48;break;//2016
case 17: llsu=0x652BBC;break;//2017
case 18: llsu=0x052B50;break;//2018
case 19: llsu=0x0A9345;break;//2019
case 20: llsu=0x474AB9;break;//2020
case 21: llsu=0x06AA4C;break;//2021
case 22: llsu=0x0AD541;break;//2022
case 23: llsu=0x24DAB6;break;//2023
case 24: llsu=0x04B64A;break;//2024
case 25: llsu=0x69573D;break;//2025
case 26: llsu=0x0A4E51;break;//2026
case 27: llsu=0x0D2646;break;//2027
case 28: llsu=0x5E933A;break;//2028
case 29: llsu=0x0D534D;break;//2029
case 30: llsu=0x05AA43;break;//2030
case 31: llsu=0x36B537;break;//2031
case 32: llsu=0x096D4B;break;//2032
case 33: llsu=0xB4AEBF;break;//2033
case 34: llsu=0x04AD53;break;//2034
case 35: llsu=0x0A4D48;break;//2035
case 36: llsu=0x6D25BC;break;//2036
case 37: llsu=0x0D254F;break;//2037
case 38: llsu=0x0D5244;break;//2038
case 39: llsu=0x5DAA38;break;//2039
case 40: llsu=0x0B5A4C;break;//2040
case 41: llsu=0x056D41;break;//2041
case 42: llsu=0x24ADB6;break;//2042
case 43: llsu=0x049B4A;break;//2043
case 44: llsu=0x7A4BBE;break;//2044
case 45: llsu=0x0A4B51;break;//2045
case 46: llsu=0x0AA546;break;//2046
case 47: llsu=0x5B52BA;break;//2047
case 48: llsu=0x06D24E;break;//2048
case 49: llsu=0x0ADA42;break;//2049
}
} /**/
void nongni(uint nian,uchar yue,uchar ri)
{
uchar i;
uint Spring_NY,Sun_NY,StaticDayCount;//Spring_NY 記錄春節離當年元旦的天數
uint index,flag;//Sun_NY 記錄陽歷日離當年元旦的天數。
chek_table(nian);
if(((llsu&0x0060)>>5)== 1)
Spring_NY=(llsu&0x001F)-1;
else
Spring_NY=(llsu&0x001F)-1+31;
Sun_NY=MonthAdd[yue-1]+ri-1;
if((!(nian%4))&&(yue>2))
Sun_NY++;
//StaticDayCount記錄大小月的天數 29 或30
//index 記錄從哪個月開始來計算。
//flag 是用來對閏月的特殊處理。
//判斷陽歷日在春節前還是春節后
if(Sun_NY>=Spring_NY)//陽歷日在春節后(含春節那天)
{
Sun_NY-=Spring_NY;
yue=1;
index=1;
flag=0;
if((llsu&(0x80000>>(index-1))) ==0)
StaticDayCount=29;
else
StaticDayCount=30;
while(Sun_NY>= StaticDayCount)
{
Sun_NY-=StaticDayCount;
index++;
if(yue==((llsu&0xF00000)>>20))
{
flag=~flag;
if(flag==0)
yue++;
}
else
yue++;
if((llsu&(0x80000>>(index-1)))==0)
StaticDayCount=29;
else
StaticDayCount=30;
}
ri=Sun_NY+1;
}
else//陽歷日在春節前
{
Spring_NY-=Sun_NY;
nian--;
yue=12;
if (((llsu& 0xF00000)>>20)== 0)
index=12;
else
index=13;
flag = 0;
if((llsu&(0x80000>>(index-1)))==0)
StaticDayCount=29;
else
StaticDayCount=30;
while(Spring_NY>StaticDayCount)
{
Spring_NY-=StaticDayCount;
index--;
if(flag==0)
yue--;
if(yue==((llsu&0xF00000)>>20))
flag=~flag;
if((llsu&(0x80000>>(index-1)))==0)
StaticDayCount=29;
else
StaticDayCount=30;
}
ri=StaticDayCount-Spring_NY+1;
}
//以下為顯示部分,因顯示器件不同可以更改,read()為讀取at24c16內的數據(已存)
write_cmd(0x98);
for(i=0;i<2;i++)
{
write_data(read(0xa2,0x00+((nian-2000)%10)*2+i));
}
for(i=0;i<2;i++)
{
write_data(read(0xa2,0x00+20+((nian-2000)%12)*2+i));
}
for(i=0;i<2;i++)
{
write_data(read(0xa0,0x80+i));
}
if(yue==1)
{
for(i=0;i<2;i++)
{
write_data(read(0xa0,0x8e+i));
}
}
if(yue>=10)
{
for(i=0;i<2;i++)
{
write_data(read(0xa2,0x70+20+i));
}
}
if(yue!=10&&yue!=1)
for(i=0;i<2;i++)
{
write_data(read單片機公歷轉農歷程序(0xa2,0x70+(yue%10)*2+i));
}
for(i=0;i<2;i++)
{
write_data(read(0xa0,0x84+i));
}
if(ri/10==3)for(i=0;i<2;i++)write_data(read(0xa2,0x70+6+i));
if(ri/10==2)for(i=0;i<2;i++)write_data(read(0xa2,0x70+22+i));
if(ri/10==1)for(i=0;i<2;i++)write_data(read(0xa2,0x70+20+i));
if(ri/10==0)for(i=0;i<2;i++)write_data(read(0xa2,0x70+i));
for(i=0;i<2;i++)
{
write_data(read(0xa2,0x70+(ri%10)*2+i));
}
}
|
|