DS1302时钟模块

原理图

capture_20240313210312749

我们可控的引脚为5,6,7,P13为复位,P23输入数据,P17为时钟引脚。其余口是已经配置好的。

功能实现

capture_20240313210800767

如果要写入s,秒的地址为10000000(0x80),读时末位为1。

如果要写入57,用bcd码写入,把57化为16进制:0x57.

所以是先选中,再写入。

小时位如果是12小时制的,通过第三位判断上午下午。

12小时:0x12.

数据地址

capture_20240313211653477

画圈的就是读取和写入数据所调用的地址。

capture_20240313212159492

当复位拉高时才能进行数据写入

数据由上升沿开始读取,每一位是在每一个上升沿才会读。

写入函数定义

1
2
3
4
5
6
7
8
9
10
void write_ds1302(unsigned char temp)
{
unsigned char i;
for(1=0;i<8;i++)
SCK=0;//打开复位,开始读取
SDA=temp&0x01;//屏蔽高七位,保留最后一位为1
temp>>=1;//左移一下,此时,产生上升沿,读取第一位
SCK=1;
}

第二次循环就是第二位为1,那就会读取第二位,循环八次,我会把我需要的数据写入。

1
2
3
4
5
6
7
8
9
void write_ds1302_byte(unsigned char address,unsigned char dat)
{
RST=0; _nop_();//复位拉低,等待
SCK=0; _nop_();//RST拉低,等待
RST=1; _nop_();//复位拉高,等待
write_ds1302(adress);//先写地址
write_ds1302(dat);//再写数据
RST=0;//复位拉低,结束
}

读取函数定义

读取的时候是下降沿。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)//如果SDA为真1,那么temp或10000000,
temp|=0x80;
SCK=1;//拉高后
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}

第一次循环之后,我的数据为100000000,第二次循环,1右移一位,再次判断SDA,循环八次就能读出所有数据了。

值得庆幸的是,这两个底层官方在赛点数据包里提供了。

外设添加

在赛点资源包里添加头文件capture_20240313215714693