DS1302实时时钟
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
基础知识
实时时钟就是一个可以用来计时的芯片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单片机综合实训平台 805112MHz
日 期: 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
打开写保护
读取时间流程
直接调用读取DS1302函数寄存器地址为奇数并且要记得把BCD转换成十进制
#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的时间初值设置为235955然后读取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();
}