加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入

基于51單片機(jī)的DS12C887電子鐘萬(wàn)年歷帶農(nóng)歷溫度

08/22 13:52
4444
服務(wù)支持:
技術(shù)交流群

完成交易后在“購(gòu)買(mǎi)成功”頁(yè)面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長(zhǎng)和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購(gòu)買(mǎi)后不支持退換且無(wú)法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
實(shí)物圖
相關(guān)方案
  • 方案介紹
    • 基于51單片機(jī)的DS12C887電子鐘萬(wàn)年歷( proteus仿真+程序+講解視頻)
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

基于51單片機(jī)的DS12C887電子鐘萬(wàn)年歷( proteus仿真+程序+講解視頻)

仿真圖proteus 7.8及以上

程序編譯器:keil 4/keil 5

編程語(yǔ)言:C語(yǔ)言

設(shè)計(jì)編號(hào):S0028

講解視頻


基于51單片機(jī)的DS12C887萬(wàn)年歷帶農(nóng)歷溫度顯示仿真設(shè)計(jì)

主要功能:

結(jié)合實(shí)際情況,基于51單片機(jī)設(shè)計(jì)一個(gè)電子鐘萬(wàn)年歷。該系統(tǒng)應(yīng)滿足的功能要求為:

DS12C887時(shí)鐘芯片,LED顯示、獨(dú)立鍵盤(pán)、農(nóng)歷顯示、溫度顯示。

具體功能:

1、采用DS12C887記錄日歷和時(shí)間。

2、 通過(guò)數(shù)碼管顯示,可以顯示新歷年月日時(shí)分秒,農(nóng)歷和星期,帶有溫度顯示。

3、可以按照實(shí)際,通過(guò)按鍵設(shè)置日期、時(shí)間。

以下為本設(shè)計(jì)資料展示圖:

仿真圖

主圖

img

開(kāi)始仿真

img

開(kāi)始顯示程序設(shè)置的初始時(shí)間,三組數(shù)碼管分別顯示年月日,時(shí)鐘分鐘秒、農(nóng)歷日期和溫度??梢酝ㄟ^(guò)按鍵調(diào)整時(shí)間。

設(shè)置鍵按下第一下設(shè)置分鐘,第二下設(shè)置時(shí)鐘,第三下設(shè)置星期,第四下設(shè)置日期,第五下設(shè)置月份,第六下設(shè)置年份,第七下退出設(shè)置。通過(guò)按鍵DOWN和按鍵UP調(diào)整數(shù)值加減。如果已經(jīng)調(diào)整好日期時(shí)間,按OUT按鍵可以退出設(shè)置。

程序:

img

img

ds12c887初始化和調(diào)用

#include "main.h"
#include "ds12c887.h"



void DS12C887_write(uchar add,uchar dat)  //寫(xiě)
{
	DS12C887_CS=0;
    DS12C887_AS=1;
	DS12C887_DS=1;
	DS12C887_WR=1;
	DS12C887_DATA=add;
	DS12C887_AS=0;
	DS12C887_WR=0;
	DS12C887_DATA=dat;
	DS12C887_WR=1;
	DS12C887_AS=1;
	DS12C887_CS=1;	
} 

uchar DS12C887_read(uchar add)	//讀
{
	uchar ds_date;
	DS12C887_AS=1;
	DS12C887_DS=1;
	DS12C887_WR=1;
	DS12C887_CS=0;
	DS12C887_DATA=add;
	DS12C887_AS=0;
	DS12C887_DS=0;
	DS12C887_DATA=0xff;
	ds_date=DS12C887_DATA;
	DS12C887_DS=1;
	DS12C887_AS=1;
	DS12C887_CS=1;
	return ds_date;		
}

void DS12C887_Gettime()	   //獲取DS12C887時(shí)間
{

	time_year  =DS12C887_read(0x09);	//年	
	time_month =DS12C887_read(0x08);	//月
	time_day  = DS12C887_read(0x07);	//日
	time_week  =DS12C887_read(0x06);	//周
	time_hour  =DS12C887_read(0x04);	//是
	time_min  = DS12C887_read(0x02);	//分
	time_sec =  DS12C887_read(0x00);	//秒
}

void DS12C887_Settime() ///設(shè)置初始時(shí)間
{
	DS12C887_write(0x09,0x16);	//年22	0x16->22
	DS12C887_write(0x08,0x0C);	//月12	0x0C->12
	DS12C887_write(0x07,0x0C);	//日11	0x0B->11
	DS12C887_write(0x06,0x01);	//周1	
	DS12C887_write(0x04,0x17);	//時(shí)23					 
	DS12C887_write(0x02,0x3B);	//分59
	DS12C887_write(0x00,0x32);	//秒50
}  

void DS12C887_init()	//DS12C887初始化
{
	DS12C887_write(0x0a,0x20); //DS12CR887寄存器A功能設(shè)置,開(kāi)啟時(shí)鐘振蕩器
	DS12C887_write(0x0b,0x06); //寄存器B功能設(shè)置,不開(kāi)啟鬧鐘中斷使能,數(shù)據(jù)模式為二進(jìn)制,24小時(shí)模式。		
} 		   

陰歷計(jì)算

 /*
 函數(shù)功能:輸入BCD陽(yáng)歷數(shù)據(jù),輸出BCD陰歷數(shù)據(jù)(只允許1901-2099年)
 調(diào)用函數(shù)示例:Conversion(c_sun,year_sun,month_sun,day_sun)
 如:計(jì)算2004年10月16日Conversion(0,0x4,0x10,0x16);
 c_sun,year_sun,month_sun,day_sun均為BCD數(shù)據(jù),c_sun為世紀(jì)標(biāo)志位,c_sun=0為21世
 紀(jì),c_sun=1為19世紀(jì)
 調(diào)用函數(shù)后,原有數(shù)據(jù)不變,讀c_moon,year_moon,month_moon,day_moon得出陰歷BCD數(shù)據(jù)
 */
 
 /*子函數(shù),用于讀取數(shù)據(jù)表中農(nóng)歷月的大月或小月,如果該月為大返回1,為小返回0*/
// /* static*/ unsigned char /*bit*/ get_moon_day(uchar month_p,uint table_addr)
//   {
//   uchar temp;
//       switch (month_p){
//           case 1:{temp=year_code[table_addr]&0x08;
//                if (temp==0)return(0);else return(1);}
//           case 2:{temp=year_code[table_addr]&0x04;
//                if (temp==0)return(0);else return(1);}
//           case 3:{temp=year_code[table_addr]&0x02;
//                if (temp==0)return(0);else return(1);}
//           case 4:{temp=year_code[table_addr]&0x01;
//                if (temp==0)return(0);else return(1);}
//           case 5:{temp=year_code[table_addr+1]&0x80;
//                if (temp==0) return(0);else return(1);}
//           case 6:{temp=year_code[table_addr+1]&0x40;
//                if (temp==0)return(0);else return(1);}
//           case 7:{temp=year_code[table_addr+1]&0x20;
//                if (temp==0)return(0);else return(1);}
//           case 8:{temp=year_code[table_addr+1]&0x10;
//                if (temp==0)return(0);else return(1);}
//           case 9:{temp=year_code[table_addr+1]&0x08;
//                if (temp==0)return(0);else return(1);}
//           case 10:{temp=year_code[table_addr+1]&0x04;
//                if (temp==0)return(0);else return(1);}
//           case 11:{temp=year_code[table_addr+1]&0x02;
//                if (temp==0)return(0);else return(1);}
//           case 12:{temp=year_code[table_addr+1]&0x01;		  
//                if (temp==0)return(0);else return(1);}
//           case 13:{temp=year_code[table_addr+2]&0x80;
//                if (temp==0)return(0);else return(1);}
//       }
//	 return(0);
//   }


/*月份數(shù)據(jù)表-----------------------------------------------------------------------------*/
static unsigned char  code day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
static unsigned short code day_code2[3]={0x111,0x130,0x14e};

/*子函數(shù),用于讀取數(shù)據(jù)表中農(nóng)歷月的大月或小月,如果該月為大返回1,為小返回0------------------*/
static unsigned char get_moon_day(unsigned char month_p,unsigned short table_addr)
{
	switch (month_p)
	{
		case 1:
			if((year_code[table_addr]&0x08)==0)		return(0);
			else 									return(1); 
		case 2:
			if((year_code[table_addr]&0x04)==0)		return(0);
			else 									return(1);
		case 3:
			if((year_code[table_addr]&0x02)==0)		return(0);
			else 									return(1);
		case 4:
			if((year_code[table_addr]&0x01)==0)		return(0);
			else 								    return(1);
		case 5:
			if((year_code[table_addr+1]&0x80)==0)	return(0);
			else 									return(1);
		case 6:
			if((year_code[table_addr+1]&0x40)==0)	return(0);
			else 									return(1);
		case 7:
			if((year_code[table_addr+1]&0x20)==0)	return(0);
			else 									return(1);
		case 8:
			if((year_code[table_addr+1]&0x10)==0)	return(0);
			else 									return(1);
		case 9:
			if((year_code[table_addr+1]&0x08)==0)	return(0);
			else 									return(1);
		case 10:
			if((year_code[table_addr+1]&0x04)==0)	return(0);
			else 									return(1);
		case 11:
			if((year_code[table_addr+1]&0x02)==0)	return(0);
			else 									return(1);
		case 12:
			if((year_code[table_addr+1]&0x01)==0)	return(0);
			else 									return(1);
		case 13:
			if((year_code[table_addr+2]&0x80)==0)	return(0);
			else 									return(1);
	}
	return(0);
}



  /*
  函數(shù)功能:輸入BCD陽(yáng)歷數(shù)據(jù),輸出BCD陰歷數(shù)據(jù)(只允許1901-2099年)
  調(diào)用函數(shù)示例:Conversion(c_sun,year_sun,month_sun,day_sun)
  如:計(jì)算2004年10月16日Conversion(0,0x4,0x10,0x16);
  c_sun,year_sun,month_sun,day_sun均為BCD數(shù)據(jù),c_sun為世紀(jì)標(biāo)志位,c_sun=0為21世
  紀(jì),c_sun=1為19世紀(jì)
  調(diào)用函數(shù)后,原有數(shù)據(jù)不變,讀c_moon,year_moon,month_moon,day_moon得出陰歷BCD數(shù)據(jù)
  */

 void Conversion(bit c,uchar year,uchar month,uchar day)
 {                         //c=0 為21世紀(jì),c=1 為19世紀(jì) 輸入輸出數(shù)據(jù)均為BCD數(shù)據(jù)
//     uchar c_moon,year_moon,month_moon,day_moon;
	 uchar temp1,temp2,temp3,month_p;
     uint temp4,table_addr;
     bit flag2,flag_y;
//     temp1=year/16;   //BCD->hex 先把數(shù)據(jù)轉(zhuǎn)換為十六進(jìn)制   這段要屏蔽掉,不然數(shù)碼管顯示亂碼
//     temp2=year%16;
//     year=temp1*10+temp2;
//     temp1=month/16;
//     temp2=month%16;
//     month=temp1*10+temp2;
//     temp1=day/16;
//     temp2=day%16;
//     day=temp1*10+temp2;
     //定位數(shù)據(jù)表地址
   if(c==0)
  {                   
      table_addr=(year+0x64-1)*0x3;
  }
   else 
  {
     table_addr=(year-1)*0x3;
  }
     //定位數(shù)據(jù)表地址完成
     //取當(dāng)年春節(jié)所在的公歷月份
     temp1=year_code[table_addr+2]&0x60; 
     temp1=_cror_(temp1,5);
     //取當(dāng)年春節(jié)所在的公歷月份完成
     //取當(dāng)年春節(jié)所在的公歷日
     temp2=year_code[table_addr+2]&0x1f; 
     //取當(dāng)年春節(jié)所在的公歷日完成
     // 計(jì)算當(dāng)年春年離當(dāng)年元旦的天數(shù),春節(jié)只會(huì)在公歷1月或2月
     if(temp1==0x1)
  {  
         temp3=temp2-1;  
     }  
     else
  {
         temp3=temp2+0x1f-1;        
     }
     // 計(jì)算當(dāng)年春年離當(dāng)年元旦的天數(shù)完成
     //計(jì)算公歷日離當(dāng)年元旦的天數(shù),為了減少運(yùn)算,用了兩個(gè)表
     //day_code1[9],day_code2[3]
     //如果公歷月在九月或前,天數(shù)會(huì)少于0xff,用表day_code1[9],
     //在九月后,天數(shù)大于0xff,用表day_code2[3]
     //如輸入公歷日為8月10日,則公歷日離元旦天數(shù)為day_code1[8-1]+10-1
     //如輸入公歷日為11月10日,則公歷日離元旦天數(shù)為day_code2[11-10]+10-1
     if (month<10)
  { 
         temp4=day_code1[month-1]+day-1;
     }
     else
  {
         temp4=day_code2[month-10]+day-1;
     }
     
  if ((month>0x2)&&(year%0x4==0))
  {  
 //如果公歷月大于2月并且該年的2月為閏月,天數(shù)加1
         temp4+=1;
     }
     //計(jì)算公歷日離當(dāng)年元旦的天數(shù)完成
     //判斷公歷日在春節(jié)前還是春節(jié)后
     if (temp4>=temp3){ //公歷日在春節(jié)后或就是春節(jié)當(dāng)日使用下面代碼進(jìn)行運(yùn)算
         temp4-=temp3;
         month=0x1;
         month_p=0x1;  //month_p為月份指向,公歷日在春節(jié)前或就是春節(jié)當(dāng)日month_p指向首月
         flag2=get_moon_day(month_p,table_addr); 
 //檢查該農(nóng)歷月為大小還是小月,大月返回1,小月返回0
         flag_y=0;
         if(flag2==0)temp1=0x1d; //小月29天
         else temp1=0x1e; //大小30天
         temp2=year_code[table_addr]&0xf0;
         temp2=_cror_(temp2,4);  //從數(shù)據(jù)表中取該年的閏月月份,如為0則該年無(wú)閏月
         while(temp4>=temp1){
             temp4-=temp1;
             month_p+=1;
             if(month==temp2){
             flag_y=~flag_y;
             if(flag_y==0)month+=1;
             }
             else month+=1;
             flag2=get_moon_day(month_p,table_addr);
             if(flag2==0)temp1=0x1d;
             else temp1=0x1e;
         }
         day=temp4+1;
     }
     else{  //公歷日在春節(jié)前使用下面代碼進(jìn)行運(yùn)算
         temp3-=temp4;
         if (year==0x0){year=0x63;c=1;}
         else year-=1;
         table_addr-=0x3;
         month=0xc;
         temp2=year_code[table_addr]&0xf0;
         temp2=_cror_(temp2,4);
         if (temp2==0)month_p=0xc; 
         else month_p=0xd; //
         /*
         month_p為月份指向,如果當(dāng)年有閏月,一年有十三個(gè)月,月指向13,
 無(wú)閏月指向12
         */
         flag_y=0;
         flag2=get_moon_day(month_p,table_addr);
         if(flag2==0)temp1=0x1d;
         else temp1=0x1e;
         while(temp3>temp1){
             temp3-=temp1;
             month_p-=1;
             if(flag_y==0)month-=1;
             if(month==temp2)flag_y=~flag_y;
             flag2=get_moon_day(month_p,table_addr);
             if(flag2==0)temp1=0x1d;
             else temp1=0x1e;
          }
         day=temp1-temp3+1;
     }
//     c_moon=c;                 //HEX->BCD ,運(yùn)算結(jié)束后,把數(shù)據(jù)轉(zhuǎn)換為BCD數(shù)據(jù)
//     temp1=year/10;
//     temp1=_crol_(temp1,4);
//     temp2=year%10;
//     year_moon=temp1|temp2;
//     temp1=month/10;
//     temp1=_crol_(temp1,4);
//     temp2=month%10;
//     month_moon=temp1|temp2;
//     temp1=day/10;
//     temp1=_crol_(temp1,4);
//     temp2=day%10;
//     day_moon=temp1|temp2;


	c_moon=c;
	year_moon=year;
	month_moon=month;
	day_moon=day;


}

資料清單:

下載地址見(jiàn)文章開(kāi)頭
img

  • 設(shè)計(jì)資料獲取聯(lián)系方式.doc

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
SN74LVC14APWT 1 Texas Instruments 6-ch, 2-V to 3.6-V inverters with Schmitt-Trigger inputs 14-TSSOP -40 to 125

ECAD模型

下載ECAD模型
$1.04 查看
DP83822IRHBT 1 Texas Instruments Low-power, robust 10/100-Mbps Ethernet PHY transceiver with 16-kV ESD 32-VQFN -40 to 85

ECAD模型

下載ECAD模型
$4.03 查看
SN65HVD232D 1 Texas Instruments 3.3 V CAN Transceiver 8-SOIC -40 to 85

ECAD模型

下載ECAD模型
$2.72 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜