DS1302
DS1302是具有眷细电流充电能力的低功耗实时时钟芯片
DS1302可自带一块电池,以保证掉电计时
RTC(real time clock):实时时钟,是一种集成电路,通常称为时钟芯片


CE 为芯片使能:作用为控制从DS1302中获取数据,给以0获取不了,给1有可能获取
IO:数据输入和输出
SCLK:串行时钟
命令字

第 7 位固定为1
第 6 位选择是 RAM 还是 CK
第 0 为选择是 读 还是 写
字母上加一横表示为 0有效 或低电频有效
写入

RTC

读出

根据写入和读出去写DS1302函数
源文件
cpp
#include <REGX52.H>
sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;
void DS1302_Init()
{
DS1302_CE = 0;
DS1302_SCLK = 0;
}
void DS1302_Wr(unsigned char c,d)
{
unsigned char i = 0;
DS1302_CE = 1;
// 命令字
for(i = 0 ; i < 8; i++){
DS1302_IO = c&(0x01<<i);
DS1302_SCLK = 1;
DS1302_SCLK = 0;
}
// 写入数据
for(i = 0 ; i < 8; i++){
DS1302_IO = d&(0x01<<i);
DS1302_SCLK = 1;
DS1302_SCLK = 0;
}
DS1302_CE = 0;
}
unsigned char DS1302_Rd(unsigned char c)
{
unsigned char ret = 0;
unsigned char i = 0;
DS1302_CE = 1;
// 命令字
for(i = 0 ; i < 8; i++){
DS1302_IO = c&(0x01<<i);
DS1302_SCLK = 0;
DS1302_SCLK = 1;
}
// 读取数据 这里的写法和上面不同
for(i = 0; i < 8; i++){
DS1302_SCLK = 1;
DS1302_SCLK = 0; // 命令字结束后的第一个下降沿要先进行,将io赋值
if(DS1302_IO){ret|=(0x01<<i);} // 表示读出值为1 就在相对应的位赋1
} // 为0,ret初始化就是0,所以相对应的位也为0
return ret;
}
头文件
cpp
#ifndef __DS1302_H_
#define __DS1302_H_
void DS1302_Init();
void DS1302_Wr(unsigned char c,d);
unsigned char DS1302_Rd(unsigned char c);
#endif
注意在主函数里利用函数时,DS1302初始化后
要跟哥DS1302_Wr(0x8e,0x00)关闭写入保护
BCD码
用4位二进制来表示1位十进制
BCD码转十进制:BCD/16*10 + BCD%16;(2位BCD)
十进制转BCD码:BCD = DEC/10*16 + DEC%10;(2位BCD)
DS1302内部已经限制了相对应内容的最大值
例如:秒 60 分钟 60 小时 24(会自动从新计数)、
后加2函数的思路是:利用数组将DS1302内部初始化(DS1302_SetTime),利用数组将DS1302内部数据读出存入数组中(DS1302_ReadTime),在主函数中调用一次DS1302_SerTime,在循环中调用DS1302_ReadTime(实现数据更新)
DS1302函数:
源文件
cpp
#include <REGX52.H>
sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;
unsigned char arr[] = {19,11,16,12,59,55,6};
// 写入地址
#define DS1302_S 0x80
#define DS1302_M 0x82
#define DS1302_H 0x84
#define DS1302_Date 0x86
#define DS1302_Month 0x88
#define DS1302_Day 0x8a
#define DS1302_Year 0x8c
#define DS1302_WP 0x8e
void DS1302_Init()
{
DS1302_CE = 0;
DS1302_SCLK = 0;
}
void DS1302_Wr(unsigned char c,d)
{
unsigned char i = 0;
DS1302_CE = 1;
// 命令字
for(i = 0 ; i < 8; i++){
DS1302_IO = c&(0x01<<i);
DS1302_SCLK = 1;
DS1302_SCLK = 0;
}
// 数据
for(i = 0 ; i < 8; i++){
DS1302_IO = d&(0x01<<i);
DS1302_SCLK = 1;
DS1302_SCLK = 0;
}
DS1302_CE = 0;
}
unsigned char DS1302_Rd(unsigned char c)
{
unsigned char ret = 0;
unsigned char i = 0;
c |=0x01;
DS1302_CE = 1;
// 命令字
for(i = 0 ; i < 8; i++){
DS1302_IO = c&(0x01<<i);
DS1302_SCLK = 0;
DS1302_SCLK = 1;
}
for(i = 0; i < 8; i++){
DS1302_SCLK = 1;
DS1302_SCLK = 0;
if(DS1302_IO){ret|=(0x01<<i);}
}
DS1302_CE = 0;
return ret;
}
void DS1302_SetTime(void)
{
DS1302_Wr(DS1302_WP,0X00); // 关闭写保护
DS1302_Wr(DS1302_Year,arr[0]/10*16+arr[0]%10); // DS1302数据是以BCD码存入
// 所以要10进制转化
DS1302_Wr(DS1302_Month,arr[1]/10*16+arr[1]%10);
DS1302_Wr(DS1302_Date,arr[2]/10*16+arr[2]%10);
DS1302_Wr(DS1302_H,arr[3]/10*16+arr[3]%10);
DS1302_Wr(DS1302_M,arr[4]/10*16+arr[4]%10);
DS1302_Wr(DS1302_S,arr[5]/10*16+arr[5]%10);
DS1302_Wr(DS1302_Day,arr[6]/10*16+arr[6]%10);
DS1302_Wr(DS1302_WP,0X80); // 打开写保护
}
void DS1302_ReadTime(void)
{
unsigned char tmp = 0;
tmp = DS1302_Rd(DS1302_Year);
arr[0]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_Month);
arr[1]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_Date);
arr[2]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_H);
arr[3]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_M);
arr[4]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_S);
arr[5]=tmp/16*10 + tmp%16;
tmp = DS1302_Rd(DS1302_Day);
arr[6]=tmp/16*10 + tmp%16;
}
头文件
cpp
#ifndef __DS1302_H_
#define __DS1302_H_
extern unsigned char arr[];
void DS1302_Init();
void DS1302_Wr(unsigned char c,d);
unsigned char DS1302_Rd(unsigned char c);
void DS1302_SetTime(void);
void DS1302_ReadTime(void);
#endif
1.时钟主函数文件
cpp
#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"
int main()
{
DS1302_Init();
LCD_Init();
DS1302_SetTime();
while(1)
{
DS1302_ReadTime();
LCD_ShowString(1,1," _ _");
LCD_ShowNum(1,1,arr[0],2);
LCD_ShowNum(1,4,arr[1],2);
LCD_ShowNum(1,7,arr[2],2);
LCD_ShowString(2,1," : :");
LCD_ShowNum(2,1,arr[3],2);
LCD_ShowNum(2,4,arr[4],2);
LCD_ShowNum(2,7,arr[5],2);
}
return 0;
}