本篇就常用的时钟芯片DS1302做出编程测试,实现了年月日时分秒周初值的设定和将时间在7段码上显示的功能,本程序只是简易的直接在程序中设置时间参数,没有考虑在运行中再次调整时间,当然,如果要实现那些功能,可以在程序中加入相应的按键逻辑控制程序,以做成标准的电子时钟。在此不做讨论。
一、硬件介绍
1>引脚介绍
这是常用的8引脚的DS1302时钟芯片,除了电源端和接地端与接晶振端,我们需要操作的剩下了SCLK、RST、DSIO端。
SCLK:是串行时钟输入线,用来控制数据的移动的
IO:数据的输入与输出端
RST:读写过程中RST必须置1
****************************************************************************************************************
详情请咨询: http://shop108408772.taobao.com/
**************************************************************************************************************
2>数据的输入与输出
数据输入:数据是在时钟的上升沿写入的,而且是先写低位。
数据输出:在时钟下降沿时数据输出一位,也是从低位开始输出。
3>寄存器
时钟寄存器存放的数据是压缩的BCD码形式,所以写入的初值和读出的数据都是此形式,注意进行转化。
小时寄存器的最高位为0时是24小时模式。为1时是12小时模式。
在写入时间参数或RAM时控制寄存器最高位必须是0,进行写保护禁止,以进行设置初值等。
****************************************************************************************************************
详情请咨询: http://shop108408772.taobao.com/
**************************************************************************************************************
4>读写时序
读写时分别按照上下时序即可。
5>命令表格速查
二、软件部分
#include
#include
sbit DSIO=P3^4; //数据线
sbit RST=P3^5; //RST线
sbit SCLK=P3^6; //时钟线
// 此表为 LED 的字模(共阴极) 0 1 2 3 4 5 6 7 8 9灭 a b c d e f
unsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char DSREAD(unsigned char address)//读数据
{unsigned char i,temp=0,shi,ge;
RST=0;
_nop_( ); // 初始化
SCLK=0;
_nop_( ); //初始化
RST=1; //打开RST
for(i=0;i<=7;i++) //循环8次
{SCLK=0;
DSIO=(address>>i)&0x01; //先送低位********************************************************************(1)
_nop_( );
SCLK=1;
}
DSIO=1;
for(i=0;i<=7;i++) //循环8次读8次数据
{SCLK=1;
_nop_( );
_nop_( );
SCLK=0;
temp>>=1;
if(DSIO)temp=temp|0x80; //注意先读的是低位************************************************************(2)
}
shi=temp/16; //将读到的BCD吗转化为正常数
ge=temp%16;
temp=ge+shi*10;
RST=0; //RST关闭
return temp; //返回的是正常数
}
****************************************************************************************************************
详情请咨询: http://shop108408772.taobao.com/
**************************************************************************************************************
void DSWRITE(unsigned char address,unsigned char shuju)//写数据
{unsigned char i,shi,ge,temp;
RST=0; //RST初始化
_nop_( );
SCLK=0; //时钟初始化
_nop_( );
RST=1; //RST置1
for(i=0;i<=7;i++) //开始写8位地址
{DSIO=(address>>i)&0x01;
SCLK=0;
_nop_( );
SCLK=1;
}
shi=shuju/10; //将正常数转化为BCD码
ge=shuju%10;
temp=shi*16+ge;
for(i=0;i<=7;i++) //开始写8位数据
{DSIO=(temp>>i)&0x01;
SCLK=0;
_nop_( );
SCLK=1;
}
RST=0; //RST关闭
}
void display(unsigned char number,unsigned char shuzi)//显示数据
{unsigned char temp,i;
temp=number<<2; //选中第number位数码
P2=temp&0x1c;
P1=(LED7Code[shuzi])&0x7f; //送入码值
for(i=0;i<=100;i++); //延时
}
main()
{
unsigned char i;
unsigned char shijian[8]={2,0,10,4,1,10,0,1};
DSWRITE(0x8E,0); //写保护关闭
DSWRITE(0x8C,14); //年
DSWRITE(0x8A,6); //星期
DSWRITE(0x88,10); //月
DSWRITE(0x86,4); //日
DSWRITE(0x84,11); //时
DSWRITE(0x82,3); //分
DSWRITE(0x80,0); //秒
DSWRITE(0x8E,0x80); //写保护关闭
do{
shijian[0]=DSREAD(0x85)/10;//小时 十位
shijian[1]=DSREAD(0x85)%10;//小时 个位
shijian[3]=DSREAD(0x83)/10;//分钟 十位
shijian[4]=DSREAD(0x83)%10;//分钟 个位
shijian[6]=DSREAD(0x81)/10;//秒 十位
shijian[7]=DSREAD(0x81)%10;//秒 个位
for(i=0;i<=7;i++)
{display(i,shijian[i]);
}
}while(1);
}
****************************************************************************************************************
详情请咨询: http://shop108408772.taobao.com/
**************************************************************************************************************
三、调试时遇到的问题
在(1)处,DSIO=(address>>i)&0x01中&0x01是不可少的,否则出错。使用0x01和数据进行'与'来屏蔽掉其他位!
在(2)处,注意先读的是低位,所以要把数据先存在高位再依次往后移
四、测试结果
****************************************************************************************************************
详情请咨询: http://shop108408772.taobao.com/
**************************************************************************************************************