(基于江协科技)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;
}
相关推荐
充哥单片机设计3 小时前
【STM32项目开源】基于STM32的工地环境监测系统
stm32·单片机·嵌入式硬件
速易达网络4 小时前
树莓派点亮LED灯
单片机·嵌入式硬件
straw_hat.4 小时前
PCB学习——STM32F103VET6-STM32主控部分
stm32·嵌入式硬件·学习
hazy1k5 小时前
K230基础-显示画面
stm32·单片机·嵌入式硬件·k230
蒋楼丶12 小时前
stm32和Zynq的中断抢占机制
stm32·单片机·嵌入式硬件
bmcyzs13 小时前
【展厅多媒体】解析VR虚拟驾驶实现多场景自由切换
经验分享·科技·信息可视化·软件构建·vr·设计规范
xyx-3v13 小时前
已知三极管的类型(NPN/PNP)和基极引脚,如何区分集电极(c)和发射极(e)
单片机·嵌入式硬件·学习
随机惯性粒子群14 小时前
STM32控制开发学习笔记【基于STM32 HAL库】
笔记·stm32·嵌入式硬件·学习
Deepoch15 小时前
中秋国庆双节餐饮零售破局!Deepoc 具身模型外拓板打造 “假日智能运营新范式
科技·机器人·人机交互·具身智能