基础知识

实时时钟就是一个可以用来计时的芯片,Y3是一个晶振,提供一个时钟基准给DS1302,让DS1302每一秒走时一次。有的实时时钟不需要外接晶振,直接在内部集成了,但蓝桥杯板载的有。

使用的是3线SPI协议,与前面的单总线和IIC协议不一样

电路原理

VCC1:备用电源,可以在板子断电是依然工作,但蓝桥杯板上没有电池,所以就不用管了。蓝桥杯 板重新上电时,必须重新设置时间,让它重新开始走时。

SCLK:串行时钟管脚

I/O:双向通信管脚

RST:控制通讯管脚,低电平时,51板与DS1302不可以进行通讯

芯片特性

  1. 实时时钟:计时秒、时、分、日期、月份、星期、年、闰月,可计时到2100年

  1. 21个字节的RAM

  1. 串行IO空

  1. 工作电压2.0V~5.5V

  1. 在2.0V,电流小于300nA(低功耗)

  1. 单字节或多字节(突发模式)数据传输,可用于读写时钟和RAM,突发模式可解决时间错误问题,蓝桥杯比赛不考,比赛只用单字节传输就可以了。

  1. 8脚直插封装或8脚贴片封装

  1. 三线通讯接口(三线SPI协议)

  1. TTL兼容

  1. 工作温度:-40~+85摄氏度

  1. 和DS1202兼容

  1. 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

设置时间流程:

  1. 关闭写保护

  1. 写入时钟数据(寄存地址为偶数,并且要记得把十进制转换成BCD)

  1. 打开写保护

读取时间流程

直接调用读取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的时间初值设置为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();
}

物联沃分享整理
物联沃-IOTWORD物联网 » DS1302实时时钟

发表评论