ds1302.c
#include "ds1302.h"
// 定义RTC初始化结构体,决定了初始化时间
RTC_TIME rtc_time = {
25, // 秒
35, // 分
02, // 时
25, // 日
4, // 月
4, // 星期
19 // 年
};
/*******************************************************************************
* 函 数 名 : bcd_to_hex
* 函数功能 : 从时钟芯片中读出的时间数据,需转换为十进制数。
* 输 入 : val:需要转换的值
* 输 出 : 无
*******************************************************************************/
static uint8_t bcd_to_hex(uint8_t val)
{
uint8_t temp;
temp = val & 0x0f;
val >>= 4;
val &= 0x0f;
val *= 10;
temp += val;
return temp;
}
/*******************************************************************************
* 函 数 名 : hex_to_bcd
* 函数功能 : 往时钟芯片写入数据时,需将待写的十进制数转换为8421码。
* 输 入 : val:需要转换的值
* 输 出 : 无
*******************************************************************************/
static uint8_t hex_to_bcd(uint8_t val)
{
uint8_t i,j,k;
i = val / 10;
j = val % 10;
k= j + (i << 4);
return k;
}
/*******************************************************************************
* 函 数 名 : DS1302_Write
* 函数功能 : 向DS1302命令(地址+数据)
* 输 入 : addr,dat
* 输 出 : 无
*******************************************************************************/
static void DS1302_Write(uint8_t addr, uint8_t dat)
{
uint8_t n;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1; //然后将RST(CE)置高电平。
_nop_();
for (n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//传送数据结束
_nop_();
}
/*******************************************************************************
* 函 数 名 : DS1302_Read
* 函数功能 : 读取一个地址的数据
* 输 入 : addr
* 输 出 : dat
*******************************************************************************/
static uint8_t DS1302_Read(uint8_t addr)
{
uint8_t n;
uint8_t dat;
uint8_t dat1;
RST = 0;
_nop_();
/* 先将SCLK置低电平 */
SCLK = 0;
_nop_();
/* 然后将RST(CE)置高电平 */
RST = 1;
_nop_();
/* 开始传送八位地址命令 */
for(n=0; n<8; n++)
{
DSIO = addr & 0x01; /* 数据从低位开始传送 */
addr >>= 1;
SCLK = 1; /* 数据在上升沿时,DS1302读取数据 */
_nop_();
SCLK = 0; /* DS1302下降沿时,放置数据 */
_nop_();
}
_nop_();
/* 读取8位数据 */
for(n=0; n<8; n++)
{
dat1 = DSIO; /* 从最低位开始接收 */
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0; /* DS1302下降沿时,放置数据 */
_nop_();
}
/* 以下为DS1302复位的稳定时间,必须的 */
RST = 0;
_nop_();
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
/*******************************************************************************
* 函 数 名 : DS1302_ReadTime
* 函数功能 : 读取时钟信息
* 输 入 : RTC_TIME类型的结构体指针,RTC_TIME的成员有:
rtc_sec 秒
rtc_min 分钟
rtc_hour 小时
rtc_date 日
rtc_month 月
rtc_day 星期
rtc_year 年
* 输 出 : 无
*******************************************************************************/
void DS1302_ReadTime(RTC_TIME *rtc_time)
{
unsigned temp;
temp = DS1302_Read(SEC_ADDR | 0x01);
rtc_time->rtc_sec = bcd_to_hex(temp);
temp = DS1302_Read(MIN_ADDR | 0x01);
rtc_time->rtc_min = bcd_to_hex(temp);
temp = DS1302_Read(HR_ADDR | 0x01);
rtc_time->rtc_hour = bcd_to_hex(temp);
temp = DS1302_Read(DATE_ADDR | 0x01);
rtc_time->rtc_date = bcd_to_hex(temp);
temp = DS1302_Read(MON_ADDR | 0x01);
rtc_time->rtc_month = bcd_to_hex(temp);
temp = DS1302_Read(DAY_ADDR | 0x01);
rtc_time->rtc_day = bcd_to_hex(temp);
temp = DS1302_Read(YEAR_ADDR | 0x01);
rtc_time->rtc_year = bcd_to_hex(temp);
}
/*******************************************************************************
* 函 数 名 : DS1302_SetTime
* 函数功能 : 向DS1302写入时间
* 输 入 : RTC_TIME类型的结构体指针,RTC_TIME的成员有:
rtc_sec 秒
rtc_min 分钟
rtc_hour 小时
rtc_date 日
rtc_month 月
rtc_day 星期
rtc_year 年
* 输 出 : 无
*******************************************************************************/
void DS1302_SetTime(RTC_TIME *rtc_time)
{
uint8_t temp;
DS1302_Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
temp = hex_to_bcd(rtc_time->rtc_sec);
DS1302_Write(SEC_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_min);
DS1302_Write(MIN_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_hour);
DS1302_Write(HR_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_date);
DS1302_Write(DATE_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_month);
DS1302_Write(MON_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_day);
DS1302_Write(DAY_ADDR, temp);
temp = hex_to_bcd(rtc_time->rtc_year);
DS1302_Write(YEAR_ADDR, temp);
DS1302_Write(0x8E,0x80); //打开写保护功能
}
/*******************************************************************************
* 函 数 名 : DS1302_Init
* 函数功能 : 初始化DS1302,初始化时间时由RTC初始化结构体决定的
* 输 入 : addr
* 输 出 : dat
*******************************************************************************/
void DS1302_Init(void)
{
DS1302_SetTime(&rtc_time);
}
ds1302.h
#ifndef __DS1302_H_
#define __DS1302_H_
#include "config.h"
上一篇:51单片机串口通信Bad Apple视频播放源程序(LCD12864显示)
下一篇:STC89C52+LCD12864+DS1302+DS18B20时钟原理图+源程序
推荐阅读最新更新时间:2024-10-27 22:35