本程序旨在讀出DS12C887的時間,顯示部分只做了分和秒的部分,已通過測試,詳細注釋很好用的。 #include < absacc.h > #include < reg51.h > #define uchar unsigned char #define MCA XBYTE [ 0xbf0a ] /*寄存器A*/ #define MCB XBYTE [ 0xbf0b ] /* 寄存器B*/ #define MCC XBYTE [ 0xbf0c ] /* 寄存器C*/ #define MCD XBYTE [ 0xbf0d ] /*寄存器D */ #define HOURW XBYTE [ 0xbf05 ] /*時報警*/ #define SECONDW XBYTE [ 0xbf01 ] /*秒報警*/ #define YEAR XBYTE [ 0xbf09 ] #define MONTH XBYTE [ 0xbf08 ] #define DAY XBYTE [ 0xbf07 ] #define HOUR XBYTE [ 0xbf04 ] #define MU XBYTE [ 0xbf02 ] #define SECOND XBYTE [ 0xbf00 ] sbit uip_bit = ACC^7; /* 保存更新周期標志位*/ uchar dt[6] = { 0x06,0x01,0x01,0x00,0x00,0x00 }; /* 時標緩沖區及初值 ,設置時間,用于時間校準?*/ sbit bita=P2^0; sbit bitb=P2^1; sbit bitc=P2^2; sbit bitd=P2^3; code uchar dispcode[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段碼 uchar dispbit[4]={0,0,0,0};/*顯示位*/ /*顯示函數*/ void disp() { uchar k; bita=1;bitb=bitc=bitd=0; P0=dispcode[dispbit[0]]; for(k=0;k<150;k++); bita=bitc=bitd=0;bitb=1; P0=dispcode[dispbit[1]]; for(k=0;k<150;k++); bita=bitb=bitd=0;bitc=1; P0=dispcode[dispbit[2]]; for(k=0;k<150;k++); bita=bitb=bitc=0;bitd=1; P0=dispcode[dispbit[3]]; for(k=0;k<150;k++); } /* 初始化工作狀態函數*/ void initstat ( void ) { MCA = 0x2f; /*選時鐘32.768KHz,中斷周期500ms*/ ACC = MCC; /* 清中斷請求標志 */ ACC = MCD; /* VRT = 1,數據有效 */ /* 中斷允許,時標十進制,24小時制,芯片開始工作*/ MCB = 0x72; /* HOURW = 0x17;*/ /*每小時報警中斷*/ SECONDW=0X3b; /*每秒報警中斷 , 可以選用,用于顯示秒點的閃動*/ EA = 1; EX0 = 1; /* 開外部中斷0*/ } /* 寫時標函數 */ void wMC ( void ) { MCB = 0x80; /* 置SET位為1,芯片停止工作 */ YEAR=dt[0]; MONTH=dt[1]; DAY=dt[2]; HOUR=dt[3]; MU=dt[4]; SECOND=dt[5]; } /* 讀時標函數 */ void rMC ( void ) { do { ACC = MCA; } /* 讀取UIP位 */ while ( uip_bit ); /* 等待周期更新結束 */ dt[0]=YEAR; dt[1]=MONTH; dt[2]=DAY; dt[3]=HOUR; dt[4]=MU; dt[5]=SECOND; /* 讀時標值到緩沖區 */ } void main ( void ) { SP=0x60; wMC ( ); /* 調用寫時標函數 */ initstat ( ); /* 調用初始化工作狀態函數*/ while (1) { rMC(); dispbit[0]=dt[3]/16; dispbit[1]=dt[3]%16; dispbit[2]=dt[4]/16; dispbit[3]=dt[4]%16; disp(); } } /* 外部中斷0服務函數*/ void time ( void ) interrupt 0 using 1 { ACC = MCC; /* 讀取寄存器C*/ if ( ACC^4 ) rMC ( ); /* 周期更新結束,讀取時標值*/ if ( ACC^5 ) rMC( ); /* 秒報警*/ SECONDW=0x3b; /* HOURW = 0x17; */ /* 每小時報警中斷 */ }