DS1302是美國(guó)DALLAS公司推出的一種高性能、低功耗的實(shí)時(shí)時(shí)鐘芯片,附加31字節(jié)靜態(tài)RAM,采用SPI三線接口與CPU進(jìn)行同步通信,并可采用突發(fā)方式一次傳送多個(gè)字節(jié)的時(shí)鐘信號(hào)和RAM數(shù)據(jù)。實(shí)時(shí)時(shí)鐘可提供秒、分、時(shí)、日、星期、月和年,一個(gè)月小與31天時(shí)可以自動(dòng)調(diào)整,且具有閏年補(bǔ)償功能。
下面是一段12864液晶顯示實(shí)時(shí)時(shí)鐘的程序:
/*************************************************************************************** 時(shí)間:2012.11.30 晶振:11.0592MHz 芯片:STC89C52RC 功能描述:在12864上顯示年、月、日、星期、時(shí)、分和秒等時(shí)間信息 ***************************************************************************************/ #include<reg52.h> #define uchar unsigned char sbit CLK=P1^4; //DS1302引腳定義 sbit IO=P1^5; sbit CE=P1^6; sbit ACC0=ACC^0; sbit ACC7=ACC^7; sbit RS=P2^4; //12864引腳定義 數(shù)據(jù)口為P0 sbit RW=P2^5; sbit EN=P2^6; sbit PSB=P2^1; sbit RET=P2^3; void Input_1byte(uchar TD) //DS1302輸入一字節(jié)數(shù)據(jù) { uchar i; ACC=TD; for(i=8;i>0;i--) { IO=ACC0; CLK=1; CLK=0; ACC=ACC>>1; } } uchar Output_1byte(void) //DS1302輸出一字節(jié)數(shù)據(jù) { uchar i; for(i=8;i>0;i--) { ACC=ACC>>1; ACC7=IO; CLK=1; CLK=0; } return(ACC); } void Write_DS1302(uchar add,uchar dat)//向DS1302寫 { CE=0; CLK=0; CE=1; Input_1byte(add); Input_1byte(dat); CE=0; } uchar Read_DS1302(uchar add) //從DS1302讀 { uchar inf; //信息臨時(shí)存儲(chǔ)變量 CE=0; CLK=0; CE=1; Input_1byte(add); inf=Output_1byte(); CE=0; return(inf); } /**********************DS1302初始化*****************************/ void init_1302() { if(Read_DS1302(0xd1)==0x55) //判斷內(nèi)存單元的內(nèi)容,是否進(jìn)行初始化 { return; } else { Write_DS1302(0x8e,0x00); //關(guān)閉寫保護(hù) Write_DS1302(0x90,0x00); //電池充電設(shè)置 Write_DS1302(0x80,0x00); //秒 Write_DS1302(0x82,0x54); //分 Write_DS1302(0x84,0x20); //時(shí) Write_DS1302(0x86,0x30); //日 Write_DS1302(0x88,0x11); //月 Write_DS1302(0x8a,0x05); //星期 Write_DS1302(0x8c,0x12); //年 Write_DS1302(0xd0,0x55); //寫RAM Write_DS1302(0x8e,0x80); //打開寫保護(hù) } } /**********************延時(shí)函數(shù)*****************************/ void DelayUs2x(unsigned char t) { while(--t); } void DelayMs(unsigned char t) { while(t--) { //大致延時(shí)1mS DelayUs2x(245); DelayUs2x(245); } } /**********************12864判忙*****************************/ void check_busy() { RS=0; RW=1; EN=1; while((P0&0x80)==0x80); EN=0; } /**********************12864寫指令*****************************/ void write_com(uchar com) { check_busy(); RS=0; RW=0; EN=1; P0=com; DelayUs2x(250); EN=0; DelayUs2x(250); } /**********************12864寫數(shù)據(jù)*****************************/ void write_data(uchar dat) { check_busy(); RS=1; RW=0; EN=1; P0=dat; DelayUs2x(250); EN=0; DelayUs2x(250); } /**********************12864初始化函數(shù)*****************************/ void init() { DelayMs(40); //大于40MS的延時(shí)程序 PSB=1; //設(shè)置為8BIT并口工作模式 DelayMs(1); //延時(shí) RET=0; //復(fù)位 DelayMs(1); //延時(shí) RET=1; //復(fù)位置高 DelayMs(200); write_com(0x30); //選擇基本指令集 DelayUs2x(250); //延時(shí)大于100us write_com(0x30); //選擇8bit數(shù)據(jù)流 DelayUs2x(200); //延時(shí)大于37us write_com(0x0c); //開顯示(無游標(biāo)、不反白) DelayUs2x(250); //延時(shí)大于100us write_com(0x01); //清除顯示,并且設(shè)定地址指針為00H DelayMs(200); //延時(shí)大于10ms write_com(0x06); //指定在資料的讀取及寫入時(shí),設(shè)定游標(biāo)的移動(dòng)方向及指定顯示的移位,光標(biāo)從右向左加1位移動(dòng) DelayUs2x(250); //延時(shí)大于100us } /**********************清屏*****************************/ void clrscreen() { write_com(0x01); DelayMs(15); } /********************************************************* 主函數(shù) ********************************************************/ void main() { uchar sec,sec1,sec2; uchar min,min1,min2; uchar hour,hour1,hour2; uchar date,date1,date2; uchar mon,mon1,mon2; uchar day; uchar year,year1,year2; uchar table1[]="年月日時(shí)分秒星期溫度攝氏"; //長(zhǎng)度24 uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //長(zhǎng)度14 uchar table3[]="0123456789"; //長(zhǎng)度10 init(); //液晶初始化 clrscreen(); DelayMs(200); init_1302(); //1302初始化 只初始化一下就可以 需要下載兩次 DelayMs(50); write_com(0x80); //顯示20 write_data('2'); write_data('0'); write_com(0x82); //顯示年 write_data(table1[0]); write_data(table1[1]); write_com(0x84); //顯示月 write_data(table1[2]); write_data(table1[3]); write_com(0x86); //顯示日 write_data(table1[4]); write_data(table1[5]); write_com(0x91); //顯示時(shí) write_data(table1[6]); write_data(table1[7]); write_com(0x93); //顯示分 write_data(table1[8]); write_data(table1[9]); write_com(0x95); //顯示秒 write_data(table1[10]); write_data(table1[11]); write_com(0x88); //顯示星期 write_data(table1[12]); write_data(table1[13]); write_data(table1[14]); write_data(table1[15]); while(1) { sec=Read_DS1302(0x81); ////讀秒 sec1=sec&0x0f; //個(gè)位 sec2=sec>>4; //十位 min=Read_DS1302(0x83); ////讀分 min1=min&0x0f; //個(gè)位 min2=min>>4; //十位 hour=Read_DS1302(0x85); ////讀時(shí) hour1=hour&0x0f; //個(gè)位 hour2=hour>>4; //十位 date=Read_DS1302(0x87); ////讀日 date1=date&0x0f; //個(gè)位 date2=date>>4; //十位 mon=Read_DS1302(0x89); ////讀月 mon1=mon&0x0f; //個(gè)位 mon2=mon>>4; //十位 year=Read_DS1302(0x8d); ////讀年 year1=year&0x0f; //個(gè)位 year2=year>>4; //十位 day=Read_DS1302(0x8b); ////讀星期 write_com(0x94); //送顯示內(nèi)容 write_data(table3[sec2]); //秒 write_data(table3[sec1]); write_com(0x92); write_data(table3[min2]); //分 write_data(table3[min1]); write_com(0x90); write_data(table3[hour2]); //時(shí) write_data(table3[hour1]); write_com(0x85); write_data(table3[date2]); //日 write_data(table3[date1]); write_com(0x83); write_data(table3[mon2]); //月 write_data(table3[mon1]); write_com(0x81); write_data(table3[year2]); //年 write_data(table3[year1]); write_com(0x8a); write_data(table2[2*day-2]); //星期 write_data(table2[2*day-1]); } }