当前位置:首页 >> 信息与通信 >>

ATmega8万年历


ATmega8 万年历(内部 RTC) 软件部分. 程序中包含一个头文件"LCD1620.h",此文件中包含有关 LCD 的一些显示函数. 下面是部分程序原代码---不知道怎么回事,今天网络速度比较慢,无法上传文件. 如有需要可与我 e-mail 联系 lhy_radio@yeah.net. /*********************************

**********************/ /* 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 中断中刷新显示,精度提高 1S@5H */ */ /* 4,加入星期显示 /* 5,加入农历换算 */ /* 6,秒末位大于等于 5 时,显示公历:Solar 年月日 */ */ /* 7,SolarYear>2099 或 SolarYear<1900, /* 显示"Out of range!" */ */ /* 8,加入手动调整日期和时间 /*******************************************************/ #i nclude <iom8v.h> #i nclude <macros.h> #define DataPortPullup PORTD #define DataPortDirection DDRD #define ReadLCDPin PIND #define CtrlPortPullup PORTC #define CtrlPortDirection DDRC #define RS_Bit PC0 #define RW_Bit PC1 #define E_Bit PC2 #i 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 char MonthBit1,MonthBit2; unsigned char DayBit1,DayBit2; unsigned char HourBit1,HourBit2; unsigned char MinBit1,MinBit2; unsigned char SecBit1,SecBit2; unsigned char Week[][4] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; unsigned char ChangeSymbol[][5] = {"-Yar","-Mth","-Day","-Hor","-Min"}; unsigned char LeapYearWeekTable[] = {3,6,0,3,5,1,3,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 LunarConvertBit;//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,否则为 1 static unsigned char const LunarDayCode1[9]= {0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3}; static unsigned short const LunarDayCode2[3]={0x111,0x130,0x14e}; /************************** ***********子函数********** *************************/ void PortInit(void) //端口初始化 { DDRC &= ~((1<<PC3)|(1<<PC4)|(1<<PC5)); PORTC |= (1<<PC3)|(1<<PC4)|(1<<PC5); }

void Timer2Init(void) //timer2 初始化 { TCCR2 = 0x00; //stop ASSR = 0x08; //set async mode TCNT2 = ClkTcnt2; //setup TCCR2 = 0x06; //start } void Timer2Ovf(void)//timer2 中断函数 { TCNT2 = ClkTcnt2;//reload counter value Sec += 1; AskLeapYear(); SolarCount(); AskLeapYear(); CountWeek(); LunarCount();//先判断是否转换成功,然后再计算各位显示数值 if(ModeSelect == 0) { LCDispClear(); DispUpdate(); } } void AskLeapYear(void) { if ( ( (Year%4 == 0) && (Year % 100!=0) ) || Year%400 == 0)//判断是否为闰 年 { LeapYearBit = 1; } else { LeapYearBit = 0; } } void SolarCount(void)//计算各位显示值 { if (Sec>59) { Sec = 0; Min ++; } if (Min>59)

{ Min = 0; Hour ++; } if (Hour>23) { Hour = 0; Day ++; } if ( ( (Month==1) || (Month==3) || (Month==5) || (Month==7) ||(Month==8) || (Month==10) || (Month==12) ) && (Day>31) ) { Month ++; Day = 1; } else if ( ( (Month==4) || (Month==6) || (Month==9) || (Month==11) ) && (Day>30) ) { Month ++; Day = 1; } else if (Month==2) { if (LeapYearBit == 1)//如果是闰年 { if (Day>29) { Month ++; Day = 1; } } else if (Day > 28)//平年 { Month ++; Day = 1; } } if (Month > 12) { Month = 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 /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); 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,LunarYear2); 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) { 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,Week[TodayWeek]); if(ChangeModeBit && SecOddBit) { PutStringLCD(1,12,ChangeSymbol[ModeSelect - 1]); } }

void CountWeek(void) { if(LeapYearBit == 1) { TodayWeek = ((Year/100%4*5) + (Year%100/4*5) + (Year%4) + 1 + Day + LeapYearWeekTable[Month - 1])%7; } else { TodayWeek = ((Year/100%4*5) + (Year%100/4*5) + (Year%4) + 1 + Day + UnLeapWeekTable[Month - 1])%7; } } void KeyScan(void) {if((PINC&(1<<PC5)) == 0) { OldKeyNum = 1; } else if((PINC&(1<<PC4)) == 0) { OldKeyNum = 2; } else if((PINC&(1<<PC3)) == 0) { OldKeyNum = 3; } if((PINC & (1<<PC5)) && (PINC & (1<<PC4)) && (PINC & (1<<PC3)))//判断 是否有按键按下 { 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 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 ++; 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; } } /*********************** **********主函数******** ***********************/ 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 背光的控制模块,无光亮时无法看时间.


相关文章:
ATmega8万年历
A​T​m​e​g​a​8​万​年​历ATmega8 万年历(内部 RTC) 0 推荐 把自己以前做的小东东整理整理,发上来欢迎大家拍砖... 今年年初买了一...
ATmega8单片机万年历C程序(内部RTC)
ATmega8单片机万年历C程序(内部RTC)_信息与通信_工程科技_专业资料 暂无评价|0人阅读|0次下载|举报文档 ATmega8单片机万年历C程序(内部RTC)_信息与通信_工程科技...
基于ATmega16的多功能万年历
原理图如下: 3、单片机主控模块: 万年历的主控芯片我们选择的是 ATmega16。 ATmega16 是基于增强的 AVR RISC 结构的低功耗 8 位 CMOS 微控制器, 由于其先进...
多功能电子万年历的设计
29 V 北华航天工业学院毕业论文 多功能电子万年历的设计第1章 1.1 课题的...通过将 8 位 RISC CPU 与系统内可编程 的 Flash 集成在一个芯片内,ATmega16...
ATMEGA8引脚功能
ATMEGA8引脚功能_电子/电路_工程科技_专业资料。端口引脚 PB7 电器脚电路: 第二功能 XTAL2 (芯片时钟振荡器引脚 2) TOSC2 ( 定时振荡器引脚 2) PB6 XTAL1...
基于单片机的万年历制作
基于DS1302 和 ATmega16 的万年历制作一、 题目分析以及器件选择 1、设计要求:...引脚号 1 2 3 4 5 6 7 8 名称 Vcc1 X1 X2 GND RST I/O SCLK Vcc...
基于MEGA16数字万年历设计
基于MEGA16数字万年历设计_电子/电路_工程科技_专业...速度等级:– 0 - 16 MHz ATmega16 3.1.2 Mega...8 10 GND GND VCC RESET 长春理工大学毕业设计 第...
基于单片的万年历设计
基于51单片机的遥控万年历... 45页 5财富值如要投诉违规内容,请到百度文库投诉...通过将8位RISC CPU与系统内可编程的 Flash集成在一个芯片内,ATmega16成为一个...
ATmega8中文资料
ATmega8中文资料_信息与通信_工程科技_专业资料。ATmega8 是一款采用低功耗CMOS工艺生产的基于AVR RISC结构的8位单片机。AVR单片机的核心是将32个工作寄存器和丰富的...
第5组万年历实验报告
第5组万年历实验报告_工学_高等教育_教育专区。北邮小学期AVR单片机实验万年历实验...8 9 10 11 12 13 14 15 14 2).控制芯片 学校提供的 Atmega16 芯片高...
更多相关标签:
天天万年历v8.1 | 2016年8月万年历 | 8位数码管 万年历 | 8月万年历 | 万年历2017年1月8号 | atmega8 | atmega8a au | atmega8a |