本程序旨在讀出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; */ /* 每小時報警中斷 */
}