首页 单片机电子万年历设计

单片机电子万年历设计

举报
开通vip

单片机电子万年历设计 带日历电子钟 摘要 本设计采用AT89S52系列单片机作为时钟的控制核心,电路使用了2个四位数码管,利用动态来实现显示功能,用于自动同步显示时间温度、日期星期,其切换时间为5秒。利用单片机定时中断程序设计出一秒钟的精确定时,可通过按钮实现了秒表、闹钟、倒计时、自动更新、可进行单倍速和24倍速计两种时等功能的切换,并用指示灯指示当前的工作状态,系统具有可设置年、月、日或时、分、秒的功能,调时过程中通过编程实现可调位的闪烁来标志,本设计具有农历功能,通过按键可实现输...

单片机电子万年历设计
带日历电子钟 摘要 本设计采用AT89S52系列单片机作为时钟的控制核心,电路使用了2个四位数码管,利用动态来实现显示功能,用于自动同步显示时间温度、日期星期,其切换时间为5秒。利用单片机定时中断程序设计出一秒钟的精确定时,可通过按钮实现了秒 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 、闹钟、倒计时、自动更新、可进行单倍速和24倍速计两种时等功能的切换,并用指示灯指示当前的工作状态,系统具有可设置年、月、日或时、分、秒的功能,调时过程中通过编程实现可调位的闪烁来标志,本设计具有农历功能,通过按键可实现输入特定的日期就可现实对应的农历。其中倒计时和闹钟到达预设的时间时,利用指示灯发出报警信号,系统还通过语音模块实现整点报时功能,另外,在设计中时附加了测温功能,实时测试环境的温度。做出实物后,我们将时钟连续工作了4天,测得平均每24小时的误差小于1秒。 关键词:单片机、控制、显示、调时。 设计任务 基本要求 (1)用六位数码管显示年、月、日或时、分、秒,日历由时间自动同步。 (2)可设置年、月、日或时、分、秒。 (3)可进行单倍速和24倍速计两种时。 (4)24小时误差小于4秒。 (5)具有倒计时功能。 发挥部分 (1)具有秒表功能。 (2)24小时误差小于1秒。 (3)具有自动日历功能,改变年、月能自动显示日和星期(切换显示年、月、日和星期、时、分)。 (4)具有农历功能,改变日期能自动显示对应的农历(切换显示年、月、日和农历、时、分)。 3、附加功能 (1)测温功能 (2)语音整点报时功能 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 设计 总体功能的描述 1.1硬件的设计 1)电路原理图 本设计电路连接如上图所示,通过软件编程,配合外部硬件电路,实现带日历电子钟的多种功能。 PCB图 1.2软件的设计 程序 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 图 主程序流程图: 定时器0函数流程图: 定时器1函数流程图: 1.3模块分析 单片机控制模块:单片机控制模块在系统中处于核心地位。其工作包括读取并处理键盘输入、显示模块控制、处理各种功能的切换等任务。 按键输入模块:此模块完成对各种功能的控制,功能的切换在硬件上通过此部分来操作完成。 温度传感器模块:此模块配合完成测温功能。通过温度传度器对外部温度的读取,并将信号输入单片机,单片机将此信号进行处理,并做出判断,最终在数码管上显示。 工作指示灯模块:此部分是对各种功能操作的标志。为了知道系统工作在什么状态下,增加此模块进行指示。 语音报时模块:此模块实现时钟的整点报时,在系统工作前将人的声音录入系统。系统正常工作后,每到整点时系统会发出录入的声音,发出报时信号。 基本部分功能的实现 2.1自动更新、设置显示年、月、日或时、分、秒 本设计利用单片机中断程序设计出一秒钟的精确计数,自动更新显示年、月、日或时、分、秒,其显示切换时间设置为5秒。在显示过程中系统内部一直在扫描是否有按键设置时间的操作,其程序流程图如下所示: 2.2单倍速和24倍速计两种时 和2.1的程序流程图一样,系统原本工作在24小时制,通过按键可以调整为12小时制。 2.3倒计时功能 同以上功能类似,由软件编程配合一部分外部电路可实现倒计时功能,其倒计时初值由外部按键输入实现,其最大初值可设为99天23小时59分59秒。当预设时间到达时,会有特定的指示灯进行指示。 发挥部分功能的实现 3.1秒表功能 秒表功能由按键输入进行设置开始结束,其最大时间可计时到23小时59分59秒。 3.2自动日历、农历功能功能 本系统可切换显示时间温度和日期星期,其切换时间为5秒。系统还具有农历功能,可任意查询对应日期的农历。 3.3闹钟功能 此功能使得系统具有闹钟提醒效应,当预设时间到达时,电路板上有指示灯进行指示。 3.4测温功能 本设计外接温度传感器,利用其接受的外部信号,输入到单片机进行处理,最后在数码管上显示,实现外部温度的实时测试。 3.5语音整点报时功能 此功能实现时钟的报时,通过软件编程,外接语音系统模块,从而实现语音的报时响应效果。 测试方法、数据及测试结果分析 基本原理弄清楚后,我们利用单片机开发板,通过Keil uVision3软件将程序反复的调试、修改,直至预期的功能全部实现。之后使用Protel 99 SE软件画出PCB图,做出实物,并在实物上进行试验,除了误差不能立即在实物上体现出来外,所有的功能都成功实现。因此我们将实物连续工作了4天,测得平均每24小时的误差小于1秒。 参考文献 【1】张毅刚,单片机原理与应用,北京:高等教育出版社,2008.12。 【2】张齐 杜群贵,单片机应用系统设计技术—基于C语言编程,北京:电子工业出版社,2004.8。 附录 单片机源程序: #include #include //包含_nop_()函数定义的头文件 #define uchar unsigned char #define uint unsigned int /***********全局变量声明部分*******************/ sbit DQ=P3^1; sbit beep=P3^0;//蜂鸣器 sbit LED1=P3^2; sbit LED2=P3^3; sbit LED3=P3^4; sbit LED4=P3^6; sbit LED5=P3^5; sbit LED6=P3^7; uchar code DIS_SEG7[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};/*数码管0~9代码*/ uchar code DIS_BIT[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};/*数码管位选通*/ uchar clockstr[8];/*日历模式时间显示的数组*/ uchar datestr[8]; /*日历模式日期显示的数组*/ uchar yindatestr[8];/*阴历日期显示的数组*/ uchar miaostr[8];/*秒表模式显示的数组*/ uchar daoclockstr[8];/*倒计时模式时间显示的数组*/ uchar naoclockstr[8]; /*闹钟模式日期显示的数组*/ uchar code year_code[597]={ 0x04,0xAe,0x53,0x0A,0x57,0x48,0x55,0x26,0xBd, // 1901-1903 0 0x0d,0x26,0x50,0x0d,0x95,0x44,0x46,0xAA,0xB9, // 1904-1906 9 0x05,0x6A,0x4d,0x09,0xAd,0x42,0x24,0xAe,0xB6, // 1907-1909 18 0x04,0xAe,0x4A,0x6A,0x4d,0xBe,0x0A,0x4d,0x52, // 1910-1912 27 0x0d,0x25,0x46,0x5d,0x52,0xBA,0x0B,0x54,0x4e, // 1913-1915 36 0x0d,0x6A,0x43,0x29,0x6d,0x37,0x09,0x5B,0x4B, // 1916-1918 45 0x74,0x9B,0xC1,0x04,0x97,0x54,0x0A,0x4B,0x48, // 1919-1921 54 0x5B,0x25,0xBC,0x06,0xA5,0x50,0x06,0xd4,0x45, // 1922-1924 63 0x4A,0xdA,0xB8,0x02,0xB6,0x4d,0x09,0x57,0x42, // 1925-1927 72 0x24,0x97,0xB7,0x04,0x97,0x4A,0x66,0x4B,0x3e, // 1928-1930 81 0x0d,0x4A,0x51,0x0e,0xA5,0x46,0x56,0xd4,0xBA, // 1931-1933 90 0x05,0xAd,0x4e,0x02,0xB6,0x44,0x39,0x37,0x38, // 1934-1936 99 0x09,0x2e,0x4B,0x7C,0x96,0xBf,0x0C,0x95,0x53, // 1937-1939 108 0x0d,0x4A,0x48,0x6d,0xA5,0x3B,0x0B,0x55,0x4f, // 1940-1942 117 0x05,0x6A,0x45,0x4A,0xAd,0xB9,0x02,0x5d,0x4d, // 1943-1945 126 0x09,0x2d,0x42,0x2C,0x95,0xB6,0x0A,0x95,0x4A, // 1946-1948 135 0x7B,0x4A,0xBd,0x06,0xCA,0x51,0x0B,0x55,0x46, // 1949-1951 144 0x55,0x5A,0xBB,0x04,0xdA,0x4e,0x0A,0x5B,0x43, // 1952-1954 153 0x35,0x2B,0xB8,0x05,0x2B,0x4C,0x8A,0x95,0x3f, // 1955-1957 162 0x0e,0x95,0x52,0x06,0xAA,0x48,0x7A,0xd5,0x3C, // 1958-1960 171 0x0A,0xB5,0x4f,0x04,0xB6,0x45,0x4A,0x57,0x39, // 1961-1963 180 0x0A,0x57,0x4d,0x05,0x26,0x42,0x3e,0x93,0x35, // 1964-1966 189 0x0d,0x95,0x49,0x75,0xAA,0xBe,0x05,0x6A,0x51, // 1967-1969 195 0x09,0x6d,0x46,0x54,0xAe,0xBB,0x04,0xAd,0x4f, // 1970-1972 207 0x0A,0x4d,0x43,0x4d,0x26,0xB7,0x0d,0x25,0x4B, // 1973-1975 216 0x8d,0x52,0xBf,0x0B,0x54,0x52,0x0B,0x6A,0x47, // 1976-1978 225 0x69,0x6d,0x3C,0x09,0x5B,0x50,0x04,0x9B,0x45, // 1979-1981 234 0x4A,0x4B,0xB9,0x0A,0x4B,0x4d,0xAB,0x25,0xC2, // 1982-1984 243 0x06,0xA5,0x54,0x06,0xd4,0x49,0x6A,0xdA,0x3d, // 1985-1987 252 0x0A,0xB6,0x51,0x09,0x37,0x46,0x54,0x97,0xBB, // 1988-1990 261 0x04,0x97,0x4f,0x06,0x4B,0x44,0x36,0xA5,0x37, // 1991-1993 270 0x0e,0xA5,0x4A,0x86,0xB2,0xBf,0x05,0xAC,0x53, // 1994-1996 279 0x0A,0xB6,0x47,0x59,0x36,0xBC,0x09,0x2e,0x50, // 1997-1999 288 0x0C,0x96,0x45,0x4d,0x4A,0xB8,0x0d,0x4A,0x4C, // 2000-2002 297 0x0d,0xA5,0x41,0x25,0xAA,0xB6,0x05,0x6A,0x49, // 2003-2005 306 0x7A,0xAd,0xBd,0x02,0x5d,0x52,0x09,0x2d,0x47, // 2006-2008 315 0x5C,0x95,0xBA,0x0A,0x95,0x4e,0x0B,0x4A,0x43, // 2009-2011 324 0x4B,0x55,0x37,0x0A,0xd5,0x4A,0x95,0x5A,0xBf, // 2012-2014 333 0x04,0xBA,0x53,0x0A,0x5B,0x48,0x65,0x2B,0xBC, // 2015-2017 342 0x05,0x2B,0x50,0x0A,0x93,0x45,0x47,0x4A,0xB9, // 2018-2020 351 0x06,0xAA,0x4C,0x0A,0xd5,0x41,0x24,0xdA,0xB6, // 2021-2023 360 0x04,0xB6,0x4A,0x69,0x57,0x3d,0x0A,0x4e,0x51, // 2024-2026 369 0x0d,0x26,0x46,0x5e,0x93,0x3A,0x0d,0x53,0x4d, // 2027-2029 378 0x05,0xAA,0x43,0x36,0xB5,0x37,0x09,0x6d,0x4B, // 2030-2032 387 0xB4,0xAe,0xBf,0x04,0xAd,0x53,0x0A,0x4d,0x48, // 2033-2035 396 0x6d,0x25,0xBC,0x0d,0x25,0x4f,0x0d,0x52,0x44, // 2036-2038 405 0x5d,0xAA,0x38,0x0B,0x5A,0x4C,0x05,0x6d,0x41, // 2039-2041 414 0x24,0xAd,0xB6,0x04,0x9B,0x4A,0x7A,0x4B,0xBe, // 2042-2044 423 0x0A,0x4B,0x51,0x0A,0xA5,0x46,0x5B,0x52,0xBA, // 2045-2047 432 0x06,0xd2,0x4e,0x0A,0xdA,0x42,0x35,0x5B,0x37, // 2048-2050 441 0x09,0x37,0x4B,0x84,0x97,0xC1,0x04,0x97,0x53, // 2051-2053 450 0x06,0x4B,0x48,0x66,0xA5,0x3C,0x0e,0xA5,0x4f, // 2054-2056 459 0x06,0xB2,0x44,0x4A,0xB6,0x38,0x0A,0xAe,0x4C, // 2057-2059 468 0x09,0x2e,0x42,0x3C,0x97,0x35,0x0C,0x96,0x49, // 2060-2062 477 0x7d,0x4A,0xBd,0x0d,0x4A,0x51,0x0d,0xA5,0x45, // 2063-2065 486 0x55,0xAA,0xBA,0x05,0x6A,0x4e,0x0A,0x6d,0x43, // 2066-2068 495 0x45,0x2e,0xB7,0x05,0x2d,0x4B,0x8A,0x95,0xBf, // 2069-2071 504 0x0A,0x95,0x53,0x0B,0x4A,0x47,0x6B,0x55,0x3B, // 2072-2074 513 0x0A,0xd5,0x4f,0x05,0x5A,0x45,0x4A,0x5d,0x38, // 2075-2077 522 0x0A,0x5B,0x4C,0x05,0x2B,0x42,0x3A,0x93,0xB6, // 2078-2080 531 0x06,0x93,0x49,0x77,0x29,0xBd,0x06,0xAA,0x51, // 2081-2083 540 0x0A,0xd5,0x46,0x54,0xdA,0xBA,0x04,0xB6,0x4e, // 2084-2086 549 0x0A,0x57,0x43,0x45,0x27,0x38,0x0d,0x26,0x4A, // 2087-2089 558 0x8e,0x93,0x3e,0x0d,0x52,0x52,0x0d,0xAA,0x47, // 2090-2092 567 0x66,0xB5,0x3B,0x05,0x6d,0x4f,0x04,0xAe,0x45, // 2093-2095 576 0x4A,0x4e,0xB9,0x0A,0x4d,0x4C,0x0d,0x15,0x41, // 2096-2098 585 0x2d,0x92,0xB5, // 2099 594 }; uchar code day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3}; uint code day_code2[3]={0x111,0x130,0x14e};//月修正数据表 uchar code week_code[12]={0,3,3,6,1,4,6,2,5,0,3,5}; struct{uint year;//日历结构体变量 uchar year1;//year1=year%100; uchar month; uchar day; uchar week; uchar h; uchar h12; uchar m; uchar s; uint time; uchar wei;//调整时指示调的是哪一位 }rili={2011,11,3,9,3,23,11,59,50,0,0}; struct{ uchar year; uchar month; uchar day; }yinli={0,0,0}; struct{uchar h; uchar m; //秒表结构体变量 uchar s; uint ms; uint time; }miao={0,0,0,0,0}; struct{uchar h; //倒计时结构体变量 uchar m; uchar s; uint time; uchar day; uchar wei; }daoji={0,0,0,0,0,0}; struct{ uchar h; uchar m; uchar s; uchar wei; }nao={0,0,0,0}; uchar time;//用于测温函数中 uchar goneng=0;/*0-日历功能,1-秒表,2-倒计时,3-闹钟*/ uchar wendu=18; uchar keynumber=0;//键值, uchar shanshou; bit yinyang=0;//1-显示阳历 bit on24=0;//0-单倍速 1-24倍速 bit on12=0;//0-24小时制,1-12小时制 bit clte=1;/*0时显示日期,1时显示时间*/ bit onoff=0;/*1-秒表开始,0-停止;*/ bit daojionoff=0;/*1-开始倒计时,0-停止*/ bit daojizhishi=0;/*1-倒计时结束*/ bit naoonoff=0;/*1-闹钟开始*/ bit naozhishi=0;/*1-闹钟响*/ /*************1ms基准延时*********/ void delay(uint i) { uchar j; while(i--) { for(j=0;j<115;j++) { ; } } } /**************计算某月的天数的子函数************/ uchar getmonthdays(uint year,uchar month) { uchar days; switch(month) { case 4: case 6: case 9: case 11:days=30;break; case 2:if(year%4==0)days=29; else days=28; break; default:days=31;break; } return days; } /*************根据日期计算星期**************/ void getweek(uint aa,uchar bb,uchar cc) { uchar c;//公元年份的前两位数 uchar y;//公元年份的后两位数 uint a1; char w;//表示星期 if(bb==1){aa=aa-1;bb=13;} if(bb==2){aa=aa-1;bb=14;} c=aa/100; y=aa%100; a1=26*(bb+1); w=(c/4+y+y/4+a1/10+cc-2*c-1); while(w<0){w=w+7;} rili.week=w%7; if(rili.week==0) rili.week=7; } /***************初始化程序******************/ void sys(void) { TMOD=0x22; // TMOD=0000 0010B,使定时器T0的模式2 EA=1; //开总中断 ET0=1; //允许定时器T0的中断 ET1=1; TR0=1; //启动T0 TH0=TL0=6; //计数器T0高8位赋初值6 TH1=TL1=255; } /***************刷新数码管一次***************/ void display( uchar a[8]) { uchar cnt; for(cnt=0;cnt<8;cnt++) { P0=DIS_SEG7[a[cnt]]; P2=DIS_BIT[cnt]; delay(2); P2=0xff; P0=0xff; } } /***************数组赋值********/ void update(uchar b[8],uchar i,uchar j,uchar m,uchar n) { b[0]=i/10; b[1]=i%10; b[2]=j/10; b[3]=j%10; b[4]=m/10; b[5]=m%10; b[6]=n/10; b[7]=n%10; } /************键盘扫描程序********************/ uchar key(void) { uchar number=0; uchar tem; tem=P1; if(tem!=0xff) { delay(5); //延时去抖动 if(tem!=0xff) { switch(tem) { case 0xfe:goneng++;if(goneng==5)goneng=0;break; case 0xfd:number=1;break; case 0xfb:number=2;break; case 0xf7:number=3;break; case 0xef:number=4;break; default: number=5;break; } while(P1!=0xff);//等待按键释放 } } return number; } uchar get_moon_day(uchar month_p,uint code_addr) /*读取数据表中农历月的大月或小月,如果该月大返回1,小返回0*/ { uchar temp,temp5; temp=0x80>>((month_p+3)%8); temp5=(month_p+3)/8; temp=year_code[code_addr+temp5]&temp; if(temp==0){return(29);}else{return(30);} } void zhuanhuan(uint a,char b,uchar c) /*==转换当前农历信息====================================*/ { uchar temp1,temp2,temp3,month_p,d,t,year,month,day; uint temp4,code_addr; bit flag_y; if(a>=2000)d=0; else d=0x80; t=(a%100)|(d&0x80); year=t&0x7f; //加载年月日数据,如为BCD则需转为十进制 month=b; day =c; code_addr=year-1; //定位数据表地址 if(t>>7==0)code_addr+=0x64; code_addr*=3; temp1=(year_code[code_addr+2]&0x60)>>5; //取当年春节所在的公历月份 temp2=year_code[code_addr+2]&0x1f; //取当年春节所在的公历日 temp3=temp2-1; //计算当年春节离当年元旦的天数,春节只会在公历1月或2月 if(temp1!=1)temp3+=31; //如果不在1月则天数加上31天(1月) if(month<10){temp4=day_code1[month-1]+day;} else{temp4=day_code2[month-10]+day;} if((month<=2)||(year%0x04!=0))temp4-=1; //如果公历月小于等于2月或者该年的2月非闰月,天数减1 temp2=(year_code[code_addr]&0xf0)>>4; //从数据表中取该年的闰月月份,如为0则该年无闰月 if (temp4>=temp3) //判断公历日在春节前还是春节后 { //公历日在春节后或就是春节当日使用下面代码进行运算 temp4 -=temp3; month = 1; flag_y = 0; month_p= 1; //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月 temp1=get_moon_day(month_p,code_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0 while(temp4>=temp1) { temp4-=temp1; month_p+=1; if(month==temp2) { flag_y=~flag_y; if(flag_y==0)month+=1; }else{month+=1;} temp1=get_moon_day(month_p,code_addr); } day=temp4+1; } else { //公历日在春节前使用下面代码进行运算 temp3-=temp4; if(year==0){year=0xe3;}else{year-=1;} code_addr-=3; month = 12; flag_y = 0; if(temp2==0){month_p=12;}else{month_p=13;} //如果当年有闰月,一年有十三个月,月指向13,无闰月指向12 temp1=get_moon_day(month_p,code_addr); while(temp3>temp1) { temp3-=temp1; month_p-=1; if(flag_y==0)month-=1; if(month==temp2)flag_y=~flag_y; temp1=get_moon_day(month_p,code_addr); } day=temp1-temp3+1; } yinli.year=year%100; yinli.month=month; yinli.day=day; } /***************测温函数******************/ /***************************************************** 函数功能:将DS18B20传感器初始化,读取应答信号 出口参数:flag ***************************************************/ bit Init_DS18B20(void) { bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在 DQ = 1; //先将数据线拉高 for(time=0;time<2;time++) //略微延时约6微秒 ; DQ = 0; //再将数据线从高拉低,要求保持480~960us for(time=0;time<200;time++) //略微延时约600微秒 ; //以向DS18B20发出一持续480~960us的低电平复位脉冲 DQ = 1; //释放数据线(将数据线拉高) for(time=0;time<10;time++) ; //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲) flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在) for(time=0;time<80;time++) //延时足够长时间,等待存在脉冲输出完毕 ; return (flag); //返回检测成功标志 } /***************************************************** 函数功能:从DS18B20读取一个字节数据 出口参数:dat ***************************************************/ unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat; //储存读出的一个字节数据 for (i=0;i<8;i++) { DQ =1; // 先将数据线拉高 _nop_(); //等待一个机器周期 DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序 _nop_(); //等待一个机器周期 DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备 for(time=0;time<2;time++) ; //延时约6us,使主机在15us内采样 dat>>=1; if(DQ==1) dat|=0x80; //如果读到的数据是1,则将1存入dat else dat|=0x00;//如果读到的数据是0,则将0存入dat //将单片机检测到的电平信号DQ存入r[i] for(time=0;time<20;time++) ; //延时60us,两个读时序之间必须有大于1us的恢复期 } return(dat); //返回读出的十六进制数据 } /***************************************************** 函数功能:向DS18B20写入一个字节数据 入口参数:dat ***************************************************/ WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=0; i<8; i++) { DQ =1; // 先将数据线拉高 _nop_(); //等待一个机器周期 DQ=0; //将数据线从高拉低时即启动写时序 DQ=dat&0x01; //利用与运算取出要写的某位二进制数据, //并将其送到数据线上等待DS18B20采样 for(time=0;time<10;time++) ;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样 DQ=1; //释放数据线 for(time=0;time<10;time++) ;//延时30us,两个写时序间至少需要1us的恢复期 dat>>=1; //将dat中的各二进制位数据右移1位 } for(time=0;time<4;time++) ; //稍作延时,给硬件一点反应时间 } /***************************************************** 函数功能:做好读温度的准备 ***************************************************/ void ReadyReadTemp(void) { Init_DS18B20(); //将DS18B20初始化 WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 delay(100); //转换一次需要延时一段时间 Init_DS18B20(); //将DS18B20初始化 WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位 } void cewen(void) { uchar TL; //储存暂存器的温度低位 uchar TH; //储存暂存器的温度高位 ReadyReadTemp(); //读温度准备 TL=ReadOneChar(); //先读的是温度值低位 TH=ReadOneChar(); //接着读的是温度值高位 wendu=TH*16+TL/16; //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16 } /***************日历功能程序**************/ void rilimoshi(uchar i) { if(i==1) { rili.wei++; if(rili.wei==7) { rili.wei=0; } } if(i==4)yinyang=!yinyang; if(i==5){on24=!on24;rili.time=0;} if(rili.wei!=0)//进行调整 { if(i==2) { switch(rili.wei) { case 1:rili.year++;break; case 2:rili.month++;if(rili.month==13)rili.month=1;break; case 3:rili.day++;if(rili.day==(getmonthdays(rili.year,rili.month)+1))rili.day=1;break; case 4:rili.h++;if(rili.h==24)rili.h=0;break; case 5:rili.m++;if(rili.m==60)rili.m=0;break; default:rili.s++;if(rili.s==60)rili.s=0;break; } } if(i==3) { switch(rili.wei) { case 1:rili.year--;break; case 2:rili.month--;if(rili.month==0)rili.month=12;break; case 3:rili.day--;if(rili.day==0)rili.day=getmonthdays(rili.year,rili.month);break; case 4:if(rili.h==0)rili.h=23;else rili.h--;break; case 5:if(rili.m==0)rili.m=59;else rili.m--;break; default:if(rili.s==0)rili.s=59;else rili.s--;break; } } getweek(rili.year,rili.month,rili.day); rili.year1=rili.year%100; update(datestr,rili.year1,rili.month,rili.day,rili.week); datestr[6]=10; if(on12==1)//转换成12小时制 { if(rili.h>=12) { rili.h12=rili.h-12; } else rili.h12=rili.h; update(clockstr,rili.h12,rili.m,rili.s,wendu); } else update(clockstr,rili.h,rili.m,rili.s,wendu); if(rili.wei<=3) { shanshou++; if(shanshou<=20) { switch(rili.wei) { case 1:datestr[1]=10;break; case 2:datestr[3]=10;break; default:datestr[5]=10;break; } } else if(shanshou==40)shanshou=0; display(datestr); } else { shanshou++; if(shanshou<=20) { switch(rili.wei) { case 4:clockstr[1]=10;break; case 5:clockstr[3]=10;break; default:clockstr[5]=10;break; } } else if(shanshou==40)shanshou=0; display(clockstr); } } else { if(yinyang!=0) { zhuanhuan(rili.year,rili.month,rili.day); getweek(rili.year,rili.month,rili.day); update(yindatestr,yinli.year,yinli.month,yinli.day,rili.week); yindatestr[6]=10; if(on12==1)//转换成12小时制 { if(rili.h>=12) { rili.h12=rili.h-12; } else rili.h12=rili.h; update(clockstr,rili.h12,rili.m,rili.s,wendu); } else update(clockstr,rili.h,rili.m,rili.s,wendu); if(clte==1) display(yindatestr); else display(clockstr); } else { getweek(rili.year,rili.month,rili.day); rili.year1=rili.year%100; update(datestr,rili.year1,rili.month,rili.day,rili.week); datestr[6]=10; if(on12==1)//转换成12小时制 { if(rili.h>=12) { rili.h12=rili.h-12; } else rili.h12=rili.h; update(clockstr,rili.h12,rili.m,rili.s,wendu); } else update(clockstr,rili.h,rili.m,rili.s,wendu); if(clte==1) display(datestr); else display(clockstr); } } } /*************日历模式定时器的函数************/ void rilidingshi(void) { rili.time++; if((rili.time==167)&&(on24==1)) //167一小时慢2分钟 166一小时快6分钟 { rili.time=0; rili.s++; if(rili.s==60) { rili.s=0; rili.m++; if(rili.m%2==0){clte=~clte;} if(rili.m==60) { rili.m=0; rili.h++; if(rili.h==24) { rili.h=0; rili.day++; switch(rili.month) { case 4: case 6: case 9: case 11:if(rili.day==31){rili.day=1; rili.month++;}break; case 2:if(rili.year%4==0){if(rili.day==30) {rili.day=1;rili.month++;} } else {if(rili.day==29){ rili.day=1;rili.month++;}} break; default:if(rili.day==32){rili.day=1;rili.month++;}break; } if(rili.month==13) { rili.month=1; rili.year++; } } } } } else if(rili.time==3988) //3987-13小时快13秒 { rili.time=0; rili.s++; if(rili.s%5==0){clte=~clte;}; if(rili.s==60) { rili.s=0; rili.m++; if((goneng==0)&&(yinyang==0))TR1=1;//开定时器2测温; if(rili.m==60) { rili.m=0; rili.h++; if(rili.h==24) { rili.h=0; rili.day++; switch(rili.month) { case 4: case 6: case 9: case 11:if(rili.day==31){rili.day=1; rili.month++;}break; case 2:if(rili.year%4==0){if(rili.day==30) {rili.day=1;rili.month++;} } else {if(rili.day==29){ rili.day=1;rili.month++;}} break; default:if(rili.day==32){rili.day=1;rili.month++;}break; } if(rili.month==13) { rili.month=1; rili.year++; } } } } } } /*************倒计时功能函数*************/ void daojimoshi(uchar k) { if(k==1) // 开始 { daoji.wei++; if(daoji.wei==5) {daoji.wei=0;daojionoff=1;} } if(k==4) //停止并清零 { daojionoff=!daojionoff; daojizhishi=0; daoji.day=daoji.h=daoji.m=daoji.s=0; } if((daoji.wei!=0)) { if(k==2) { switch(daoji.wei) { case 1:daoji.day++;if(daoji.day==99)daoji.day=0;break; case 2:daoji.h++;if(daoji.h==24)daoji.h=0;break; case 3:daoji.m++;if(daoji.m==60)daoji.m=0;break; default:daoji.s++;if(daoji.s==60)daoji.s=0;break; } } if(k==3) { switch(daoji.wei) { case 1:if(daoji.day==0)daoji.day=99;else daoji.day--;break; case 2:if(daoji.h==0)daoji.h=23;else daoji.h--;break; case 3:if(daoji.m==0)daoji.m=59;else daoji.m--;break; default:if(daoji.s==0)daoji.s=59;else daoji.s--;break; } } update(daoclockstr,daoji.day,daoji.h,daoji.m,daoji.s); shanshou++; if(shanshou<=20) { switch(daoji.wei) { case 1:daoclockstr[1]=10;break; case 2:daoclockstr[3]=10;break; case 3:daoclockstr[5]=10;break; default:daoclockstr[7]=10;break; } } else if(shanshou==40)shanshou=0; display(daoclockstr); } else { update(daoclockstr,daoji.day,daoji.h,daoji.m,daoji.s); display(daoclockstr); } } /***************倒计时模式定时器函数**********/ void daojidingshi(void) { daoji.time++; if(daoji.time==4000) { daoji.time=0; if(daoji.s!=0)daoji.s--; else { daoji.s=59; if(daoji.m!=0)daoji.m--; else { daoji.m=59; if(daoji.h!=0)daoji.h--; else { daoji.h=23; if(daoji.day!=0)daoji.day--; } } } } } /**************闹钟功能函数**************/ void naomoshi(uchar m) { if(m==1) // 开始 { nao.wei++; if(nao.wei==4) {nao.wei=0;naoonoff=1;} } if(m==4) //关闭闹钟 { naoonoff=!naoonoff; naozhishi=0; nao.h=nao.m=nao.s=0; } if((nao.wei!=0)) { if(m==2) { switch(nao.wei) { case 1:nao.h++;if(nao.h==24)nao.h=0;break; case 2:nao.m++;if(nao.m==60)nao.m=0;break; default:nao.s++;if(nao.s==60)nao.s=0;break; } } if(m==3) { switch(nao.wei) { case 1:if(nao.h==0)nao.h=23;else nao.h--;break; case 2:if(nao.m==0)nao.m=59;nao.m--;break; default:if(nao.s==0)nao.s=59;else nao.s--;break; } } update(naoclockstr,nao.h,nao.m,nao.s,nao.s); naoclockstr[6]=naoclockstr[7]=10; shanshou++; if(shanshou<=20) { switch(nao.wei) { case 1:naoclockstr[1]=10;break; case 2:naoclockstr[3]=10;break; default:naoclockstr[5]=10;break; } } else if(shanshou==40)shanshou=0; display(naoclockstr); } else { update(naoclockstr,nao.h,nao.m,nao.s,nao.s); naoclockstr[6]=naoclockstr[7]=10; display(naoclockstr); } } /***************秒表功能函数*************/ void miaobiaomoshi( uchar j) { if(j==1)//开始 { onoff=1; } if(j==2)//停止 { onoff=0; } if(j==3)//清零 { onoff=0; miao.h=miao.ms=miao.s=miao.m=miao.time=0; } update(miaostr,miao.h,miao.m,miao.s,miao.ms); display(miaostr); } /********秒表模式定时器函数******/ void miaobiaodingshi(void) { miao.time++; if(miao.time==40) { miao.time=0; miao.ms++; if(miao.ms==100) { miao.ms=0; miao.s++; if(miao.s==60) { miao.s=0; miao.m++; if(miao.m==60) { miao.m=0; miao.h++; } } } } } /****************主程序*******************/ void main(void) { sys(); cewen(); while(1) { if((daoji.day==0)&&(daoji.h==0)&&(daoji.m==0)&&(daoji.s==0)&&(daojionoff==1)) daojizhishi=1; if((nao.h==rili.h)&&(nao.m==rili.m)&&(nao.s==rili.s)&&(naoonoff==1)) naozhishi=1; if((rili.m==0)&&(rili.s<5)&&(rili.wei==0)) //正点报时 { beep=0; } else beep=1; if(daojizhishi==1) //倒计时报警指示灯 LED5=0; else LED5=1; if(naozhishi==1) //闹钟报警指示灯 LED6=0; else LED6=1; keynumber=key(); if(goneng==0) { on12=0; rilimoshi(keynumber); LED1=0; //日历前台工作指示灯 } if(goneng==1) { on12=1; rilimoshi(keynumber); LED1=0; } if((goneng!=0)&&(goneng!=1)) LED1=1; if(goneng==2) { miaobiaomoshi(keynumber); LED2=0; //秒表前台工作指示灯 } else LED2=1; if(goneng==3) { daojimoshi(keynumber); LED3=0; //倒计时前台工作指示灯 } else LED3=1; if(goneng==4) { naomoshi(keynumber); LED4=0; //闹钟前台工作指示灯 } else LED4=1; } } /***************定时器0中断程序**************/ void timer0(void)interrupt 1 using 1 { if((daojionoff==1)&&(daojizhishi==0)&&(daoji.wei==0)) daojidingshi(); if(onoff==1) miaobiaodingshi(); if(rili.wei==0) rilidingshi(); } /**************定时器1中断程序***************/ void timer1(void )interrupt 3 { TR0=TR1=0; cewen(); TR0=1; } 显示模块 单片机控制模块 温度传感器模块 按键输入模块 工作指示灯模块 语音报时模块
本文档为【单片机电子万年历设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: ¥17.0 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
北溟愚鱼
暂无简介~
格式:doc
大小:358KB
软件:Word
页数:0
分类:工学
上传时间:2018-09-21
浏览量:29