单片机万年历程序

ATmega8单片机万年历C程序(内部RTC)作者:jdzj868来源:机电之家下载站录入:jdzj868更新时间:2009-11-30 16:17:01点击数:0【字体:】正文:) 调整时间和日期,只设置了四个按键a, 复位按键;b, 调整模态选择按键,切换调整不同参数;c, 上调按键,调整模式下按此键被调整值上调;d, 下调按键,调整模式下按此键被调整值下调.这shi调整年份时de显示状态,LCD第二行末尾显示"yar".依此类推,调整月份时显示"mth",调整日期时显示"day",小时时显示"hor",分钟时显示"min".3) 软件部分.程序中包含一个头文件"LCD1620.h",此文件中包含有关LCDde一些显示函数.下面shi部分程序原代码---不知道怎么回事,今天网络速度比较慢,无法上传文件.如有需要可与我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中断中刷新显示,精度提高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 charLunarYear1,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,否则为1static 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; //stopASSR = 0x08; //set async modeTCNT2 = ClkTcnt2; //setupTCCR2 = 0x06; //start}void Timer2Ovf(void)//timer2中断函数{TCNT2 = ClkTcnt2;//reload counter valueSec += 1;AskLeapYear();SolarCount();AskLeapYear();CountWeek();LunarCount();//先判断shi否转换成功,然后再计算各位显示数值if(ModeSelect == 0){LCDispClear();DispUpdate();}}void AskLeapYear(void){if ( ( (Year%4 == 0) && (Year % 100!=0) ) || Year%400 == 0)//判断shi否为闰年{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)//如果shi闰年{if (Day>29){Month ++;Day = 1;}}else if (Day > 28)//平年{Month ++;Day = 1;}}if (Month > 12){Month = 1;Year ++;}//计算各位de值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)))//判断shi否有按键按下{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)//判断现在shi否处于更改时间日期状态{ChangeModeBit = 1;}else{ChangeModeBit = 0;}if(SecBit2 % 2 == 0)//如果秒末位shi偶数,SecSymbol=0 {SecOddBit = 0;}else{SecOddBit = 1;}KeyScan();TimeChange();if(ChangeModeBit == 1){CLI();DispUpdate();SEI();}}}此万年历程序不足,未尽完善之处:1) 未设置闹钟,只能显示阴历阳历和星期等信息.2) 后续应加入温度显示,以测定日气温3) 没有与计算机或其他设备通讯接口4) 液晶显示处于常亮状态,影响寿命.应当设置如果一定时间未操作,显示屏应关闭.待有按键操作时再打开.这样才能使LCD寿命更为长久.5) 程序和硬件中未加入对于LCD背光de控制模块,无光亮时无法看时间.。

合集下载

(完整版)单片机毕业课程设计—万年历

(完整版)单片机毕业课程设计—万年历

郑州轻工业学院软件学院单片机与接口技术课程设计总结报告设计题目:电子万年历学生姓名:系别:专业:班级:学号:指导教师:2011年12月16日设计题目:电子万年历设计任务与要求:1、显示年月日时分秒及星期信息2、具有可调整日期和时间功能3、增加闰年计算功能方案比较:方案一:系统分为主控制器模块、显示模块、按键开关模块,主控制模块采用AT89C52单片机为控制中心,显示模块采用普通的共阴LED数码管,键输入采用中断实现功能调整,计时使用AT89C52单片机自带的定时器功能,实现对时间、日期的操作,通过按键盘开关实现对时间、日期的调整。

方案二:系统分为主控模块、时钟电路模块、按键扫描模块,LCD显示模块,电源电路、复位电路、晶振电路等模块。

主控模块采用AT89C52单片机,按键模块用四个按键,用于调整时间,显示模块采用LCD1602,时钟电路模块采用DS1302时钟芯片实现对时间、日期的操作。

两个方案工作原理大致相同,只有显示模块和时钟电路不同。

LED 数码管价格适中,对于数字显示效果较好,而且使用单片机的端口也较少; LCD1602液晶显示屏,显示功能强大,可以显示大量文字、图形,显示多样性,清晰可见,价格相对LED数码管来说要昂贵些,但是基于本设计显示的东西较多,若采用LED数码管的话,所需数码管较多,而且不利于控制,因此选择LCD1602作为显示模块。

DS1302是一款高性能的实时时钟芯片,以计时准确、接口简单、使用方便、工作电压范围宽和低功耗等优点,得到广泛的应用,实时时钟有秒、分、时、星期、日、月和年,月小于31天时可以自动调整,并具有闰年补偿功能,而且在掉电时能够在外部纽扣电池的供电下继续工作。

单片机有定时器的功能,但时间误差较大,且需要编写时钟程序,因此采用DS1302作为时钟电路。

对比以上方案,结合设计技术指标与要求我们选择了方案二进行设计。

逻辑总框图:该电子万年历的总体设计框图如图(1)所示。

万年历用单片机设计带仿真图1

万年历用单片机设计带仿真图1

#include <reg52.h>#include <math.H>#define uchar unsigned char#define uint unsigned intuchar code table [ ]={'0','1','2','3','4','5','6','7','8','9',':'};uchar code table2[ ]={'S','M','T','W','T','F','S'};uchar code table3[ ]={'U','O','U','E','U','R','A'};uchar code table4[ ]={'N','N','E','N','R','I','T'};sbit s3=P3^3;sbit s4=P3^4;sbit s5=P3^5;sbit s6=P3^6;sbit s7=P3^7;sbit s8=P3^0;sbit en=P2^0;sbit rs=P2^1;sbit sounder=P2^3;sbit button1=P2^4;sbit s00=P0^0;sbit s01=P0^1;sbit s02=P0^2;sbit s03=P0^3;sbit s04=P0^4;sbit s05=P0^5;sbit s06=P0^6;sbit s07=P0^7;sbit s08=P2^5;sbit s9=P3^1;sbit s10=P2^6;sbit s11=P2^7;sbit ds = P2^2;charnum,yue=4,xingqi=5,ri=22,miao=20,fen=36,shi=20,naoshi=20,naofen=53,naomiao=59,naoxingqi; int nian=2012;ucharnaomiao1,naofen1,naoshi1=66,naomiao2,naofen2,naoshi2=66,naomiao3,naofen3,naoshi3=66,nao xingqi1,naoxingqi2,naoxingqi3;uint a,b,c, d,e,f, g,h,i;uchar u;void writecom(uchar com);void writedate(uchar date);void fengmingqi(void);void delay(int x)//自定义延时时间{uint i,j;for(i=0;i<x;i++)for(j=0;j<110;j++);}void delayms(uint a) //Ms延时{uint i,j;for(i = a;i>0;i--)for(j=100;j>0;j--);}void dsinit() //复位命令{uint i;ds = 0;i = 100;while(i>0)i--;ds = 1;i = 4;while(i>0)i--;}void dsWait() //延时等待{uint i;while(ds);while(~ds);i=10;while(i>0) i--;}bit readBit(){uint i;bit b;ds=0;i++;ds =1;b=ds;i=8;while(i>0) i--;return b;}unsigned char readByte() //从单总线上读一个字节{uint i;uchar j,dat;dat = 0;for(i=0;i<8;i++){j=readBit();dat=(j<<7)|(dat>>1);}return dat;}void writeByte(unsigned char dat) //向单总线上写一个字节{uchar j;for(j=0;j<8;j++){ds=0;ds=dat&0x01;delay(5);ds=1;dat=dat/2;}} //温度转换void sendchangecmd(){dsinit();dsWait();delayms(1);writeByte(0xcc);writeByte(0x44);}void sendreadcmd()//读取数据{dsinit();dsWait();delayms(1);writeByte(0xcc);writeByte(0xbe);} //读取温度int gettmpvalue(){uint tmpvalue;int value;float t;uchar low, high;sendreadcmd();low=readByte();high=readByte();tmpvalue=high;tmpvalue<<=8;tmpvalue|=low;value=tmpvalue;t=value*0.0625;value=t*100+(value>0?0.5:-0.5);return value;}void display(int v) //显示温度{uchar count;uchar datas[]={0};uint tmp=abs(v);datas[0]=tmp/10000;datas[1]=tmp%10000/1000;datas[2]=tmp%1000/100;datas[3]=tmp%100/10;datas[4]=tmp%10;writecom(0xc0+14);if(v < 0){writedate('-');}else{writedate('+');}if(datas[0]!=0){writedate('0'+datas[0]);}for(count=1;count!=5;count++){writedate('0'+datas[count]);if(count == 2){writedate('.');}}}void cgdingnaozhong() //成功定闹钟画面{writecom(0x01);writecom(0x83);writedate('S');writedate('u');writedate('c');writedate('c');writedate('e');writedate('s');writedate('s');writedate('f');writedate('u');writedate('l');delay(1000);writecom(0x01);delayms(10);;}void tsdingnaozhong() //提示设置的闹钟1{writecom(0x01);writecom(0x80);writedate('P');writedate('l');writedate('e');writedate('a');writedate('s');writedate('e');writedate(' ');writedate('s');writedate('e');writedate('t');writecom(0x80+0x40+7);writedate('t');writedate('h');writedate('e');writedate(' ');writedate('a');writedate('l');writedate('a');writedate('r');writedate('m');writedate('-');writedate('-');writedate('1');delay(1000);writecom(0x01);delayms(10);}void tsdingnaozhong1() //提示设置闹钟2 {writecom(0x01);writecom(0x80);writedate('P');writedate('l');writedate('e');writedate('a');writedate('s');writedate('e');writedate(' ');writedate('e');writedate('t');writecom(0x80+0x40+7);writedate('t');writedate('h');writedate('e');writedate(' ');writedate('a');writedate('l');writedate('a');writedate('r');writedate('m');writedate('-');writedate('-');writedate('2');delay(1100);writecom(0x01);delayms(10);}void tsdingnaozhong2() //提示设置闹钟3 {writecom(0x01);writecom(0x80);writedate('P');writedate('l');writedate('e');writedate('a');writedate('s');writedate('e');writedate(' ');writedate('s');writedate('e');writedate('t');writedate('t');writecom(0x80+0x40+7);writedate('t');writedate('h');writedate('e');writedate(' ');writedate('a');writedate('l');writedate('r');writedate('m');writedate('-');writedate('-');writedate('3');delay(1000);writecom(0x01);delayms(10);}void xianshinaozhong() //显示所有闹钟{writecom(0x01);writecom(0x80);writedate('1');writedate('^');writedate(table[g/10]);writedate(table[g%10]);writedate(':');writedate(table[d/10]);writedate(table[d%10]);writedate(':');writedate(table[a/10]);writedate(table[a%10]);writedate(' ');writecom(0x80+12);writedate('3');writedate('^');writedate(':');writecom(0x80+0x40);writedate('2');writedate(':');writedate(table[h/10]);writedate(table[h%10]);writedate(':');writedate(table[e/10]);writedate(table[e%10]);writedate(':');writedate(table[b/10]);writedate(table[b%10]);writedate(' ');writedate(table[i/10]);writedate(table[i%10]);writedate(':');writedate(table[f/10]);writedate(table[f%10]);writedate(':');writedate(table[c/10]);writedate(table[c%10]);delay(4000);writecom(0x01);delayms(10);}void naozhong1() //闹钟显示文字1 {writecom(0x01);writecom(0x80+8);writedate('T');writedate('i');writedate('m');writedate('e');writecom(0x80+0x40+6);writedate('i');writedate('s');writedate(' ');writedate(' ');writedate(' ');writedate('u');writedate('p');writedate('!');writedate('!');fengmingqi();writecom(0x01);delayms(10);}void naozhong2() //闹钟显示文字2 {writecom(0x01);writecom(0x80+8);writedate('G');writedate('e');writedate('t');writedate(' ');writecom(0x80+0x40+6);writedate('u');writedate('p');writedate(' ');writedate(' ');writedate('n');writedate('o');writedate('w');writedate('!');writedate('!');fengmingqi();writecom(0x01);}void naozhong3() //闹钟显示文字3 {writecom(0x01);writecom(0x80+8);writedate('P');writedate('l');writedate('e');writedate('a');writedate('s');writedate('e');writecom(0x80+0x40+6);writedate('q');writedate('u');writedate('i');writedate('c');writedate('k');writedate('l');writedate('y');fengmingqi();writecom(0x01);}void fengmingqi(void) //蜂鸣实现闹钟{while(u<3){sounder=!sounder;delay(u);}}void writecom(uchar com)//写命令{rs=0;P1=com;delay(5);en=1;en=0;}void writedate(uchar date) //写数据{rs=1;P1=date;delay(5);en=1;en=0;}void init() //初始化{en=0;writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);delay(5);TMOD=0X01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;IT0=1;EX0=1;}void main() //主函数开始{ uint q;sendchangecmd();init();if(button1==0) //按键实现开机程序for(q=0;q<1;q++);if(button1==0){while(1){while(miao==naomiao1&&fen==naofen1&&shi==naoshi1) //设置第一个闹钟时间{naozhong1(); //闹钟时间到显示的文字}while(miao==naomiao2&&fen==naofen2&&shi==naoshi2){naozhong2();}while(miao==naomiao3&&fen==naofen3&&shi==naoshi3){naozhong3();}writecom(0x80);//开始写数据writedate(' ');writedate(table[shi/10]);writedate(table[shi%10]);writedate(table[10]);writedate(table[fen/10]);writedate(table[fen%10]);writedate(table[10]);writedate(table[miao/10]);writedate(table[miao%10]);writecom(0x80+11);writedate(0x22);writedate(table[naoshi/10]);//显示闹钟设置时间writedate(table[naoshi%10]);writedate(table[10]);writedate(table[naofen/10]);writedate(table[naofen%10]);writedate(table[10]);writedate(table[naomiao/10]);writedate(table[naomiao%10]);writecom(0x80+0x40);writedate(table[nian/1000]);writedate(table[nian%1000/100]);writedate(table[nian%100/10]);writedate(table[nian%10]);writedate(table[10]);writedate(table[yue/10]);writedate(table[yue%10]);writedate(table[10]);writedate(table[ri/10]);writedate(table[ri%10]);writecom(0x80+0x40+11);writedate(table2[xingqi]);writedate(table3[xingqi]);writedate(table4[xingqi]);display(gettmpvalue()); //显示温度sendchangecmd();}}while(button1==1){writecom(0x80+4);writedate('P');writedate('l');writedate('e');writedate('a');writedate('s');writedate('e');writedate(' ');writedate(' ');writedate('C');writedate('l');writedate('i');writedate('c');writedate('k');writecom(0x80+0x40+3);writedate('T');writedate('h');writedate('e');writedate(' ');writedate(' ');writedate('b');writedate('u');writedate('t');writedate('t');writedate('o');writedate('n');writedate(' ');writedate('o');writedate('f');writedate(' ');writedate('K');writedate('0');}}void T0_time()interrupt 1{ uint q;TH0=(65536-50000)/256;TL0=(65536-50000)%256;num++;if(num==20){ num=0; u++;if(u>3)u=0;miao++;if(miao==60){ fen++;miao=0; }if(fen==60){ shi++;fen=0;}if(shi==24){shi=0;xingqi++;ri++;}if(xingqi==7){xingqi=0;}if(s4==0) //时加{ for(q=0;q<1000;q++);if(s4==0){ shi++;if(shi==24)shi=0;}}if(s3==0) //分加{ for(q=0;q<1000;q++);if(s3==0){ fen++;if(fen==60)fen=0;}}if(s5==0) //星期加{ for(q=0;q<1000;q++);if(s5==0){ xingqi++;if(xingqi==7)xingqi=0;}}if(s6==0) //日加{ for(q=0;q<1000;q++);if(s6==0){ ri++;if(ri==32)ri=0;}} //月加if(s7==0){ for(q=0;q<1000;q++);if(s7==0){ yue++;if(yue==13)yue=0;}}if(s8==0) //年加{ for(q=0;q<1000;q++);if(s8==0){ nian++;if(nian>9999)nian=0;}}if(s00==0) //分减{for(q=0;q<1000;q++);if(s00==0)fen--;if(fen<0)fen=59;}if(s01==0) //时减{for(q=0;q<1000;q++);if(s01==0)shi--;if(shi<0)shi=23;}if(s02==0) //星期减{for(q=0;q<1000;q++);if(s02==0)xingqi--;if(xingqi<0)xingqi=6;}if(s03==0) //日减{for(q=0;q<1000;q++);if(s03==0)ri--;if(ri<0)ri=31;}if(s04==0) //月减{for(q=0;q<1000;q++);if(s04==0)yue--;if(yue<0)yue=12;}if(s05==0) //年减{for(q=0;q<1000;q++);if(s05==0)nian--;if(nian<0)nian=9999;}if(s06==0) //闹钟秒减{for(q=0;q<1000;q++);if(s06==0)naomiao--;if(naomiao<0)naomiao=59;}if(s07==0) //闹钟分减{for(q=0;q<1000;q++);if(s07==0)naofen--;if(naofen<0)naofen=59;}if(s08==0) //闹钟时减{for(q=0;q<1000;q++);if(s08==0)naoshi--;if(naoshi<0)naoshi=59;}if(s9==0) //闹钟秒加{for(q=0;q<1000;q++);if(s9==0)naomiao++;if(naomiao==60)naomiao=0;}if(s10==0) //闹钟分加{for(q=0;q<1000;q++);if(s10==0)naofen++;if(naofen==60)naofen=0;}if(s11==0) //闹钟时加{for(q=0;q<1000;q++);if(s11==0)naoshi++;if(naoshi==24)naoshi=0;}if(yue==1 || yue==3 || yue==5 || yue==7 || yue==8 || yue==10) //31天的日子if(ri==32){ yue++;ri=1; }if(yue==12)if(ri==32){ yue=1;ri=1; }if(yue==4 || yue==6 || yue==9 || yue==11) //30天的日子if(ri==31){ yue++;ri=1; }if(((nian%4==0&&nian%100!=0)||(nian%400==0))&&yue==2) //29天的日子if(ri==30){ yue++;ri=1; }if(nian%4!=0 && yue==2) //28天的日子if(ri==29){ yue++;ri=1; }}}void INT0_time() interrupt 0 //实现的功能是依次设定各个闹钟{uint k;k++;if(k==1){tsdingnaozhong();}if(k==2){ naofen1=naofen; //第一个闹钟定时naomiao1=naomiao;naoshi1=naoshi;cgdingnaozhong();}if(k==3){tsdingnaozhong1();}if(k==4){ naomiao2=naomiao;naofen2=naofen;naoshi2=naoshi;cgdingnaozhong();}if(k==5){tsdingnaozhong2();}if(k==6){ naomiao3=naomiao;naofen3=naofen;naoshi3=naoshi;cgdingnaozhong();}if(k==7) //显示设置的闹钟时间{k=0;a=naomiao1;b=naomiao2 ;c=naomiao3;d=naofen1;e=naofen2;f=naofen3;g=naoshi1;h=naoshi2;i=naoshi3;xianshinaozhong();}}。

万年历单片机课程设计报告

万年历单片机课程设计报告

1 任务和设计要求首先要学会安装软件,要熟悉会使用.2 系统设计系统框图3 硬件设计3。

1 电路原理图3.2 主要单元电路3。

3 元件清单4 软件设计4.1 程序流程图4.2程序清单TIME_WEEK DATA 52H TIME_YEAR DATA 5DH TIME_MONTH DATA 5EH TIME_DATA DATA 5FH YEARH DATA 36HYEAR DATA 35H MONTH DATA 34HDAY DATA 33HHOUR DATA 32H MINUTE DATA 31HSEC DATA 30HAAA BIT P3.0BBB BIT P3.1AA BIT P3.3BB BIT P3.4CC BIT P3。

5BL BIT P3.2BZ1 BIT 21H.0 TIMES DATA 20H COM DATA P1 ORG 0000HLJMP START ORG 0003H RETIORG 000BH LJMP INTT0ORG 0013H RETIORG 001BH RETIORG 0023H RETISTART:MOV R0,#30HMOV R7,#9 CLEETE:MOV @R0,#00HINC R0DJNZ R7,CLEETEMOV TIMES,#00H MOV TMOD,#01H MOV TL0,#0C0H MOV TH0,#63H MOV SEC,#0MOV MINUTE,#0H MOV HOUR,#0H MOV DAY,#01H MOV MONTH,#01H MOV YEAR,#01H MOV YEARH,#20H SETB EASETB ET0SETB TR0MOV R4,#19 START1:CALL DISPJNB AA,SETMM1 JMP START1 SETMM1:CALL SETMMJMP START1SETMM:CALL DISPCALL DISPJB AA,SETMM0SETMM2:JNB AA,SETMM3CLR ET0CLR TR0MOV SEC,#0MOV TIMES,#01H MOV R0,#MINUTE SETMM4:NOPINC22:CALL OFFLCALL INC11CALL DISPJB AA,INC22CALL DISPJB AA,INC22INC R0MOV A,TIMESRL AMOV TIMES,AJNB TIMES. 5, SETMM4 SETMM12:JNB AA ,SETMM11 SETMM0:SETB TR0SETB ET0RETSETMM11:CALL DISPJMP SETMM12 SETMM3:CALL DISPJMP SETMM2INC11:MOV R3,#40INC111:MOV A,@R0JB BB,INC17 ADD A,#1DA ACALL INC000INC13:JNB BB ,INC14 INC17:MOV @R0,A CALL DISP DJNZ R3,INC111 RETINC14:CALL DISP JMP INC13 OFFL:MOV 22H,@R0 MOV R6,#10 OFF1:MOV R7,#10OFF2:MOV @ R0, #0AAH CALL DISPDJNZ R7 , OFF2DJNZ R6 , OFF1MOV @R0 , 22HRETINC000:JB TIMES。

基于51单片机的万年历设计

基于51单片机的万年历设计

基于51单片机的万年历设计一、系统设计方案本万年历系统主要由 51 单片机、时钟芯片、液晶显示屏、按键等部分组成。

51 单片机作为核心控制器,负责整个系统的运行和数据处理。

时钟芯片用于提供精确的时间信息,液晶显示屏用于显示万年历的相关内容,按键则用于设置时间和功能切换。

二、硬件设计1、单片机选型选用常见的 51 单片机,如 STC89C52 单片机,它具有性能稳定、价格低廉、易于编程等优点。

2、时钟芯片选择 DS1302 时钟芯片,该芯片能够提供高精度的实时时钟,具有闰年补偿功能,并且可以通过串行接口与单片机进行通信。

3、液晶显示屏采用 1602 液晶显示屏,能够清晰地显示字符和数字,满足万年历的显示需求。

4、按键电路设计四个按键,分别用于时间设置、功能切换、加和减操作。

三、软件设计1、主程序流程系统上电后,首先进行初始化操作,包括单片机端口初始化、时钟芯片初始化、液晶显示屏初始化等。

然后读取时钟芯片中的时间数据,并在液晶显示屏上显示出来。

接着进入循环,不断检测按键状态,根据按键操作执行相应的功能,如时间设置、功能切换等。

2、时钟芯片驱动程序通过单片机的串行接口向 DS1302 发送命令和数据,实现对时钟芯片的读写操作,获取准确的时间信息。

3、液晶显示屏驱动程序编写相应的函数,实现对1602 液晶显示屏的字符和数字显示控制。

4、按键处理程序采用扫描方式检测按键状态,当检测到按键按下时,执行相应的按键处理函数,实现时间设置和功能切换等操作。

四、时间设置功能通过按键操作进入时间设置模式,可以分别设置年、月、日、时、分、秒等信息。

在设置过程中,液晶显示屏会显示当前设置的项目和数值,并通过加、减按键进行调整。

设置完成后,将新的时间数据保存到时钟芯片中。

五、显示功能万年历的显示内容包括年、月、日、星期、时、分、秒等信息。

通过合理的排版和显示控制,使这些信息在液晶显示屏上清晰、直观地呈现给用户。

六、系统调试在完成硬件和软件设计后,需要对系统进行调试。

基于STM32单片机的万年历设计毕业设计论文

基于STM32单片机的万年历设计毕业设计论文

万年历是一种可以显示年、月、日、星期的电子设备,广泛应用于日常生活和办公场所。

本文将介绍一个基于STM32单片机的万年历的设计思路和实现过程。

首先,我们需要明确设计目标。

在这个项目中,我们的目标是使用STM32单片机开发一个功能齐全、易于操作的万年历。

具体地说,这个万年历应该能够显示当前的年、月、日和星期,并且能够进行日期的加减操作,同时应该具备一些辅助功能如闹钟设置、倒计时等。

接下来,我们需要进行硬件设计。

首先需要选择适当的显示屏,比如常见的LCD或OLED屏幕。

然后,我们需要选择合适的按键和外部触发器,用于用户的交互输入。

同时,还需要添加一些必要的接口,如USB接口用于数据传输和维护。

在软件设计方面,我们需要定义合适的数据结构来存储日期、时间、闹钟等信息。

同时,需要编写相应的程序来实现日期的显示和更新、日期的加减、闹钟的设置等功能。

在实现倒计时功能时,我们可以使用定时器中断来实现精确的计时。

此外,为了提高用户体验,我们可以添加一些额外的功能。

比如,我们可以为万年历设计一个简洁美观的用户界面,考虑使用图形库绘制用户界面元素。

同时,可以添加一些实用的功能如温湿度监测、天气预报等。

最后,在整个开发流程结束后,我们需要进行集成测试和调试,确保万年历的各项功能正常运行。

并且,我们还可以考虑为万年历添加一些优化和改进措施,如增加存储容量、优化节能技术等。

综上所述,基于STM32单片机的万年历设计主要涉及硬件设计和软件设计两个方面。

通过精心的设计和合理的实现,我们可以开发出一款功能丰富、易于使用的万年历产品,满足用户的各种需求。

基于单片机万年历设计

基于单片机万年历设计

基于单片机万年历设计基于单片机的万年历设计二、实验要求设计一个万年历,将时钟显示在LCD1602的显示屏上并且可以进行年、月、日以及时、分、秒的设置。

此外还可以通过按键进行闹钟设置以及事件提醒功能,用蜂鸣器进行闹铃提醒。

最后附加一个温湿度检测的功能,用温湿度传感器检测室内的温湿度并将温湿度数据在显示屏上显示出来。

三、实验设备和仪器1.用STC89C52芯片作为系统板的主控芯片2.DHT11温湿度传感器3.DS1302时钟芯片4.LCD1602显示屏四、实验各模块原理介绍4.1STC89C52单片机STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K字节系统可编程Flah存储器。

STC89C52使用经典的MCS-51内核,具有传统51单片机不具备的功能。

在单芯片上,拥有灵巧的8位CPU和在系统可编程Flah,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。

2.工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机) 3.工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可达48MHz4.用户应用程序空间为8K字节5.片上集成512字节RAM6.通用I/O口(32个),复位后为:P1/P2/P3是准双向口/弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。

8.具有EEPROM功能9.共3个16位定时器/计数器。

即定时器T0、T1、T2。

10.外部中断4路,下降沿中断或低电平触发电路,PowerDown模式可由外部中断低电平触发中断方式唤醒。

11.通用异步串行口(UART),还可用定时器软件实现多个UART。

12.工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)13.PDIP封装1、STC89C52单片机引脚图图4.1STC89C52单片机引脚图①主电源引脚(2根) VCC(Pin40):电源输入,接+5V电源GND(Pin20):接地线②外接晶振引脚(2根) 某TAL1(Pin19):片内振荡电路的输入端某TAL2(Pin20):片内振荡电路的输出端③控制引脚(4根) RST/VPP(Pin9):复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。

基于单片机的可调万年历

课程设计报告书目录设计报告书目录一、设计目的 (1)二、设计思路 (1)三、设计过程 (1)3.1、系统方案论证 (1)3.2、模块电路设计 (2)四、系统调试与结果 (10)五、主要元器件与设备 (10)六、课程设计体会与建议 (10)6.1、设计体会 (10)6.2、设计建议 (10)七、参考文献 (11)键盘可调时钟显示设计基于单片机的可调万年历一、设计目的1、熟悉集成电路的引脚安排。

2、掌握芯片的逻辑功能及使用方法。

3、了解电路板结构及其接线方法。

4、了解键盘可调时钟显示的组成及工作原理。

5、熟悉键盘可调时钟显示的设计与制作。

二、设计思路1、电子时钟主要由显示模块、校时模块和时钟运算模块三大部分组成。

2、其中校时模块和时钟运算模块要对时、分、秒的数值进行操作,并且秒计算到60 时,要自己清零并向分进1;分计算到60 时,要自己清零并向时进1;时计算到24时,要清零。

这样,才能循环记时。

三、设计过程3.1、系统方案论证设计一款电子时钟,用共阴极七段数码管显示时间;6 个数码管分别显示时、分、秒;可以利用四个键盘调整时间,小时键每次调整一小时,分钟用两个键调整十位和各位,秒钟键调整秒显示的十位;硬件电路的调试;写出详细的课设报告。

3.2、系统方案选择1 电子与信息工程系2009年10月1、键盘的设计考虑到时间误差的存在以及调整时间的方便性,采用独立式键盘。

提高CPU 的工作效率,采用中断工作方式四个键盘接于P1 口,用74ls21 与门接于外部中断0,实现了调整时间的快速性,当四个键盘有中断发生,首先判断四个键哪个按下,向CPU 发一个中断请求信号,然后调用相应的中断程序。

参考电路如下:键盘的工作过程可分为两步:第一步是CPU 首先检测键盘上是否有按键被按下,第二步是识别哪一个减按下。

检查键盘上有无键按下可采用查询工作方式、定时扫描工作方式和中断工作方式。

查询工作方式(例如用8155 扩展I/O 组成的行列式键盘):键盘上有无键按下是有列线送出全扫描字,然后读入行线状态来识别的。

51单片机万年历课程设计报告

一、设计任务:1、设计任务:设计并制作一个数字钟。

2、设计要求:●显示年月日时分秒及星期信息●具有可调整日期和时间功能●增加闰年计算功能●显示部分由LCD1602完成二、方案论证:1.显示部分:显示部分是本次设计的重要部分,一般有以下两种方案:方案一:采用LED显示,分静态显示和动态显示。

对于静态显示方式,所需的译码驱动装置很多,引线多而复杂,且可靠性也较低。

而对于动态显示方式,虽可以避免静态显示的问题,但设计上如果处理不当,易造成亮度低,有闪烁等问题。

方案二:采用LCD显示。

LCD液晶显示具有丰富多样性、灵活性、电路简单、易于控制而且功耗小等优点,对于信息量多的系统,是比较适合的。

鉴于上述原因,我们采用方案二。

2.数字时钟:数字时钟是本设计的核心的部分。

根据需要可采用以下两种方案实现:方案一:方案完全用软件实现数字时钟。

原理为:在单片机内部存储器设三个字节分别存放时钟的时、分、秒信息。

利用定时器与软件结合实现1秒定时中断,每产生一次中断,存储器内相应的秒值加1;若秒值达到60,则将其清零,并将相应的分字节值加1;若分值达到60,则清零分字节,并将时字节值加1;若时值达到24,则将时字节清零。

该方案具有硬件电路简单的特点,但当单片机不上电,程序将不执行。

而且由于每次执行程序时,定时器都要重新赋初值,所以该时钟精度不高。

方案二:方案采用Dallas公司的专用时钟芯片DS1302。

该芯片内部采用石英晶体振荡器,其芯片精度不大于10ms/年,且具有完备的时钟闹钟功能,因此,可直接对其以用于显示或设置,使得软件编程相对简单。

为保证时钟在电网电压不足或突然掉电等突发情况下仍能正常工作,芯片内部包含锂电池。

当电网电压不足或突然掉电时,可使系统自动转换到内部锂电池供电系统。

而且即使系统不上电,程序不执行时,锂电池也能保证芯片的正常运行,以备随时提供正确的时间。

基于时钟芯片的上述优点,本设计采用方案二完成数字时钟的功能。

51系列单片机制作万年历

目录摘要 (I)Abstract .................................................... I I 第一章前言.. (1)1.1 研究目的和意义 (1)1.2 国内外研究现状 (1)1.3 研究内容和方法 (1)第二章设计方案论证 (3)2.1 系统基本方案选择和论证 (3)2.2 控制部分的方案选择 (3)2.2 显示部分的方案选择 (4)第三章系统硬件设计 (6)3.1 系统硬件框图 (6)3.2 控制部分电路设计 (6)3.3 显示部分电路设计 (13)3.4 时钟电路模块的设计 (14)第四章系统软件设计 (18)4.1 主程序 (18)4.2 阳历部分 (18)4.3 阴历部分 (20)4.4 阳历日和阴历日的对应调整 (22)4.5 键盘防抖程序 (24)第五章结论与建议 (25)致谢 (26)参考文献 (27)附录一整体电路图 (28)附录二程序 (29)摘要万年历的设计过程在硬件与软件方面进行同步设计。

硬件部分主要由AT89S51单片机,LED 显示电路,以及调时按键电路等组成。

在单片机的选择上本人使用了AT89S51单片机,该单片机适合于许多较为复杂控制应用场合。

显示器使用2片7SEG-MPX8-CA和一片7SEG-MPX4-CA。

7SEG-MPX8-CA是一种八个共阳二极管显示器,7SEG-MPX4-CA是一种四个共阳二极管显示器。

为了能更轻松的控制这三片显示器,本人使用了3片74HC164来驱动。

74HC164是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。

软件方面主要包括日历程序、时间调整程序,公历转阴历程序,显示程序等。

程序采用汇编语言编写,以便更简单地实现调整时间及阴历显示功能。

关键词:时钟电钟,动态扫描,单片机AbstractCalendar of the design process in hardware and software to synchronize the design. Hardware mainly by the AT89S51 micro-controller, LED display circuit, and the tune composed of the circuit when the button. In the SCM choice I used the AT89S51 micro-controller, which is suitable for many of the more complex control applications. Monitor the use of two 7SEG-MPX8-CA and a 7SEG-MPX4-CA. 7SEG-MPX8-CA is a total of eight-yang diode display, 7SEG-MPX4-CA is a total of four-yang diode display. In order to more easily control the three monitors, I use three 74HC164 to drive.74HC164 is an 8-bit edge-triggered shift register, serial input data, and parallel output. The software includes calendar program, time to adjust procedures, turn the lunar calendar programs, display programs. Programs written in assembly language used in order to more easily adjust the time and the realization of the lunar calendar display.Keywords:Clock electric clock, Dynamic scan, SCM第一章前言1.1 研究目的和意义电子万年历是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。

基于单片机的电子万年历的设计与实现毕业论文

保密类别编号毕业论文基于单片机的电子万年历的设计与实现摘要电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行.它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。

对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。

该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。

本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能.在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。

在硬件与软件设计时,没有良好的基础知识和实践经验会受到很大限制,每项功能实现时需要那种硬件,程序该如何编写,算法如何实现等,没有一定的基础就不可能很好的实现.在编写程序过程中发现以现有的相关知识要独自完成编写任务困难重重,在老师和同学的帮助下才完成了程序部分的编写.关键词:单片机万年历DS1302 STC89C52第1章绪论 (1)1。

1 课题研究的背景 (1)1。

2 国内外关于该论题的研究现状和发展趋势 (1)1。

3 本课题研究的目的 (1)第2章系统基本方案选择和论证 (1)2。

1 单片机芯片的选择 (1)2.2 显示模块选择方案和论证 (1)2.3 时钟芯片的选择方案和论证 (1)2。

4 温度传感器的选择方案与论证 (2)第3章系统的硬件设计与实现 (3)3.1电路设计框图 (3)3.2 主要单元电路的设计 (4)3.3 单片机中断系统 (5)3.4 温度采集模块设计 (8)3。

5显示模块的设计 (9)3.6系统的软件设计 (10)结论1。

硬件测试 (12)2.软件测试 (12)参考文献 (13)附录 (14)后记 (16)第1章绪论1.1 课题研究的背景随着微电子技术和超大规模集成电路技术的不断发展家用电子产品不但种类日益丰富而且变得更加经济实用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档