|
STC12C5A60S2+DS1302+DS18B20+LCD1602,晶振11.0592M
主要功能:時(shí)間溫度顯示,設(shè)置一個(gè)鬧表
溫度大于30度LED亮起,鬧表時(shí)間時(shí)分對(duì)應(yīng)LED閃爍
4個(gè)按鍵分別對(duì)應(yīng)設(shè)置、時(shí)間+、時(shí)間—、退出設(shè)置
鬧表時(shí)間保存于DS1302的RAM區(qū)。
開(kāi)發(fā)中間遇到的主要問(wèn)題:
一、STC12C5A60S2是1T的芯片,運(yùn)行速度比89C52快,延時(shí)函數(shù)需要調(diào)整
二、DS1302模塊與STC12的連接線不能過(guò)長(zhǎng),調(diào)試過(guò)程開(kāi)始線路過(guò)長(zhǎng),讀取模塊的結(jié)果會(huì)是0xff,各種找原因也不能解決,程序改得亂七八糟。各種百度各種改,最后看到一條有說(shuō)線路過(guò)長(zhǎng)可能是原因。最終對(duì)線路測(cè)量,兩段線電阻分別為0.4歐和0.5歐,長(zhǎng)度分別為7cm和15cm,最終理論解決希望有大佬能夠幫忙解釋。
電路原理圖如下:

上圖是初始電路圖,圖中芯片為89C52,后改為STC12C5A60S2,個(gè)別細(xì)節(jié)
11.jpg (5.69 MB, 下載次數(shù): 96)
下載附件
2021-3-24 19:07 上傳
1.jpg (5.23 MB, 下載次數(shù): 65)
下載附件
2021-3-24 19:04 上傳
1.jpg (212.44 KB, 下載次數(shù): 72)
下載附件
2021-3-24 21:34 上傳
上圖為最終結(jié)果
上圖上面箭頭為原來(lái)DS1302用排線連接位置,下面是最終位置
顯示全是????
單片機(jī)源程序如下:
- #include "STC12C5A60S2.H"
- #include <intrins.h>
- #include "delay.h"
- #include "lcd1602.h"
- #include "ds18b20.h"
- #include "ds1302.h"
- sbit led= P3^7;//led燈,替代蜂鳴器
- uchar count=0; //計(jì)時(shí)器計(jì)數(shù)
- uint temperature=0; //溫度,取實(shí)際溫度的10倍,輸出時(shí)最后一位前加小數(shù)點(diǎn)
- float ftempp; //浮點(diǎn)型溫度
- uchar *p1,*p2,*p3,*p4;//定義指針,分別對(duì)應(yīng)日期,時(shí)間,芯片格式數(shù)據(jù),設(shè)置光標(biāo)位置
- uchar mdate[16];//用于顯示日期"20xx-xx-xx Mon."
- uchar mtime[9],ntime[6];//用于顯示時(shí)間"xx:xx:xx"和鬧表時(shí)間"XX:XX"末位寫0用于結(jié)束字符串輸出
- uchar stime[2];//用于保存鬧鐘時(shí)間
- uchar ttime[7];//={0x48,0x48,0x22,0x028,0x05,0x06,0x18};//用于初始化DS1302,和讀取時(shí)間
- sbit key1=P2^7;//時(shí)間調(diào)整按鍵,1設(shè)置
- sbit key2=P2^6;//2加
- sbit key3=P2^5;//3減
- sbit key4=P2^4;//4退出
- uchar n,stat=0;//設(shè)置狀態(tài)標(biāo)志,0為正常顯示狀態(tài)
- //1-9為設(shè)置狀態(tài)1-年、2-月、3-日、4-周、5-時(shí)、6-分、7-秒、8-鬧表時(shí)、9-鬧表分
- uchar isryear(uchar year1)
- {
- int year,isrun;
- //判斷是否閏年,1為閏年,0為平年
- year=2000+year1/16*10+year1%16;
- if(year%4==0)
- {
- if(year%100!=0)
- {
- isrun=1;
- }
- else if(year%400)
- {
- isrun=1;
- }
- else
- {
- isrun=0;
- }
- }
- else
- {
- isrun=0;
- }
- return isrun;
- }
- void keyscan(uchar *tempt,uchar *stime)
- {
- uchar isrun;
- if(key1==0)//設(shè)置
- {
- delayms(30);
- if(key1==0)
- {
- stat++;//設(shè)置標(biāo)志在0--9之間變化,0為正常顯示狀態(tài),1--7打開(kāi)光標(biāo)閃爍并在7個(gè)時(shí)間選項(xiàng)中移動(dòng),8、9鬧表時(shí)間
- if(stat>9)
- stat=1;
- }
- while(!key1);
- }
- if(key2==0)//選中位置+1
- {
- delayms(30);
- if(key2==0)
- {
- switch(stat)
- {
- case 1://年
- {
- tempt[6]++;
- if((tempt[6]&0x0f)==0x0a)//逢10進(jìn)1
- {
- tempt[6]+=0x10;
- tempt[6]=tempt[6]&0xf0;
- if(tempt[6]==0xa0)//逢100變0
- tempt[6]=0x00;
- }
- //判斷平年閏年2月是否溢出
- isrun=isryear(tempt[6]);
- if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
- tempt[3]=0x29;
- else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
- tempt[3]=0x28;
- break;
- }
- case 2://月
- {
- tempt[4]+=0x01;
- if((tempt[4]&0x0f)==0x0a)//逢10進(jìn)1
- {
- tempt[4]+=0x10;//前4位進(jìn)位
- tempt[4]=tempt[4]&0xf0;//后4位置0
- }
- if(((tempt[4]&0x0f)==0x03)&((tempt[4]&0xf0)==0x10))//逢13變1
- tempt[4]=0x01;
- //檢查調(diào)整月之后的日期有沒(méi)有溢出
- isrun=isryear(tempt[6]);
- if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))//29天月
- tempt[3]=0x29;
- else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))//28天月
- tempt[3]=0x28;
- else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)//31天月
- ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
- ||(tempt[4]==0x12))&&(tempt[3]>0x31))
- tempt[3]=0x31;
- else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)//30天月
- ||(tempt[4]==0x11))&&(tempt[3]>0x30))
- tempt[3]=0x30;
- break;
- }
- case 3://日
- {
- tempt[3]+=0x01;
- if((tempt[3]&0x0f)==0x0a)//逢10進(jìn)1
- {
- tempt[3]+=0x10;
- tempt[3]=tempt[3]&0xf0;
- }
- //檢查調(diào)整月之后的日期有沒(méi)有溢出
- isrun=isryear(tempt[6]);
- if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
- tempt[3]=0x01;
- else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
- tempt[3]=0x01;
- if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
- ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
- ||(tempt[4]==0x12))&&(tempt[3]==0x32))
- tempt[3]=0x01;
- if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
- ||(tempt[4]==0x11))&&(tempt[3]==0x31))
- tempt[3]=0x01;
- break;
- }
- case 4://星期
- {
- tempt[5]+=0x01;
- if(tempt[5]>0x07)
- tempt[5]=0x01;
- break;
- }
- case 5://時(shí)
- {
- tempt[2]+=0x01;
- if((tempt[2]&0x0f)==0x0a)
- {
- tempt[2]+=0x10;
- tempt[2]=tempt[2]&0xf0;
- }
- if(((tempt[2]&0x0f)==0x04)&((tempt[2]&0xf0)==0x20))
- tempt[2]=0x00;
- break;
- }
- case 6://分
- {
- tempt[1]+=0x01;
- if((tempt[1]&0x0f)==0x0a)
- {
- tempt[1]+=0x10;
- tempt[1]=tempt[1]&0xf0;
- }
- if(tempt[1]==0x60)
- tempt[1]=0x00;
- break;
- }
- case 7://秒
- {
- tempt[0]+=0x01;
- if((tempt[0]&0x0f)==0x0a)
- {
- tempt[0]+=0x10;
- tempt[0]=tempt[0]&0xf0;
- }
- if(tempt[0]==0x60)
- tempt[0]=0x00;
- break;
- }
- case 8://鬧表時(shí)
- {
- stime[1]+=0x01;
- if((stime[1]&0x0f)==0x0a)
- {
- stime[1]+=0x10;
- stime[1]=stime[1]&0xf0;
- }
- if(((stime[1]&0x0f)==0x04)&&((stime[1]&0xf0)==0x20))
- stime[1]=0x00;
- Ds1302Write(0x8e,0x00);//關(guān)閉寫保護(hù)
- Ds1302Write(0xc0,stime[0]);
- Ds1302Write(0xc2,stime[1]);
- Ds1302Write(0x8e,0x80);//打開(kāi)寫保護(hù)
- break;
- }
- case 9://鬧表分
- {
- stime[0]+=0x01;
- if((stime[0]&0x0f)==0x0a)
- {
- stime[0]+=0x10;
- stime[0]=stime[0]&0xf0;
- }
- if(((stime[0]&0x0f)==0x00)&&((stime[0]&0xf0)==0x60))
- stime[0]=0x00;
- Ds1302Write(0x8e,0x00);//關(guān)閉寫保護(hù)
- Ds1302Write(0xc0,stime[0]);
- Ds1302Write(0xc2,stime[1]);
- Ds1302Write(0x8e,0x80);//打開(kāi)寫保護(hù)
- break;
- }
- }
- }
- while(!key2);
- }
- if(key3==0)//選中位置-1
- {
- delayms(30);
- if(key3==0)
- {
- switch(stat)
- {
- case 1://年
- {
- if(tempt[6]==0x00)//逢00變99
- tempt[6]=0x99;
- else if((tempt[6]&0x0f)==0x00)//逢0進(jìn)9
- {
- tempt[6]-=0x10;
- tempt[6]=tempt[6]|0x09;
- }
- else tempt[6]--;
- //檢查調(diào)整月之后的日期有沒(méi)有溢出
- isrun=isryear(tempt[6]);
- //判斷平年閏年2月是否溢出
- if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
- tempt[3]=0x29;
- else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
- tempt[3]=0x28;
- break;
- }
- case 2://月
- {
- if(((tempt[4]&0x0f)==0x01)&((tempt[4]&0xf0)==0x00))//逢1變12
- tempt[4]=0x12;
- else if((tempt[4]&0x0f)==0x00)//10變9
- {
- tempt[4]=0x09;
- }
- else tempt[4]-=0x01;
- //檢查調(diào)整月之后的日期有沒(méi)有溢出
- isrun=isryear(tempt[6]);
- if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
- tempt[3]=0x29;
- else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
- tempt[3]=0x28;
- else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
- ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
- ||(tempt[4]==0x12))&&(tempt[3]>0x31))
- tempt[3]=0x31;
- else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
- ||(tempt[4]==0x11))&&(tempt[3]>0x30))
- tempt[3]=0x30;
- break;
- }
- case 3://日
- {
- //檢查調(diào)整月之后的日期有沒(méi)有溢出
- isrun=isryear(tempt[6]);
- if((tempt[4]==0x02)&&(tempt[3]==0x01)&&(isrun==1))
- tempt[3]=0x29;
- else if((tempt[4]==0x02)&&(tempt[3]==0x01)&&(isrun==0))
- tempt[3]=0x28;
- else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
- ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
- ||(tempt[4]==0x12))&&(tempt[3]==0x01))
- tempt[3]=0x31;
- else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
- ||(tempt[4]==0x11))&&(tempt[3]==0x01))
- tempt[3]=0x30;
- else if((tempt[3]&0x0f)==0x00)//逢0借1變9
- {
- tempt[3]-=0x10;
- tempt[3]=tempt[3]|0x09;
- }
- else tempt[3]-=0x01;
- break;
- }
- case 4://星期
- {
- tempt[5]-=0x01;
- if(tempt[5]==0x00)
- tempt[5]=0x07;
- break;
- }
- case 5://時(shí)
- {
- if(tempt[2]==0x00)
- tempt[2]=0x23;
- else if((tempt[2]&0x0f)==0x00)
- {
- tempt[2]-=0x10;
- tempt[2]=tempt[2]|0x09;
- }
- else tempt[2]-=0x01;
- break;
- }
- case 6://分
- {
- if(tempt[1]==0x00)
- {
- tempt[1]=0x59;
- }
- else if((tempt[1]&0x0f)==0x00)
- {
- tempt[1]-=0x10;
- tempt[1]=tempt[1]|0x09;
- }
- else tempt[1]-=0x01;
- break;
- }
- case 7://秒
- {
- if(tempt[0]==0x00)
- tempt[0]=0x59;
- else if((tempt[0]&0x0f)==0x00)
- {
- tempt[0]-=0x10;
- tempt[0]=tempt[0]|0x09;
- }
- else tempt[0]-=0x01;
- break;
- }
- case 8://鬧表時(shí)
- {
- if(stime[1]==0x00)
- stime[1]=0x23;
- else if((stime[1]&0x0f)==0x00)
- {
- stime[1]-=0x10;
- stime[1]=stime[1]|0x09;
- }
- else stime[1]-=0x01;
- Ds1302Write(0x8e,0x00);//關(guān)閉寫保護(hù)
- Ds1302Write(0xc0,stime[0]);
- Ds1302Write(0xc2,stime[1]);
- Ds1302Write(0x8e,0x80);//打開(kāi)寫保護(hù)
- break;
- }
- case 9://鬧表分
- {
- if(stime[0]==0x00)
- stime[0]=0x59;
- else if((stime[0]&0x0f)==0x00)
- {
- stime[0]-=0x10;
- stime[0]=stime[0]|0x09;
- }
- else stime[0]-=0x01;
- Ds1302Write(0x8e,0x00);//關(guān)閉寫保護(hù)
- Ds1302Write(0xc0,stime[0]);
- Ds1302Write(0xc2,stime[1]);
- Ds1302Write(0x8e,0x80);//打開(kāi)寫保護(hù)
- break;
- }
- }
- }
- while(!key3);
- }
- if(key4==0)//設(shè)置
- {
- delayms(30);
- if(key4==0)
- {
- stat=0;
- }
- while(!key4);
- //退出設(shè)置讀取鬧表時(shí)間
- stime[0]=Ds1302Read(0xc1);
- stime[1]=Ds1302Read(0xc3);
- }
- if(stat>0)
- {
- Ds1302Write(0x8e,0x00);//關(guān)閉寫保護(hù)
- for(n=0;n<8;n++){
- Ds1302Write(WRITE_RTC_ADDR[n],tempt[n]);
- }
- Ds1302Write(0x8e,0x80);//打開(kāi)寫保護(hù)
- }
- }
- void showtime()//顯示正常時(shí)間
- {
- Ds1302readTime(p3);//讀取時(shí)間
- dispros(p1,p2,p3);//轉(zhuǎn)換時(shí)間
- Lcdwritedat(0x80,mdate);//顯示日期
- Lcdwritedat(0x80+0x40,mtime);//顯示時(shí)間
- }
- void showntime()//顯示鬧表設(shè)置
- {
- stime[0]=Ds1302Read(0xc1);
- stime[1]=Ds1302Read(0xc3);
- ntime[0]=stime[1]/16+0x30;
- ntime[1]=stime[1]%16+0x30;
- ntime[2]=':';
- ntime[3]=stime[0]/16+0x30;
- ntime[4]=stime[0]%16+0x30;
- ntime[5]=0;
- Lcdwritedat(0x80,"Set Alarm Time: ");
- Lcdwritedat(0x80+0x40,ntime);//顯示時(shí)間
- Lcdwritedat(0x80+0x40+5," ");//顯示溫度之前空格
- }
- void Timer0Init()
- {
- TMOD=0x01; //設(shè)置定時(shí)器0工作方式為1
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- ET0=1; //開(kāi)啟定時(shí)器0中斷
- TR0=1; //開(kāi)啟定時(shí)器
- EA=1; //打開(kāi)總中斷
- }
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼 全部代碼51hei下載地址:
萬(wàn)年歷.zip
(74.74 KB, 下載次數(shù): 100)
2021-3-24 19:11 上傳
點(diǎn)擊文件名下載附件
參考各種例程,最終版本 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|