(基于江协科技)51单片机入门:8.DS1302

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;
}
相关推荐
别掩1 小时前
MOS防倒灌电路设计
单片机·嵌入式硬件
夜流冰1 小时前
EE - 电容电感电路中电流的变化
单片机·嵌入式硬件
橙露2 小时前
STM32中断配置全解析:从寄存器到HAL库的实战应用
stm32·单片机·嵌入式硬件
c-u-r-ry302 小时前
ZYNQ7 Processing System各个配置界面介绍
嵌入式硬件
北京耐用通信2 小时前
耐达讯自动化赋能:Canopen转Profibus网关水泵连接新范式
人工智能·科技·物联网·自动化·信息与通信
idcardwang3 小时前
esp32s3-pwm介绍与stm32的不同原理
单片机·嵌入式硬件
码咔吧咔3 小时前
Flash 是什么?SRAM 是什么?它们的作用、特点、区别、在 STM32 中如何使用?
stm32·嵌入式硬件
三佛科技-187366133974 小时前
KP521405LGA低功耗5V1A易用高性能BUCK同步降压转换器芯片解析
单片机·嵌入式硬件
Joshua-a4 小时前
FPGA基于计数器的分频器时序违例的解决方法
嵌入式硬件·fpga开发·fpga
Dillon Dong5 小时前
STM32嵌入式:如何使用keil 来获取flash块数据并转换成可视化的数据 来判断源头数据是否错误
stm32·单片机·嵌入式硬件