📄 wds12887led8.c
字号:
//参考程序B. WDS12887LED8.c程序功能:读取时钟值,并将时,分,秒显示在数码管上. 可以实现时钟初始化(授时)
// Includes
#include <c8051f020.h> // SFR declarations
#include <intrins.h>
// Global CONSTANTS
#define CS12887 0x8300 /*DS12887时间寄存器首地址*/
#define CS12887A 0x830A /*DS12887内部寄存器A地址*/
#define CS12887B 0x830B /*DS12887内部寄存器B地址*/
#define CS12887C 0x830C /*DS12887内部寄存器C地址*/
#define PORTA 0x8000 /*8255的A口*/
#define PORTB 0x8001
#define PORTC 0x8002
#define PORTCON 0x8003
unsigned long x;
unsigned char *lcdpoint; //指向 lcddata数组的指针
unsigned char lcd_data_count; //要显示的数据个数
// Function PROTOTYPES
void PORT_Init (void);
void sleep_ms(unsigned int count)// 延时
{
unsigned int ii,jj;
for(ii=0;ii<count;ii++)
{
for(jj=0;jj<250;jj++)
_nop_();
}
}
void SYSCLK_Init (void) //函数功能: 系统时钟初始化
{
OSCICN = 0x05; // 系统时钟初始化为片内的4MHz
}
void DS12887INIT(void)// 初始化时钟芯片并写入时间初值
{
unsigned char i;
unsigned char xdata *idata Point1;
Point1=CS12887B;
*Point1=0x80; /*设置SET=1,禁止时间更新*/
Point1=CS12887;
*Point1=0x00; /*写入当前秒值:"30"秒*/
Point1++;
*Point1=0xff; /*秒不报警(不闹秒)*/
Point1++;
*Point1=0x00; /*写入当前分值:"58"分*/
Point1++;
*Point1=0xff; /*分不报警(不闹分)*/
Point1++;
*Point1=0x12; /*写入当前时值:"23" 时*/
Point1++;
*Point1=0xff; /*时不报警(不闹时)*/
Point1++;
*Point1=0x04; /*写入当前周日:"5"*/
Point1++;
*Point1=0x04; /*写入当前日期:"01"日*/
Point1++;
*Point1=0x08; /*写入当前月份:"07"月*/
Point1++;
*Point1=0x05; /*写入当前年份:"05"年*/
Point1=CS12887C;
i=*Point1; /*CLEAR C*/
Point1++;
i=*Point1; /*CLEAR D*/
Point1=CS12887B;/*更新周期正常运行,禁止中断,采用BCD码格式,24[小]时制*/
*Point1=0x02; /*不用复时制*/
}
void PORT_Init (void)// 初始化I/O
{
XBR2 = 0x40; /*时能交叉开关,弱上拉*/
P74OUT = 0xc0; /*P7为推拉方式,P4,P5,P6漏极开路*/
EMI0CF |= 0x2c; /*EMIF工作在地址/数据复用方式,只用外部存储器,ALE高/低脉宽占1个SYSCLK周期*/
EMI0TC |= 0x6d; /*地址建立/保持时间占1个SYSCLK周期,/WR和/RD占12个SYSCLK周期*/
}
// MAIN Routine
void main (void) {
unsigned char j,k,temp;
unsigned int i;
unsigned char TimeVal[10];
unsigned char xdata *idata Pointm;
unsigned char HMS[6],YMD[6];
/*无效看门狗*/
WDTCN = 0xde;
WDTCN = 0xad;
SYSCLK_Init ();
PORT_Init ();
//DS12887INIT();
Pointm=PORTCON;
*Pointm=0x80; //B口输出,A口输出
// sleep_ms(4000);
do{
temp=temp&0x7f; /*UIP=0*/
Pointm=CS12887A; /*判断更新周期结束否?查询UIP位*/
temp=*Pointm;
temp=temp&0x80; /*UIP=0,时钟更新已经完成,可以读取时钟值*/
}while(temp==0x80); /*UIP=1,时钟更新周期正在进行,需继续等待*/
while(1)
{
Pointm=CS12887;
for(temp=0;temp<10;temp++) /*读时间寄存器*/
{
TimeVal[temp]=*Pointm;
Pointm++;
switch(temp){ /*准备待显示数据*/
case 0x00: /*秒*/
HMS[4]=(TimeVal[temp]>>4);
HMS[5]=TimeVal[temp]&0x0f;
break;
case 0x02: /*分*/
HMS[2]=(TimeVal[temp]>>4);
HMS[3]=TimeVal[temp]&0x0f;
break;
case 0x04: /*时*/
HMS[0]=(TimeVal[temp]>>4);
HMS[1]=TimeVal[temp]&0x0f;
break;
case 0x07: /*日*/
YMD[4]=(TimeVal[temp]>>4);
YMD[5]=TimeVal[temp]&0x0f;
break;
case 0x08: /*月*/
YMD[2]=(TimeVal[temp]>>4);
YMD[3]=TimeVal[temp]&0x0f;
break;
case 0x09: /*年*/
YMD[0]=(TimeVal[temp]>>4);
YMD[1]=TimeVal[temp]&0x0f;
break;
default:
_nop_();
}
}
for(j=0;j<6;j++)
{
switch(HMS[j]){ /*转化成数码管数字显示码*/
case 0x01:
k=0x06; // '1'
break;
case 0x02:
k=0x5b; // '2'
break;
case 0x03:
k=0x4f; // '3'
break;
case 0x04:
k=0x66; // '4'
break;
case 0x05:
k=0x6d; // '5'
break;
case 0x06:
k=0x7d; // '6'
break;
case 0x07:
k=0x07; // '7'
break;
case 0x08:
k=0x7f; // '8'
break;
case 0x09:
k=0x6f; // '9'
break;
case 0x00:
k=0x3f; // '0'
break;
default:
k=0x80; // 'dot'
}
switch(j) //动态驱动6数码管
{
case 0x00:
Pointm=PORTB;
*Pointm=0x01;
break;
case 0x01:
Pointm=PORTB;
*Pointm=0x02;
break;
case 0x02:
Pointm=PORTB;
*Pointm=0x04;
break;
case 0x03:
Pointm=PORTB;
*Pointm=0x08;
break;
case 0x04:
Pointm=PORTB;
*Pointm=0x10;
break;
case 0x05:
Pointm=PORTB;
*Pointm=0x20;
break;
default:
_nop_();
}
Pointm=PORTC;
*Pointm=k; /*送显示码*/
for(i=0;i<=600;i++);
_nop_();
}
_nop_();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -