}
//ds1302写1字节
void rtc_wt_byte(unsigned char sent_buf)
{unsigned char i;
for (i=0; i<8; i++)
{RTC_CLK=0;
if (sent_buf&0x01) RTC_IO=1;
else RTC_IO=0;
RTC_CLK=1;
dly(5);
sent_buf=sent_buf>>1;
}
RTC_CLK=0;
dly(5);
}
//ds1302读1字节
unsigned char rtc_rd_byte(void)
{unsigned char i,read_buf;
RTC_IO=1; //RTC_IO置1,保证为输入状态
for (i=0; i<8; i++)
{read_buf=read_buf>>1;
RTC_CLK=0;
dly(5);
if (RTC_IO) read_buf=read_buf|0x80;
else read_buf=read_buf&0x7f;
RTC_CLK=1;
dly(5);
}
RTC_CLK=0;
dly(5);
return read_buf;
}
//ds1302写入时间
void rtc_wr_time(unsigned char *p_wt_time)
{unsigned char i;
unsigned char tmp1;
dly(30);
RTC_RST=1;
rtc_wt_byte(0xbe); //burst写入时间
for (i=0; i<8; i++)
{tmp1=*p_wt_time++;
rtc_wt_byte(tmp1);
}
RTC_CLK=0;
RTC_RST=0;
}
//ds1302读出时间
void rtc_rd_time(unsigned char *p_rd_time)
{unsigned char i;
unsigned char tmp1;
dly(30);
RTC_RST=1;
rtc_wt_byte(0xbf); //burst读取时间
RTC_IO=1;
for (i=0; i<8; i++)
{tmp1=rtc_rd_byte();
*p_rd_time++=tmp1;
}
RTC_CLK=0;
RTC_RST=0;
}
//ds1302初始化
void ini_rtc()
{RTC_CLK=0;
RTC_RST=0;
dly(30);
RTC_RST=1;
rtc_wt_byte(0x8e); //写CONTROL寄存器
rtc_wt_byte(0x00); //值:去掉写保护
RTC_RST=0; //复位
RTC_RST=1; //正常工作
rtc_wt_byte(0x90); //写TRICKLE CHARGER寄存器
rtc_wt_byte(0xa9); //值:使能充电,串联2个二极管,串联2k欧姆的电阻
RTC_CLK=0;
RTC_RST=0;
}
//把4位数字的SEG放到COM1、COM2、COM3、COM4对应的段码
//LCD的管脚定义与LED不同,它不是一个COM对应一位数字,而是对应每个数字的一部分SEG
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// < 1f 1a 2f 2a 3f 3a 4f 4a > -- ---- COM0
// < 1g 1b 2g 2b 2g 3b 4g 4b > -- ---- COM1
// < 1e 1c 2e 2c : 3e 3c 4e 4c > -- ---- COM2
// 1d 1h 2d 2h 3d 3h 4d -- ---- COM3
void Seg2Seg()
{unsigned char SegXX;
SegBuf[0]=0;
SegBuf[1]=0;
SegBuf[2]=0x08;
SegBuf[3]=0;
bi_4a=0;
bi_4b=0;
bi_4c=0;
SegXX=seg_code[DisplayBuf[0]]; //第1位数字
if (SegXX&0x80) SegBuf[0]|=0x40;
if (SegXX&0x40) SegBuf[1]|=0x40;
if (SegXX&0x20) SegBuf[2]|=0x40;
if (SegXX&0x10) SegBuf[3]|=0x80;
if (SegXX&0x08) SegBuf[2]|=0x80;
if (SegXX&0x04) SegBuf[0]|=0x80;
if (SegXX&0x02) SegBuf[1]|=0x80;
if (SegXX&0x01) SegBuf[3]|=0x40;
SegXX=seg_code[DisplayBuf[1]]; //第2位数字
if (SegXX&0x80) SegBuf[0]|=0x10;
if (SegXX&0x40) SegBuf[1]|=0x10;
if (SegXX&0x20) SegBuf[2]|=0x10;
if (SegXX&0x10) SegBuf[3]|=0x20;
if (SegXX&0x08) SegBuf[2]|=0x20;
if (SegXX&0x04) SegBuf[0]|=0x20;
if (SegXX&0x02) SegBuf[1]|=0x20;
if (SegXX&0x01) SegBuf[3]|=0x10;
SegXX=seg_code[DisplayBuf[2]]; //第3位数字
if (SegXX&0x80) SegBuf[0]|=0x02;
if (SegXX&0x40) SegBuf[1]|=0x02;
if (SegXX&0x20) SegBuf[2]|=0x02;
if (SegXX&0x10) SegBuf[3]|=0x04;
if (SegXX&0x08) SegBuf[2]|=0x04;
if (SegXX&0x04) SegBuf[0]|=0x04;
if (SegXX&0x02) SegBuf[1]|=0x04;
if (SegXX&0x01) SegBuf[3]|=0x02;
SegXX=seg_code[DisplayBuf[3]]; //第4位数字
if (SegXX&0x80) bi_4a=1;
if (SegXX&0x40) bi_4b=1;
if (SegXX&0x20) bi_4c=1;
if (SegXX&0x10) SegBuf[3]|=0x01;
if (SegXX&0x08) SegBuf[2]|=0x01;
if (SegXX&0x04) SegBuf[0]|=0x01;
if (SegXX&0x02) SegBuf[1]|=0x01;
}
/*一个BCD码转化成两个十进制数(如:0x79转化成0x07和0x09)*/
BcdToDec(unsigned char BcdValue,unsigned char *pDecValue)
{//if (BcdValue>=0x9a||(BcdValue&0x0f)>=0x0a) return 0;
*pDecValue++=(BcdValue&0xf0)>>4;
*pDecValue=BcdValue&0x0f;
//return 1;
}
//初始化MCS51内部资源
InitInterResource()
{IE=0; //关全部中断
TCON=0; //清全部中断请求
IP=0; //清中断优先级
TMOD=0x01; //T0工作方式1(16位定时器)
TH0=0x00; //T0定时器辅初值
TL0=0x00;
TR0=1; //允许T0定时
ET0=1; //允许T0中断
EA=0; //关全局中断
RTC_RST=0;
}
void main()
{
InitInterResource();
ini_rtc(); //初始化DS1302
rtc_wr_time(ClockBuffer); //写入时间初始值
EA=1; //开全局中断
while(1)
{
}
}
//定时器0中断服务程序,5ms定时器,4位数码管动态显示驱动
void tmr0_p(void) interrupt 1
{
TL0=0x78; //重新定时5ms
TH0=0xec;
Seg2Seg();
P3M1=0x3c;
P3M0=0x00;
switch(ScanCoun) //动态扫描显示
{
case 0: //COM0正向驱动
P1= SegBuf[0];
BI_4= bi_4a;
COM0=0;
P3M1=0x1c; //除COM0输出外,其余COM设为输入
P3M0=0x00;
break;
case 1: //COM0反向驱动
P1= ~SegBuf[0];
BI_4= ~bi_4a;
COM0=1;
P3M1=0x1c;
P3M0=0x00;
break;
case 2: //COM1正向驱动
P1= SegBuf[1];
BI_4= bi_4b;
COM1=0;
P3M1=0x2c;
P3M0=0x00;
break;
case 3: //COM1反向驱动
P1= ~SegBuf[1];
BI_4= ~bi_4b;
COM1=1;
P3M1=0x2c;
P3M0=0x00;
break;
case 4: //COM2正向驱动
P1= SegBuf[2];
BI_4= bi_4c;
COM2=0;
P3M1=0x34;
P3M0=0x00;
break;
case 5: //COM2反向驱动
P1= ~SegBuf[2];
BI_4= ~bi_4c;
COM2=1;
P3M1=0x34;
P3M0=0x00;
break;
case 6: //COM3正向驱动
P1= SegBuf[3];
COM3=0;
P3M1=0x38;
P3M0=0x00;
RTC_RST=0;
rtc_rd_time(ClockBuffer); //读时间
BcdToDec(ClockBuffer[0],DisplayBuf+2); //秒送入显示缓冲
BcdToDec(ClockBuffer[1],DisplayBuf); //分送入显示缓冲
BI_4= ~bi_4c;
break;
case 7: //COM3反向驱动
P1= ~SegBuf[3];
COM3=1;
P3M1=0x38;
P3M0=0x00;
break;
}
ScanCoun++; //下一位
if (ScanCoun>7) ScanCoun=0;
}