最近正在准备蓝桥杯单片机比赛,学习这台单片机的时候,里面涉及到DS1302芯片的使用,所以今天在这里写一个学习使用DS1302的过程,方便以后查
DS1302是DALLAS公司推出的涓流充电时钟芯片,芯片内包含实时时钟和31字节静态RAM,可以通过简单的串行接口与单片机进行通信。
与单片机连接的参考电路如上所述。 显然,与单片机连接需要三条线。
CE复位端:输入信号必须高,以便在读取和写入数据期间保持空闲,因此该端包括两个功能: CE开始控制字访问移位寄存器的控制逻辑,以及终止一个或多个字节的数据传输
I/O端子:三线连接器时的双向数据线。
SCLK:串行时钟、输入、控制数据的输入输出。
我知道怎么连接布线,所以直接开始编写程序吧。 (一些单片机板在制造过程中已经连接起来)
其实任何芯片使用的过程都是一样的,只是先进行初始化,初始化后才能进行自己想要的读写(与芯片的通信)。
说到初始化,似乎是与芯片的通信不同的操作,但实际上是相同的,对芯片的寄存器进行读写操作。 当然初始化只是简单的写入。 为了写,必须知道DS1302控制字的格式,如下图所示。
一共八个人。
最高有效位必须为7:1,如果为0,则无法将数据写入DS1302。
位6:0表示操作时钟数据,1表示操作RAM数据。
BIT5~BIT1:读写寄存器的地址。
位0:0时写入,1时读取。
读取动作示意图
写入操作示意图
很明显,在数据操作之前必须提高CE。 在读操作中,在前8个周期中输入读命令字节,数据字节在下8个周期的下降沿输出。 请注意,在第一个数据字节的第一个下降沿发生后,将写入命令字的最后一位。
对于写入操作,在前8个周期中输入一个写入命令字节,在下一个8个周期的启动时输入数据字节。
下面发布蓝桥杯官方推出的读写操作函数。
unsignedcharread _ ds 1302 _ byte (void )
{
无符号char I,dat=0;
for(I=0; i8; I )
{
dat=dat 1; //读取的数据从下位开始读取,所以不断向右移动
if(sda_r )//#define SDA_R SDA双向数据线的电平读取
//你可能会怀疑在这里是否能读取水平?
dat |=0x80; //是不是还没有下降沿的制造,为什么数据会传输到SDA线上呢
//如上所述,在第一个数据字节的第一个下降沿发生之后,
else //指令字的最后一位写入,即写入操作的最后一位和读取操作的第一位
//的传输紧接着发生,高兴的时候写入要读取的寄存器的地址,传输的字节的
dat=0x7F;//第一名当然到达了SDA线。
}
SCK_SET; //提高或降低时钟周期的水平,形成上升、下降边缘
SCK_CLR;
}
返回日期;
}
void write _ ds 1302 _ byte (unsignedchardat ) )。
{
无符号char I;
SCK=0;
for(I=0; i8; I )
{
(if ) dat0x01 )//同样从最低位开始写
{
SDA_SET; //#define SDA_SET SDA=1
}
else
{
SDA_CLR; //#define SDA_CLR SDA=0
}
SCK_SET; //同样地制作上升下降沿,用于数据传输
SCK_CLR;
dat=dat 1;
}
}
虽然上面提到要根据时间顺序编写DS1302的读/写程序,但必须对指定的寄存器执行读/写操作。 由此,需要知道寄存器的地址。 各寄存器地址如下图所示。
DS1302内部共有12个寄存器,其中7个寄存器与时钟、日历有关。 没错,是上表的前七个。 寄存器的数据是2----10十进制的BCD代码。
下面对这7个寄存器中比较特殊的2个寄存器进行说明。 秒寄存器和时间寄存器
。秒寄存器:BIT7位,时间暂停位,当为1时,时钟振荡器停止工作,DS1302进入低功耗模式,当为0时,DS1302正常工作。
小时寄存器:BIT7用来选择12小时还是24小时工作模式,很显然为1是12小时工作模式,为0是24小时工作模式,BIT5为AM/PM位,为0是AM模式,为1是PM模式。
上表中的倒数第二个为写保护寄存器:WP是写保护位,工作时,除WP外的其他位都置0,对时钟寄存器或RAM进行写操作之前,WP必须置为0,当WP为1,不得对任何时钟寄存器或者RAM进行写操作。
下面说一下对指定寄存器进行读写操作。依旧给出蓝桥杯官网给出的代码。
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp;
RST_CLR; //CE引脚置低
SCK_CLR; //时钟线拉低
RST_SET; //CE引脚置高,开始数据传输
addr = addr | 0x01; //前面说过,要进行读操作,控制字最后一位应置1
Write_Ds1302_Byte(addr); //写入地址
temp=Read_Ds1302_Byte(); //读出数据
RST_CLR; //CE引脚拉低
return temp;
}
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
RST_CLR;
SCK_CLR;
RST_SET;
addr = addr & 0xFE; //同样,控制字最后一位置0,确保是写操作
Write_Ds1302_Byte(addr); //写地址
Write_Ds1302_Byte(dat); //写数据
RST_CLR;
}
好,最基本的函数讲解介绍完了,这些也是蓝桥杯大赛时给出的库函数,下面我将介绍利用这些函数完成DS1302的初始化以及读写DS1302的操作。
初始化函数如下所示:
void Init_DS1302(void)
{
Ds1302_Single_Byte_Write(0x8e,0x00);
Ds1302_Single_Byte_Write(ds1302_sec_addr,0x00);
Ds1302_Single_Byte_Write(ds1302_min_addr,0x20);
Ds1302_Single_Byte_Write(ds1302_hr_addr,0x09);
Ds1302_Single_Byte_Write(ds1302_date_addr,0x25);
Ds1302_Single_Byte_Write(ds1302_month_addr,0x12);
Ds1302_Single_Byte_Write(ds1302_day_addr,0x06);
Ds1302_Single_Byte_Write(ds1302_year_addr,0x10);
Ds1302_Single_Byte_Write(ds1302_charger_addr,0x01);
Ds1302_Single_Byte_Write(0x8e,0x80);
}
当然还有对应的一些宏定义:
#define ds1302_sec_addr 0x80
#define ds1302_min_addr 0x82
#define ds1302_hr_addr 0x84
#define ds1302_date_addr 0x86
#define ds1302_month_addr 0x88
#define ds1302_day_addr 0x8A
#define ds1302_year_addr 0x8C
没错,初始化就是在相应地址写上相应的初始化操作数据。
当初始化完成之后,就可以与DS1302进行通信了,即配合使用上面的函数就可以读出相应寄存器的内容。