由于该电路使用了两个专用芯片,为了在分析程序时使大家理解清楚,有必要对8155及DS12887的功能、特点进行较详细的介绍。
8155结构及特点
图2为8155的内部结构,8155为多功能的可编程接口芯片,内部包含有256字节RAM,两个可编程8位并行口、一个6位并行口和一个14位的计数器。8155是8051单片机应用系统中最适用的外围器件。数据存贮器是256x8位静态RAM。I/O由三个通用口组成,其中的6位口可编程为状态控制信号。可编程的14位计数器/定时器用于给单片机系统提供方波或计数脉冲。
图3为8155的引脚排列。RESET为复位端,高电平有效。AD0~AD7为三态地址/数据线。CE为芯片片选端。/RD、/WR为读写信号端。ALE为地址锁存信号。IO/M为IO/RAM选择线,低电平选择RAM,高电平选择I/O口。PA0~PA7为端口A。PB0~PB7为端口B。PC0~PC5为端口C,用作控制信号线时,其功能如下:
PC0──AINTR(口A中断)
PC1──ABF(口A缓冲器满)
PC2──/ASTB(口A选通)
PC3──BINTR(口B中断)
PC4──BBF(口B缓冲器满)
PC5──/BSTB(口B选通)
TIMERIN为计数器/定时器输入端。TIMEROUT为定时器输出端,可以是方波或脉冲波形。Vcc为十5V电源。Vss为接地端。
8155的口A、口B可工作于基本I/O方式或选通I/O方式,□C可作为输入输出线,也可作为口A、口B选通方式时的状态控制信号线。具体选择由写入命令寄存器的命令字决定。命令字如下:
PA,PB:定义口A、口B,0为输入,1为输出。
IEA,IEB:口A、口B中断控制,1为允许,0为禁止。
PC1,PC2:定义口的工作方式。
TM1,TM2:定时器命令
8155的定时器为14位的减法计数器,对输入脉冲进行减法计数,定时器由两个字节组成,其格式如下:
T13~T0:计数长度。
M2,M1:定时器方式
DS12887结构及特点
图4为DS12887的结构框图,DS12887是DALLAS公司的实时时钟芯片RTC(RealTimeClock),它功能丰富,应用广泛,PC机内的时钟信号就是由D512887提供的。DS12887内部自带晶体振荡器及锂电池,可计算到2100年前的秒、分、小时、星期、日、月、年七种日历信息并带闰年补偿,断电后能运行10年之久不丢失数据。可选用夏令时,具有24小时或12小时两种制式。它在工业控制及仪器仪表中有广泛用途。DS12887上电时,当Vcc高于4.25V200mS后,芯片可以被外部程序操作。当Vcc低于4.25V时,芯片处于写保护状态(所有的输入均无效),同时所有输出呈高阻状态。当Vcc低于3V时,芯片将自动把供电方式切换为由内部电池供电。
图5为DS12887的引脚排列。AD0~AD7为地址/数据复用总线。NC为空脚。MOT为总线模式选择(MOTOROLA/INTEL),当此脚接到Vcc时,选用的是MOTOROLA总线时序,当它接地或不接时,选用的是INTEL总线时序。CS为片选端。AS为地址锁存允许端。R/W在INTEL总线下作为写。DS在INTEL总线下作为读。RESET为复位端,复位端对时钟、日历、RAM无效,系统上电时复位端要保持低电平200mS以上DS12887才可以正常工作。IRQ为中断请求输出端。SQW为方波输出端,当Vcc低于4.25V时没有作用。Vcc为+5V电源。GND为接地端。
DS12887有128个RAM单元。其中4个单元用作控制寄存器,10个单元用作存放时钟字节,114字节为通用RAM。其主要寄存器如下:
DS12887内部寄存器A:
UIP=l:更新已到,不能读/写DSl2887;UIP=0:更新末到,能读/写DS12887。
DV2,DV1,DV0应设置为010,表示打开晶振,允许计时。
RS3,RS2,RS1,RS0为方波频率选择位,产生方波周期中断。
DS12887内部寄存器B:
SET=0:时间更新正常进行,每秒计数1次;SET=1:禁止更新,程序可初始化时间和日历。
PIE=l:允许周期中断;PIE=0:禁止周期中断。
AIE=1:允许报警中断;AIE=0:禁止报警中断。
UIE=1:允许更新结束中断;UIE=0:禁止更新结束中断。
SQWE为方波允许位。SQWE=1:将RS3,RS2,RS1,RS0选定的方波输出。
DM=1:BCD码;DM=0:二进制。该位不受复位信号影响
24/12:1表示24[小]时制;0表示12[小]时制。
DSE为夏时制允许位。DSE=l:采用夏时制;DSE=0:不采用夏时制。
DS12887内部寄存器C:
IRQF为中断申请标志。
PF为方波周期中断标志。PF=1:方波周期结束,申请中断。
AF为闹铃中断标志。AF=1:当前时间与闹铃时间匹配时即刻申请中断。
UF为更新周期结束中断标志。UF二I:更新周期结束时申请中断。
DS12887内部寄存器D:
VRT为内部锂电池状态。VRT=1:锂电池正常;VRT=0:锂电池耗尽。
D512887内部存储器功能如附表所示。
defineuintunsignedint
//============================
definePAXBYTE[0x7001]
definePCXBYTE[0x7003]
//============================
defineminXBYTE[0x8002]
defineweekXBYTE[0x8006]
definemonXBYTE[0x8008]
definecentXBYTE[0x8032]
defineDS12887BXBYTE[0x800b]
#defineDS12887CXBYTE[0x800c]
//===============================
sbitset_inc=P1^0;
sbitset_dec=P1^1;
sbitinc=P1^2;
sbitdec=P1^3;
uchardisbit;
bitflag;
ucharSEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
ucharcodeact_PB[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
ucharcodeact_PC[5]={0xfe,0xfd,0xfb,0xf7,0xef};
charms=0;
chardataram_year,ram_mon,ram_day,ram_week,ram_hou,ram_min,ram_sec;
voidscan_key(void);
voiddelay(uintk);
voidwr_time(void);
voidrd_time(void);
/******************************/
voidinit_timer0(void)
{
TH0=-(2000/256);
TL0=-(2000%256);
TR0=1;
}
//***********************
voidinit(void)
{init_timer0();
EA=1;ET0=1;
C8155=0x0f;
DS12887A=0x20;
}
/**********************************/
voidtime_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/****************************************/
voidmin_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10]0x7f;}break;
case3:{PA=SEG7[ram_min/10]0x7f;}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/***************************************/
voidhou_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10]0x7f;}break;
case5:{PA=SEG7[ram_hou/10]0x7f;}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/***************************************/
voidweek_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1]0x7f;}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/**************************************/
voidday_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10]0x7f;}break;
case8:{PA=SEG7[ram_day/10]0x7f;}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/********************************************/
voidmon_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10]0x7f;}break;
case10:{PA=SEG7[ram_mon/10]0x7f;}break;
case11:{PA=SEG7[ram_year%10];}break;
case12:{PA=SEG7[ram_year/10];}break;
default:break;
}
}
/****************************************/
voidyear_dis(uchardisbit)
{uchary_week;
switch(disbit)
{
case0:{PA=SEG7[ram_sec%10];}break;
case1:{PA=SEG7[ram_sec/10];}break;
case2:{PA=SEG7[ram_min%10];}break;
case3:{PA=SEG7[ram_min/10];}break;
case4:{PA=SEG7[ram_hou%10];}break;
case5:{PA=SEG7[ram_hou/10];}break;
case6:{if(ram_week==1)y_week=9;
elsey_week=ram_week;PA=SEG7[y_week-1];}break;
case7:{PA=SEG7[ram_day%10];}break;
case8:{PA=SEG7[ram_day/10];}break;
case9:{PA=SEG7[ram_mon%10];}break;
case10:{PA=SEG7[ram_mon/10];}break;
case11:{PA=SEG7[ram_year%10]0x7f;}break;
case12:{PA=SEG7[ram_year/10]0x7f;}break;
default:break;
}
}
/****************************************/
voidtime0(void)interrupt1using1
{staticuchardisbit;
TH0=-(2000/256);
TL0=-(2000%256);
PB=0xff;PC=0xff;
switch(ms)
{
case0:{time_dis(disbit);}break;
case1:{min_dis(disbit);}break;
case2:{hou_dis(disbit);}break;
case3:{week_dis(disbit);}break;
case4:{day_dis(disbit);}break;
case5:{mon_dis(disbit);}break;
case6:{year_dis(disbit);}break;
default:break;
}
disbit++;
if(disbit12)disbit=0;
if(disbit8){PB=act_PB[disbit];PC=0xff;}
else{PB=0xff;PC=act_PC[disbit-8];}
}
/***********************************/
voidmain(void)
{
init();
rd_time();
while(1)
{
scan_key();
if(ms==0){
if(flag){wr_time();flag=0;}
elserd_time();
}
}
}
/*****************************************/
voidwr_time(void)
{
DS12887B=0x86;
year=ram_year;mon=ram_mon;day=ram_day;
week=ram_week;hou=ram_hou;min=ram_min;
DS12887B=0x06;
}
/*******************************************/
voidrd_time(void)
{
uchardatatemp,x;
do{temp=DS12887A;x=temp|0x7f;}while(x==0xff);
ram_year=year;ram_mon=mon;ram_day=day;
ram_week=week;ram_hou=hou;ram_min=min;ram_sec=sec;
}
/*****************************************/
voidscan_key(void)
{
if(!set_inc){ms++;delay(200);if(ms6)ms=0;}
if(!set_dec){ms--;delay(200);if(ms0)ms=6;}
if(ms==1){flag=1;if(!inc){ram_min++;if(ram_min59)ram_min=59;delay(200);}
if(!dec){ram_min--;if(ram_min1)ram_min=1;delay(200);}}
if(ms==2){if(!inc){ram_hou++;if(ram_hou23)ram_hou=23;delay(200);}
if(!dec){ram_hou--;if(ram_hou0)ram_hou=0;delay(200);}}
if(ms==3){if(!inc){ram_week++;if(ram_week7)ram_week=7;delay(200);}
if(!dec){ram_week--;if(ram_week1)ram_week=1;delay(200);}}
if(ms==4){if(!inc){ram_day++;if(ram_day31)ram_day=31;delay(200);}
if(!dec){ram_day--;if(ram_day1)ram_day=1;delay(200);}}
if(ms==5){if(!inc){ram_mon++;if(ram_mon12)ram_mon=12;delay(200);}
if(!dec){ram_mon--;if(ram_mon1)ram_mon=1;delay(200);}}
if(ms==6){flag=1;if(!inc){ram_year++;if(ram_year99)ram_year=99;delay(200);}
if(!dec){ram_year--;if(ram_year0)ram_day=0;delay(200);}}
}
/********************************************************/
voiddelay(uintk)
{
uinti,j;
for(i=0;ik;i++){
for(j=0;j60;j++)
{;}}
}
/*************************************/