注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

耳朵的博客

做自己想做的人

 
 
 

日志

 
 

DS1302通用程序源代码[原创] 已测试AVR,STM8,51  

2010-11-16 15:20:00|  分类: 程序源代码 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

ds1302.h:

/************ DS1302程序 ************
* 版本.........: 1.0
* 作者.........: 陈利栋
* 文件名.......: ds1302.h
* 创建时间.....: 2010.11.11
* 最后修改.....: 2010.11.11
************************************/
#ifndef __DS1302_H__
#define __DS1302_H__

#include <ds1302_config.h>

// 寄存器地址定义
#define DS1302_SECOND_ADDR              0x80
#define DS1302_MINUTE_ADDR              0x82
#define DS1302_HOUR_ADDR                0x84
#define DS1302_DATE_ADDR                0x86
#define DS1302_MONTH_ADDR               0x88
#define DS1302_DAY_ADDR                 0x8a
#define DS1302_YEAR_ADDR                0x8c
#define DS1302_WRITE_PROTECT_ADDR       0x8e     // 写保护
#define DS1302_TRICKLE_CHARGE_ADDR      0x90     // 涓流充电
#define DS1302_CLOCK_BURST_ADDR         0xbe     // 连续读写

#if DS1302_AUTO_TO_DEC == 1

#define DEC_TO_BCD(d) DecToBcd(d)
#define BCD_TO_DEC(b) BcdToDec(b)

#else

#define DEC_TO_BCD(d) d
#define BCD_TO_DEC(b) b

#endif /* DS1302_AUTO_TO_DEC == 1 */

typedef enum
{
    _12_hours, _24_hours
}HourMode_t;

typedef enum
{
    am, pm
}AM_PM_t;

// DS1302日期时间结构
typedef struct
{
    unsigned char Year;                 // 年 0 - 99
    unsigned char Month;                // 月 1 - 12
    unsigned char Date;                 // 日 1 - 31
    unsigned char Hour;                 // 时 1 - 12 或 0 - 23
    unsigned char Minute;               // 分 0 - 59
    unsigned char Second;               // 秒 0 - 59
    unsigned char Day;                  // 星期 1 - 7 星期天 = 7
    HourMode_t    HourMode;             // 小时模式 _12_hours 或 _24_hours
    AM_PM_t       AM_PM;                // 上午下午标志 12时制时有效 am 或 pm
}DS1302_DateTime_t;

// 更新标记 1:已更新 0:未更新
// 调用 DS1302_GetDateTime 后自动清零
extern volatile unsigned char DS1302_Update;

/* 存放日期和时间的变量 
   执行 DS1302_GetDateTime 后 时间日期写入到该变量
   修改此值,并执行 DS1302_SetDateTime, 更新到DS1302   */
extern DS1302_DateTime_t DS1302_DateTime;

// 初始化
void DS1302_Init(void);

// 读取日期和时间, DS1302 -> DS1302_DateTime          
void DS1302_GetDateTime(void);

// 设置日期和时间, DS1302_DateTime -> DS1302
void DS1302_SetDateTime(void);

// 扫描(轮询)函数, 扫描频率应大于1Hz
void DS1302_Scan(void);


#endif /* __DS1302_H__ */

 

ds1302.c:

/************ DS1302程序 ************
* 版本.........: 1.0
* 作者.........: 陈利栋
* 文件名.......: ds1302.c
* 创建时间.....: 2010.11.11
* 最后修改.....: 2010.11.11
************************************/
#include "ds1302.h"

volatile unsigned char DS1302_Update = 0;
DS1302_DateTime_t DS1302_DateTime;

static unsigned char GetDayFromDate(unsigned char year, unsigned char month, unsigned char date);

// 发送一个字节,不操作CE
static void DS1302_TxByte(unsigned char byte)
{
    unsigned char i = 0;

    DS1302_IO_OUT;
    for (i = 0; i < 8; i++)
    {
        DS1302_SCLK_0;
        DS1302_DELAY_T_CL;
        if (byte & 0x01)
        {
            DS1302_IO_1;
        }
        else
        {
            DS1302_IO_0;
        }
        DS1302_DELAY_T_DC;
        DS1302_SCLK_1;
        DS1302_DELAY_T_CH;
        byte >>= 1;
    }
}

// 接收一个字节,不操作CE
static unsigned char DS1302_RxByte(void)
{
    unsigned char i = 0;
    unsigned char byte = 0;

    DS1302_IO_IN;
    DS1302_IO_1;           
    for (i = 0; i < 8; i++)
    {
        DS1302_SCLK_0;
        DS1302_DELAY_T_CDD;
        byte >>= 1;
        if (DS1302_IO_VALUE)
        {
            byte |= 0x80;
        }
        DS1302_SCLK_1;
        DS1302_DELAY_T_CH;
    }

    return byte;
}

static void DS1302_WriteByte(unsigned char address, unsigned char _data)
{
    DS1302_SCLK_0;
    DS1302_CE_1;
    DS1302_DELAY_T_CC;
    DS1302_TxByte(address);
    DS1302_TxByte(_data);
    DS1302_SCLK_0;
    DS1302_DELAY_T_CCH;
    DS1302_CE_0;
    DS1302_DELAY_T_CWH;  
}

static unsigned char DS1302_ReadByte(unsigned char address)
{
    unsigned char _data = 0;

    DS1302_SCLK_0;
    DS1302_CE_1;
    DS1302_DELAY_T_CC;   
    DS1302_TxByte(address | 0x01);
    _data = DS1302_RxByte();
    DS1302_SCLK_0;
    DS1302_DELAY_T_CCH;
    DS1302_CE_0;
    DS1302_DELAY_T_CWH;
    
    return _data;
}

#if DS1302_AUTO_TO_DEC == 1

static unsigned char DecToBcd(unsigned char d)
{
    return ((((d) / 10) << 4) + ((d) % 10));       
}

static unsigned char BcdToDec(unsigned char b)
{
    return ((((b) >> 4) * 10) + ((b) & 0x0f));       
}

#endif /* DS1302_AUTO_TO_DEC == 1 */

void DS1302_SetDateTime(void)
{
    unsigned char temp = 0;
   
    DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x00);         // 关闭写保护

    DS1302_WriteByte(DS1302_YEAR_ADDR,   DEC_TO_BCD(DS1302_DateTime.Year));
    DS1302_WriteByte(DS1302_MONTH_ADDR,  DEC_TO_BCD(DS1302_DateTime.Month));
    DS1302_WriteByte(DS1302_DATE_ADDR,   DEC_TO_BCD(DS1302_DateTime.Date));
    DS1302_WriteByte(DS1302_MINUTE_ADDR, DEC_TO_BCD(DS1302_DateTime.Minute));
    DS1302_WriteByte(DS1302_SECOND_ADDR, DEC_TO_BCD(DS1302_DateTime.Second));
    DS1302_WriteByte(DS1302_DAY_ADDR,    DEC_TO_BCD(GetDayFromDate(DS1302_DateTime.Year, DS1302_DateTime.Month, DS1302_DateTime.Date)));
   
    temp = DEC_TO_BCD(DS1302_DateTime.Hour);
    if (DS1302_DateTime.HourMode == _12_hours)
    {
        temp |= 0x80;
        temp |= (DS1302_DateTime.AM_PM == pm ? 0x20 : 0);
    }
    DS1302_WriteByte(DS1302_HOUR_ADDR, temp);

    DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x80);         // 写入完毕后设置写保护
}

void DS1302_GetDateTime(void)
{
    unsigned char temp = 0;

    DS1302_Update = 0;

    DS1302_DateTime.Year   = BCD_TO_DEC(DS1302_ReadByte(DS1302_YEAR_ADDR));
    DS1302_DateTime.Month  = BCD_TO_DEC(DS1302_ReadByte(DS1302_MONTH_ADDR));
    DS1302_DateTime.Date   = BCD_TO_DEC(DS1302_ReadByte(DS1302_DATE_ADDR));
    DS1302_DateTime.Minute = BCD_TO_DEC(DS1302_ReadByte(DS1302_MINUTE_ADDR));
    DS1302_DateTime.Second = BCD_TO_DEC(DS1302_ReadByte(DS1302_SECOND_ADDR));
    DS1302_DateTime.Day    = BCD_TO_DEC(DS1302_ReadByte(DS1302_DAY_ADDR));

    temp = DS1302_ReadByte(DS1302_HOUR_ADDR);
    if (temp & 0x80)
    {
        DS1302_DateTime.HourMode = _12_hours;
        DS1302_DateTime.AM_PM = ((temp & 0x20) ? pm : am);
        temp &= 0x1f;
    }
    DS1302_DateTime.Hour = BCD_TO_DEC(temp);
}

void DS1302_Scan(void)
{
    static unsigned second_last = 0;

    DS1302_DateTime.Second = BCD_TO_DEC(DS1302_ReadByte(DS1302_SECOND_ADDR));
    if (second_last != DS1302_DateTime.Second)
    {
        second_last = DS1302_DateTime.Second;
        DS1302_Update = 1;
    }
}

void DS1302_Init(void)
{
    // 端口初始化
    DS1302_CE_0;
    DS1302_CE_OUT;
    DS1302_SCLK_0;
    DS1302_SCLK_OUT;

    DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x00);        // 关闭写保护
    DS1302_WriteByte(DS1302_TRICKLE_CHARGE_ADDR, 0xa7);       // 使能涓流充电 1 Diode, 8kΩ
    if (DS1302_ReadByte(DS1302_SECOND_ADDR) & 0x80)           // 振荡器未启动
        DS1302_WriteByte(DS1302_SECOND_ADDR, 0x00);           // 启动振荡器
    DS1302_WriteByte(DS1302_WRITE_PROTECT_ADDR, 0x80);        // 打开写保护
}

// 计算2000~2099年任一天星期几
// year        : 00-99
// month       : 01-12
// day         : 01-31
// 返回 1 -> 7 : 星期一 -> 星期天
static unsigned char GetDayFromDate(unsigned char year, unsigned char month, unsigned char date)
{
    if (month == 1 || month == 2
    {
        month += 12;
        if (year > 0)
            year--;
        else
            year = 4;
    }
    return (1 + ((date + 2 * month + 3 * (month + 1) / 5 + year + year / 4) % 7));
}

 

 

ds1302_config.h:
/********** DS1302程序配置 **********
* 版本.........: 1.0
* 作者.........: 陈利栋
* 文件名.......: ds1302_config.h
* 创建时间.....: 2010.11.11
* 最后修改.....: 2010.11.11
************************************/
#ifndef __DS1302_CONFIG_H__
#define __DS1302_CONFIG_H__

#include <ioavr.h>
#include "delay.h"


// 1:自动转换成10进制  0:BCD格式
#define DS1302_AUTO_TO_DEC       1


// 端口控制命令定义
#define DS1302_IO_0              PORTC &= ~(1 << 2)       
#define DS1302_IO_1              PORTC |= (1 << 2)         
#define DS1302_IO_IN             DDRC &= ~(1 << 2)         
#define DS1302_IO_OUT            DDRC |= (1 << 2)        
#define DS1302_IO_VALUE          (PINC & (1 << 2)) 
       
#define DS1302_SCLK_0            PORTC &= ~(1 << 1)        
#define DS1302_SCLK_1            PORTC |= (1 << 1)         
#define DS1302_SCLK_OUT          DDRC |= (1 << 1)  
      
#define DS1302_CE_0              PORTC &= ~(1 << 0)
#define DS1302_CE_1              PORTC |= (1 << 0)
#define DS1302_CE_OUT            DDRC |= (1 << 0)


// 延时时间定义(参照datasheet)
#define DS1302_DELAY_T_DC        _delay_us(1)
#define DS1302_DELAY_T_CDH       _delay_us(1)
#define DS1302_DELAY_T_CDD       _delay_us(1)
#define DS1302_DELAY_T_CL        _delay_us(1)
#define DS1302_DELAY_T_CH        _delay_us(1)
#define DS1302_DELAY_T_CC        _delay_us(4)
#define DS1302_DELAY_T_CCH       _delay_us(1)
#define DS1302_DELAY_T_CWH       _delay_us(4)


#endif /* __DS1302_CONFIG_H__ */


  评论这张
 
阅读(2431)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018