蓝桥杯单片机基础部分——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转换

### 关于蓝桥杯单片机DS1302项目的实现方案 #### 项目背景 蓝桥杯竞赛中的单片机设计题目通常涉及硬件电路与软件编程相结合的任务。其中,DS1302是一种常用的实时时钟芯片,能够提供精确的时间信息并支持掉电保护功能。在实际应用中,它常被用来记录设备运行时间、定时控制或其他需要精准计时的功能。 以下是关于如何利用DS1302完成蓝桥杯竞赛相关项目的具体实现方案: --- #### 硬件连接说明 DS1302通过三线接口(SCLK、I/O 和 RST)与单片机通信。为了确保正常工作,需注意以下几点: - **电源供电**:DS1302的工作电压范围为2.5V至5.5V,因此可以直接由单片机的IO口或外部稳压源供电。 - **数据传输方向**:RST引脚决定当前操作是写入还是读取;SCLK负责同步时钟信号;I/O则作为双向数据通道[^1]。 --- #### 初始化配置 在使用DS1302之前,必须对其进行初始化设置。这包括设定初始时间和日期参数以及开启相应的寄存器位。一般情况下,可以通过向特定寄存器地址发送命令字来完成这些操作。例如,在C语言环境下可以定义如下函数用于写入指定位置的数据: ```c void write_ds1302_byte(unsigned char reg_addr, unsigned char data){ P2_7 = 0; //拉低RESET端准备进入写状态 delay_us(1); //短暂停留等待稳定 send_cmd(reg_addr | WR_BIT); //拼接上写标志位后发出目标寄存单元号 send_data(data); //随后送出待存储数值即可结束整个过程 P2_7 = 1; //最后释放RESET回到高阻态恢复默认模式 } ``` 上述代码片段展示了如何构建一个通用型的字节级写方法。 --- #### 时间显示模块 对于大多数比赛场景而言,除了基本的日历维护外还需要具备直观易懂的人机交互界面以便观察实时动态变化情况。这里推荐采用LCD液晶屏配合四位数码管共同构成完整的可视化平台解决方案。假设已经搭建好基础驱动框架,则只需定期调用获取最新时刻的方法并将结果显示出来就可以了: ```c unsigned char read_time_from_ds1302(){ static unsigned char buffer[9]; //预留足够的空间容纳全部字段内容 memset(buffer ,0,sizeof(buffer)); //清零以防残留干扰后续解析逻辑 for(int i=0;i<8;i++) //循环遍历每一个独立组件逐一提取原始编码形式 buffer[i]=read_ds1302_byte(i); decode_bcd_to_ascii(buffer); //将BCD码转ASCII便于打印输出处理 display_on_screen((char*)buffer); //最终呈现在屏幕上供用户查看确认无误 } ``` 此部分重点在于正确解读来自内部缓冲区的信息并通过适当方式呈现给外界感知。 --- #### 故障排查建议 尽管理论分析清晰明了但在实践过程中难免遇到各种异常状况比如无法正确更新或者丢失某些重要属性等问题都需要仔细甄别原因所在。针对前面提到过的有关温度调节方面的困惑可能源于以下几个方面的原因造成: - 检查是否存在竞争条件导致冲突发生; - 验证所使用的库文件版本兼容性是否匹配预期需求; - 审核全局变量声明范围内是否有重复定义覆盖现象存在[^3]。 如果仍然未能解决疑问不妨尝试更换其他替代算法重新验证效果差异之处。 --- ### 总结 综上所述围绕着蓝桥杯赛事主题展开讨论介绍了基于DS1302为核心的软硬协同设计方案涵盖了从底层物理链接直至高层业务展现全流程环节的内容介绍希望能够帮助参赛选手更好地理解和掌握关键技术要点从而取得理想成绩!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值