1、万年历代码ATmega8单片机万年历C程序(内部RTC)日期:2009-05-04 来源:net 作者:佚名 字体:大 中 小 (投递新闻) ) 调整时间和日期,只设置了四个按键a, 复位按键;b, 调整模态选择按键,切换调整不同参数;c, 上调按键,调整模式下按此键被调整值上调;d, 下调按键,调整模式下按此键被调整值下调.这是调整年份时的显示状态,LCD第二行末尾显示yar.依此类推,调整月份时显示mth,调整日期时显示day,小时时显示hor,分钟时显示min.3) 软件部分.程序中包含一个头文件LCD1620.h,此文件中包含有关LCD的一些显示函数.下面是部分程序原代码-不知道怎么回
2、事,今天网络速度比较慢,无法上传文件.如有需要可与我e-mail联系lhy_radio./*/* Project :Calendar */* Compiler :ICCAVR 6.31A */* Date :2008,5,31 */* Author :lhy */* Version :v1.3 */* Rework :lhy */* Rework Date :2008.6.26 */* */* Comments : */* 1,使用Atmega8内部RTC(实时时钟,32.768KHz) */* 2,显示使用LCD1620 */* 3,在Timer2中断中刷新显示,精度提高1S5H */* 4
3、,加入星期显示 */* 5,加入农历换算 */* 6,秒末位大于等于5时,显示公历:Solar 年月日 */* 7,SolarYear2099或SolarYear1900, */* 显示Out of range! */* 8,加入手动调整日期和时间 */*/i nclude i nclude #define DataPortPullup PORTD#define DataPortDirection DDRD#define ReadLCDPin PIND#define CtrlPortPullup PORTC#define CtrlPortDirection DDRC#define RS_Bit
4、 PC0#define RW_Bit PC1#define E_Bit PC2i nclude LCD1620.h#define ClkTcnt2 0x80/*变量声明*/ unsigned int Year = 2008;/年变量unsigned char Month = 6;/月变量unsigned char Day = 1;unsigned char Hour = 12;/小时unsigned char Min = 0;/分钟unsigned char Sec = 0;/秒unsigned char YearBit1,YearBit2,YearBit3,YearBit4;unsigned
5、 char MonthBit1,MonthBit2;unsigned char DayBit1,DayBit2;unsigned char HourBit1,HourBit2;unsigned char MinBit1,MinBit2;unsigned char SecBit1,SecBit2;unsigned char Week4 = Mon,Tue,Wed,Thu,Fri,Sat,Sun;unsigned char ChangeSymbol5 = -Yar,-Mth,-Day,-Hor,-Min;unsigned char LeapYearWeekTable = 3,6,0,3,5,1,3
6、,6,2,4,0,2;/闰年星期偏差表unsigned char UnLeapWeekTable = 4,0,0,3,5,1,3,6,2,4,0,2;unsigned char TodayWeek = 0;unsigned char LeapYearBit = 0;/为0时,平年unsigned char LunarData = 0,0,0,0;unsigned char LunarYear1,LunarYear2,LunarYear3,LunarYear4,LunarMonth1,LunARMonth2,LunarDay1,LunarDay2;unsigned char LunarConve
7、rtBit;/0,农历转换成功unsigned char CalendarStopBit;/1,时钟暂停unsigned char OldKeyNum = 0;unsigned char NewKeyNum = 0;unsigned char ModeSelect = 0;unsigned char ChangeModeBit = 0;/ModeSelect != 0时,为1,标志现在处于更改时间状态unsigned char SecOddBit = 0;/秒为偶数时,此为0,否则为1static unsigned char const LunarDayCode19= 0x0,0x1f,0x3
8、b,0x5a,0x78,0x97,0xb5,0xd4,0xf3;static unsigned short const LunarDayCode23=0x111,0x130,0x14e;/*子函数*/void PortInit(void) /端口初始化 DDRC &= (1PC3)|(1PC4)|(1PC5); PORTC |= (1PC3)|(1PC4)|(159) Sec = 0; Min +; if (Min59) Min = 0; Hour +; if (Hour23) Hour = 0; Day +; if ( ( (Month=1) | (Month=3) | (Month=5)
9、| (Month=7) |(Month=8) | (Month=10) | (Month=12) ) & (Day31) ) Month +; Day = 1; else if ( ( (Month=4) | (Month=6) | (Month=9) | (Month=11) ) & (Day30) ) Month +; Day = 1; else if (Month=2) if (LeapYearBit = 1)/如果是闰年 if (Day29) Month +; Day = 1; else if (Day 28)/平年 Month +; Day = 1; if (Month 12) Mo
10、nth = 1; Year +; /计算各位的值 YearBit1 = Year /1000; YearBit2 = Year %1000/100; YearBit3 = Year %100/10; YearBit4 = Year %10; MonthBit1 = Month /10; MonthBit2 = Month %10; DayBit1 = Day /10; DayBit2 = Day %10; HourBit1 = Hour /10; HourBit2 = Hour %10; MinBit1 = Min /10; MinBit2 = Min %10; SecBit1 = Sec /
11、10; SecBit2 = Sec %10; void DeviceInit(void)/MCU初始化 CLI(); PortInit(); Timer2Init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x40; LCD_Init(); SEI(); /更新显示void DispUpdate(void) if(SecBit2 = 5) | (ModeSelect != 0)/秒末位大于5时,显示公历 PutStringLCD(0,0,Solar); PutNumberLCD(0,6,YearBit1); PutNumberLCD(0,7,YearBit2)
12、; PutNumberLCD(0,8,YearBit3); PutNumberLCD(0,9,YearBit4); PutNumberLCD(0,11,MonthBit1); PutNumberLCD(0,12,MonthBit2); PutNumberLCD(0,14,DayBit1); PutNumberLCD(0,15,DayBit2); else if(LunarConvertBit = 1)/秒末位小于5并且农历转换成功时,显示农历 PutStringLCD(0,0,Lunar); PutNumberLCD(0,6,LunarYear1); PutNumberLCD(0,7,Luna
13、rYear2); PutNumberLCD(0,8,LunarYear3); PutNumberLCD(0,9,LunarYear4); PutNumberLCD(0,11,LunARMonth1); PutNumberLCD(0,12,LunARMonth2); PutNumberLCD(0,14,LunarDay1); PutNumberLCD(0,15,LunarDay2); else PutStringLCD(0,0,Out of range!); PutNumberLCD(1,0,HourBit1); PutNumberLCD(1,1,HourBit2); if(SecOddBit)
14、 PutOneCharLCD(1,2,:); PutNumberLCD(1,3,MinBit1); PutNumberLCD(1,4,MinBit2); if(SecOddBit) PutOneCharLCD(1,5,:); PutNumberLCD(1,6,SecBit1); PutNumberLCD(1,7,SecBit2); PutStringLCD(1,9,WeekTodayWeek); if(ChangeModeBit & SecOddBit) PutStringLCD(1,12,ChangeSymbolModeSelect - 1); void CountWeek(void) if
15、(LeapYearBit = 1) TodayWeek = (Year/100%4*5) + (Year%100/4*5) + (Year%4) + 1 + Day + LeapYearWeekTableMonth - 1)%7; else TodayWeek = (Year/100%4*5) + (Year%100/4*5) + (Year%4) + 1 + Day + UnLeapWeekTableMonth - 1)%7; void KeyScan(void)if(PINC&(1PC5) = 0) OldKeyNum = 1; else if(PINC&(1PC4) = 0) OldKe
16、yNum = 2; else if(PINC&(1PC3) = 0) OldKeyNum = 3; if(PINC & (1PC5) & (PINC & (1PC4) & (PINC & (1PC3)/判断是否有按键按下 NewKeyNum = OldKeyNum; OldKeyNum = 0; void TimeChange(void) switch(ModeSelect) case 0: if(NewKeyNum = 2) ModeSelect += 1; break; case 1:/更改年变量 switch (NewKeyNum) case 1: Year -; break; case
17、 2: ModeSelect +; break; case 3: Year +; break; default:break; break; case 2:/更改月变量 switch (NewKeyNum) case 1: Month -; break; case 2: ModeSelect +; break; case 3: Month +; break; default:break; break; case 3:/更改日变量 switch (NewKeyNum) case 1: Day -; break; case 2: ModeSelect +; break; case 3: Day +;
18、 break; default:break; break; case 4:/更改小时变量 switch (NewKeyNum) case 1: Hour -; break; case 2: ModeSelect +; break; case 3: Hour +; break; default:break; break; case 5: switch (NewKeyNum) case 1: Min -; break; case 2: ModeSelect = 0; break; case 3: Min +; break; default:break; break; default : break
19、; /*主函数*/void main() DeviceInit(); SEI(); for (;) if(ModeSelect != 0)/判断现在是否处于更改时间日期状态 ChangeModeBit = 1; else ChangeModeBit = 0; if(SecBit2 % 2 = 0)/如果秒末位是偶数,SecSymbol=0 SecOddBit = 0; else SecOddBit = 1; KeyScan(); TimeChange(); if(ChangeModeBit = 1) CLI(); DispUpdate(); SEI(); 此万年历程序不足,未尽完善之处:1) 未设置闹钟,只能显示阴历阳历和星期等信息.2) 后续应加入温度显示,以测定日气温3) 没有与计算机或其他设备通讯接口4) 液晶显示处于常亮状态,影响寿命.应当设置如果一定时间未操作,显示屏应关闭.待有按键操作时再打开.这样才能使LCD寿命更为长久.5) 程序和硬件中未加入对于LCD背光的控制模块,无光亮时无法看时间.参考链接:
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2