蓝桥杯单片机基础部分——4、DS1302时钟

介绍

关于蓝桥杯单片机DS1302部分的一些代码,本期主要讲应用,就是基于题目给出的要求可以写出相对应的代码,至于原理后面会详细讲,在这里先了解一下

DS1302芯片

DS1302 是DALLAS 公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31 字节静态RAM
可通过简单的串行接口与单片机进行通信
可提供:
–年月日时分秒 日期 的信息
–每月的天数和闰年的天数可自动调整
–可通过AM/PM 指示决定采用24 或12 小时格式
在这里插入图片描述

管脚说明
GND接地
CE复位引脚输入信号,在读、写数据期间,必须为高
X1 X232.768KHz晶振管脚
I/O输入/输出引脚三线接口时的双向数据线
SCLK串行时钟,输入,控制数据的输入与输出
VCC2备用电源
VCC1主电源

特殊说明
(1)CE复位引脚:该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。
(2)当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2<Vcc1时,由Vcc1向DS1302供电。

电路

参考电路
在这里插入图片描述
实际电路
在这里插入图片描述

注:CLK 和I/O虽然和IIC总线接在一条引脚上,但DS1302其实并不是使用IIC总线,而是一种三线式总线

内部结构

在这里插入图片描述

对应
Power control电源控制模块
Input shift registers输入移位寄存器
Command and control logic通讯与逻辑控制器
Oscillator and divider晶体振荡器及分频器

控制字、寄存器、时序

在这里插入图片描述
(1)控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中
(2)位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据
(3)1~5(A4~A0):指示操作单元的地址
(4)位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。同样,在紧跟8 位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。

在这里插入图片描述

如上图所示:
第一个组为单字节读操作,第二组则为单字节写操作
CE输入驱动高启动所有的数据传输。
SCLK时钟线,每当过来一个上升沿,单片机将地址/数据写到DS1302中,每当过来一个下降沿时,单片机从DS1302里读数据,即DS1302自动将时间数据发送给单片机。
I/O前八位为地址命令字,后八位为时间数据
CE拉高后,SCLK 每过来一个上升沿,单片机向DS1302发送地址命令字,以确定读写的地址
读的时候每来一个下降沿,DS1302向单片机发送数据,单片机读取时间,写就是每来一个上升沿,单片机向DS1302发送数据,设置时间
在这里插入图片描述
如上图所示
时钟日历包含在7个读/写寄存器内,读/写寄存器中的数据是二——十进制的BCD码。
前两列分别是读和写的命令字,对应本模块的第一张图片里面的最后一位,控制读写
秒寄存器的BIT7定义为时间暂停位,当BIT1为1时,时钟振荡器停止工作,DS1302 进入低功耗模式,电源消耗小于100微安,当BIT1为0时,时钟振荡器启动DS1302正常工作。
小时寄存器的BIT7定义为12或24小时工作模式选择位,当BIT7为高时,为12小时工作模式,此时BIT5为AM/PM位,低电平标示AM,高电平标示PM,在24小时模式下,BIT5为第二个10小时位标示(20~23时)。
写保护寄存器的BIT7:WP是写保护位,工作时,出WP外的其他位都置为0,对时钟/日历寄存器或RAM进行写操作之前,WP必须为0,当WP为高电平的时候,不能对任何时钟/日历寄存器或RAM进行写操作。

代码

又臭又长的写了一大坨,不如直接上代码来的实惠,下面就直接看代码
ds1302.c

#include "ds1302.h"


code unsigned char w_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年
code unsigned char r_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; 

unsigned char set[6] = {2,3,5,9,5,5};
unsigned char rtc[6];

/*
*/
void Write_Ds1302_Byte(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302( unsigned char address,unsigned char dat )     
{
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;	
   	_nop_();  
 	Write_Ds1302_Byte(address);	
 	Write_Ds1302_Byte(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302 ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;
	_nop_();
 	Write_Ds1302_Byte(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;
	_nop_();
 	RST=0;
	SCK=0;
	_nop_();
	SCK=1;
	_nop_();
	SDA=0;
	_nop_();
	SDA=1;
	_nop_();
	return (temp);			
}

/*
*/
unsigned char* ReadRTC(void)
{
 	unsigned char i, *p;
	unsigned char tmp[3];
	
 	p = (unsigned char *)r_rtc_address; 	//地址传递
 	
 	for(i=0;i<3;i++){
	  	tmp[i]=Read_Ds1302(*p);
	  	p++;
 	}
	
	rtc[0] = (tmp[2] >> 4);
	rtc[1] = (tmp[2] & 0x0F);
	
	rtc[2] = (tmp[1] >> 4);
	rtc[3] = (tmp[1] & 0x0F);
	
	rtc[4] = (tmp[0] >> 4);
	rtc[5] = (tmp[0] & 0x0F);
	
	return rtc;
}

/*
*/
void SetRTC(void)
{
 	Write_Ds1302(0x8E,0X00);
	
	Write_Ds1302(w_rtc_address[0], (set[4]<<4) | (set[5]));
	Write_Ds1302(w_rtc_address[1], (set[2]<<4) | (set[3]));
	Write_Ds1302(w_rtc_address[2], (set[0]<<4) | (set[1]));
	
	Write_Ds1302(0x8E,0x80);
}




ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

#include "regx52.h"
#include "intrins.h"

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位

void SetRTC(void);
unsigned char* ReadRTC(void);
unsigned char Read_Ds1302 ( unsigned char address );
void Write_Ds1302( unsigned char address,unsigned char dat );     



#endif

实际读写时部分的代码

unsigned char  Write_DS1302_adrr[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char  Read_DS1302_adrr[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};

unsigned char Timer[7] = {0x24,0x18,0x19,0x08,0x03,0x05,0x24};
void DS1302_peizhi()
{
	unsigned char i;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		Write_Ds1302(Write_DS1302_adrr[i],Timer[i]);
	}
	Write_Ds1302(0x8e,0x80);
}

void DS1302_readtime()
{
	unsigned char i;
	for(i=0;i<7;i++)
	{
		Timer[i] = Read_Ds1302(Read_DS1302_adrr[i]);
	}
}
//这后面在分别读取出Timer[i]里面的值,十位是Timer[i]/16,个位Timer[i]%16

上述代码并非所有代码,仅为DS1302部分代码,使代码运行许结合蓝桥杯单片机基础部分——1、基础模块代码使用

本人水平有限,所有代码都是自己的风格书写,但是大致的应该是没有什么问题,希望对大家有帮助如果有哪里出错或者有更好的解法可以与我私信或在评论区里进行讨论

上一节:蓝桥杯单片机基础部分——3、AD转换

内容概要:本文系统梳理了多个科研领域的前沿研究与技术实现,重点涵盖FDTD方法中的完美匹配层(PML)研究,以及Matlab/Simulink在电磁、电力、控制、通信、信号处理、图像处理、路径规划、能源系统优化等领域的仿真与算法实现。文中列举了大量基于Matlab和Python的科研案例,如风电功率预测、负荷预测、无人机三维路径规划、电池系统故障诊断、雷达模拟、通信编码、微电网优化调度等,并强调结合智能优化算法(如粒子群、遗传算法、深度学习等)提升系统性能。同时,提供了丰富的代码资源与仿真模型,涵盖永磁同步电机控制、逆变器设计、多智能体任务分配、虚拟电厂调度等复杂系统,助力科研人员快速开展复现实验与创新研究。; 适合人群:具备一定编程基础,熟悉Matlab/Python工具,从事电气工程、自动化、通信、人工智能、新能源、控制科学等相关领域研究的研发人员及研究生。; 使用场景及目标:① 学习并实现FDTD仿真中的PML边界条件以有效抑制数值反射;② 掌握Matlab/Simulink在多物理场建模、控制系统设计与优化算法中的综合应用;③ 借助提供的代码资源完成科研复现、课程设计、竞赛项目或工程原型开发; 阅读建议:此资源以科研实战为导向,不仅提供理论方法,更强调代码实现与仿真验证。建议读者结合自身研究方向,按目录顺序查阅相关模块,下载配套代码进行调试与二次开发,以达到学以致用、融会贯通的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值