基础知识
实时时钟就是一个可以用来计时的芯片,Y3是一个晶振,提供一个时钟基准给DS1302,让DS1302每一秒走时一次。有的实时时钟不需要外接晶振,直接在内部集成了,但蓝桥杯板载的有。
使用的是3线SPI协议,与前面的单总线和IIC协议不一样
电路原理
VCC1:备用电源,可以在板子断电是依然工作,但蓝桥杯板上没有电池,所以就不用管了。蓝桥杯 板重新上电时,必须重新设置时间,让它重新开始走时。
SCLK:串行时钟管脚
I/O:双向通信管脚
RST:控制通讯管脚,低电平时,51板与DS1302不可以进行通讯
芯片特性
实时时钟:计时秒、时、分、日期、月份、星期、年、闰月,可计时到2100年
21个字节的RAM
串行IO空
工作电压2.0V~5.5V
在2.0V,电流小于300nA(低功耗)
单字节或多字节(突发模式)数据传输,可用于读写时钟和RAM,突发模式可解决时间错误问题,蓝桥杯比赛不考,比赛只用单字节传输就可以了。
8脚直插封装或8脚贴片封装
三线通讯接口(三线SPI协议)
TTL兼容
工作温度:-40~+85摄氏度
和DS1202兼容
UL认证
寄存器与指令
SPI协议
写操作:51向DS1302发送数据,在时钟信号SCLK上升沿时,IO的数据被发送给DS1302,上升沿 前,数据要保持稳定。
读操作:51读取DS1302数据,在时钟信号SCLK下降沿时,DS1302发来的数据可以被52单片机IO空 读取,发送下降沿后,51单片机进行读取。
SIP协议也是会提供底层驱动代码的,以下时比赛中会提供的代码
/*
程序说明: DS1302驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include <reg52.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif
设置时间与读取时间
DS1302的数据是采取BCD码来进行编码的,用16进制来表示十进制,例如0x25表示十进制25
设置时间流程:
关闭写保护
写入时钟数据(寄存地址为偶数,并且要记得把十进制转换成BCD)
打开写保护
读取时间流程文章来源:https://www.toymoban.com/news/detail-445585.html
直接调用读取DS1302函数(寄存器地址为奇数,并且要记得把BCD转换成十进制)文章来源地址https://www.toymoban.com/news/detail-445585.html
#define DecToBCD(dec) (dec/10*16)+(dec%10)//十进制转BCD码
#define BCDToDec(bcd) (bcd/16*10)+(bcd%16)//BCD码转十进制
void vClock_Set(u8 hour,u8 minute,u8 second)
{
Write_Ds1302_Byte(0x8e,0x00); //关闭写保护
Write_Ds1302_Byte(0x80,DecToBCD(second));
Write_Ds1302_Byte(0x82,DecToBCD(minute));
Write_Ds1302_Byte(0x84,DecToBCD(hour));
Write_Ds1302_Byte(0x8e,0x80); //打开写保护
}
//将DS1302的时间初值设置为23:59:55,然后读取DS1302的时间,并显示在数码管上
#include "system.h"
HexToBin led_ctrl,uln_ctrl;
/*
* @brief 系统初始化函数:关闭继电器、蜂鸣器
* @param None
* @retval None
* @author dianshe.taobao.com
*/
void vSystem_Init(void)
{
vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
led_ctrl.hex=0xff;
vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
}
//DS1302时间读取
u8 hour,minute,second;
void vDS1302_Process()
{
second = BCDToDec(Read_Ds1302_Byte(0x81));
minute = BCDToDec(Read_Ds1302_Byte(0x83));
hour = BCDToDec(Read_Ds1302_Byte(0x85));
}
//数码管操作函数
void vSMG_Process()
{
smg_buf[0]=smg_code[hour/10]; //旋转电位器的电压值
smg_buf[1]=smg_code[hour%10];
smg_buf[2]=0x00;
smg_buf[3]=smg_code[minute/10];
smg_buf[4]=smg_code[minute%10];
smg_buf[5]=0x00;
smg_buf[6]=smg_code[second/10];
smg_buf[7]=smg_code[second%10];
}
void main(void)
{
vSystem_Init();
vClock_Set(23,59,55);
vTimer2_Init();
while(1)
{
vSMG_Process();
vDS1302_Process();
}
}
//中断服务程序
void vTimer2_ISR() interrupt 12 //中断入口
{
vSMG_Display();
}
到了这里,关于DS1302实时时钟的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!