目录
一、硬件电路
二、DS1302
1.DS1302概述
DS1302 是 DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日 历和 31 字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟/日 历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自 动调整。时钟操作可通过 AM/PM 指示,DS1302 与 单片机之间能简单地采用同步串行的方式进行通信,简易三线SPI通信模式:①RES 复位②I/O 数据线③SCLK 串行时钟。
1,VCC2:主电源引脚
2,X1、X2:DS1302 外部晶振引脚,通常需外接 32.768K 晶振
3,GND:电源地
4,CE:使能引脚,也是复位引脚(新版本功能变)。
5,I/O:串行数据引脚,数据输出或者输入都从这个引脚
6,SCLK:串行时钟引脚
7,VCC1:备用电源
2.ds1302控制寄存器
用于存放控制DS1302命令,可以控制该寄存器以控制选择读或写等操作。
1.第7位,固定为1
2.第6位,1为寻址内部存储器地址RAM,0为寻址内部寄存器,即年月日所在存储器,一般设置为0
3.第5到1位,第6位存储器的地址
4.第0位,1位读操作,0为写操作
具体由下图所示。
3.DS1302时序图
CE:复位时序
SCLK:时钟时序
IO:数据传输时序
注:DS1302与DS18B20都是从低位到高位传输(读/写)数据,编程时要注意。
(1)读字节程序:
/*读字节*/
u8 ds1302_read_byte(u8 addr) //addr含义:用户需要从某个寄存器里读取数据,addr即为这个寄存器的地址
{
u8 i=0,t=0,dat=0,x=0;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
for(i=0;i<8;i++)
{
t=addr<<7;
IO=t>>7;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
SCLK=1;
_nop_();
dat>>=1;
x=IO;
SCLK=0;
_nop_();
dat=dat|(x<<7);
}
CE=0;
_nop_();
//以下代码的含义:因为作者所使用的单片机IO口没有上拉电阻,需要人为上拉电平。
IO=0;
_nop_();
IO=1;
_nop_();
return dat;
}
(2)写字节程序
/*写字节*/
void ds1302_write_byte(u8 addr,u8 dat)//dat含义:要写入的数据
{ //addr含义:用户需要把数据写到某个寄存器,addr为这个寄存器的地址
u8 i=0,t=0;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
_nop_();
for(i=0;i<8;i++)
{
t=addr<<7;
IO=t>>7;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
addr>>=1;
}
for(i=0;i<8;i++)
{
t=dat<<7;
IO=t>>7;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
dat>>=1;
}
CE=0;
}
(3)初始化程序
/*本函数用于设定初始时间,比如13:30:59*/
void ds1302_init(void)
{
u8 i=0;
ds1302_write_byte(0x8e,0x00);
for(i=0;i<7;i++)//写入初始时间
{
ds1302_write_byte(gWRITE_RTC_ARRD[i],gDS1302_TIME[i]);
}
ds1302_write_byte(0x8e,0x80);
}
gWRITE_RTC_ARRD[]为读寄存器的地址
(4)转换时间程序
void ds1302_read_time(void)
{
u8 i=0;
for(i=0;i<7;i++)
{
gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ARRD[i]);
}
}
//gDS1302_TIME[]为时间对应BCD码
//gREAD_RTC_ARRD[]为读寄存器的地址
三、数码管
void smg_display(u8 dat[],u8 pos)//dat数组元素是数字对应16进制数
{ //pos是从第几个数码管开始亮
u8 i=0;
u8 pos_temp=pos-1;
for(i=pos_temp;i<8;i++)
{
switch(i)//位选
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT=dat[i-pos_temp];
delay_10us(100);
SMG_A_DP_PORT=0x00;
}
}
四、主程序
void main()
{
u8 num[8];
ds1302_init();
while(1)
{
ds1302_read_time();
num[0]=gsmg_code[gDS1302_TIME[2]/16];
num[1]=gsmg_code[gDS1302_TIME[2]%16];
num[2]=0x40;
num[3]=gsmg_code[gDS1302_TIME[1]/16];
num[4]=gsmg_code[gDS1302_TIME[1]%16];
num[5]=0x40;
num[6]=gsmg_code[gDS1302_TIME[0]/16];
num[7]=gsmg_code[gDS1302_TIME[0]%16];
smg_display(num,1);
}
}