SD3077、SD3078时钟芯片数据手册、例程

目录

芯片管脚设置:

管脚说明:

原理框图:

芯片资料获取:

部分驱动代码:

主函数:

部分驱动函数——中断调用函数:

部分驱动函数——I2C在指定地址读/写一字节数据函数:

部分驱动函数——IRTC实时数据寄存器函数:

我最近在项目上需要使用一款可以3.3V供电的时钟芯片,在网上找了一下发现了这款芯片SD3077(由于在淘宝上买的,店主应该是个倒手的,不提供资料和技术支持)没办法只能自己找资料了。不找不知道,一找差点要了我的老命(CSDN上面就一个技术手册就要四十多个币,文库那些就更别说了,好多网站还只要微信转账9.9就能下载)现在的资料都这么“值钱”了吗?本着白嫖的原则,找了一晚上,终于找到厂家了,在他那里下载了数据手册和例程。我解决问题之后,觉得还是把这些坑都写清楚,方便后面的初学者。

芯片管脚设置:

管脚说明:

原理框图:

芯片资料获取:

浏览器搜索:http://www.whwave.com.cn/在主页面打开产品中心——>实时时钟芯片——>选择你的时钟芯片型号(单击打开),芯片介绍下面就有官方例程和数据手册。

下面是DS3077、DS3078芯片介绍界面可下载资料截图:

部分驱动代码:

主函数:

主函数是一个多功能调试的集合,有给RTC写入计时的初始时间、读出芯片的ID号演示、充电使能设置演示、频率中断设置演示、报警中断设置演示、倒计时中断设置演示、禁止中断演示等。

int main(void)

{

u8 i;

CountDown_Def cdInit;

/********* USART1 配置模式为 115200 8-N-1**********/

USARTx_Config();

printf("\r\n--这是一个读写RTC的演示程序-- \r\n");

/***************** I2C总线初始化 *****************/

IIC_Init();

/************* 给RTC写入计时的初始时间 ************/

RTC_WriteDate(&time_init);

RTC_ReadDate(&sysTime);

printf("写入的初始时间为: \r\n");

printf("%02X-%02X-%02X %02X:%02X:%02X 星期%02X\r\n\r\n", \

sysTime.year, sysTime.month, sysTime.day, sysTime.hour,\

sysTime.minute, sysTime.second, sysTime.week);

printf("----------------------------\r\n\r\n");

#ifdef SD30XX_25XX

/*************** 读出芯片的ID号演示 ****************/

I2CReadSerial(RTC_Address,ID_Address,8,data_Buf);

printf("芯片64bit ID号为:\r\n");

for (i=0; i<8; i++)

printf("0x%02X ", data_Buf[i]);

printf("\r\n----------------------------\r\n\r\n");

/**************** 充电使能设置演示 *****************/

data_Buf[0] = Chg_enable;

I2CWriteSerial(RTC_Address,Chg_MG,1,data_Buf);

/************** 读出后备电池电压演示 ***************/

I2CReadSerial(RTC_Address,Bat_H8,2,VBAT_Buf);

VBAT_VAL = (VBAT_Buf[0]>>7)*255 + VBAT_Buf[1];

printf("VBAT脚的电池电压为:%d.%d%dV\r\n\r\n", VBAT_VAL/100, VBAT_VAL%100/10, VBAT_VAL%10);

#endif

#if (INT_TYPE == FREQUENCY)

/**************** 频率中断设置演示 ****************/

SetFrq(F2Hz);//输出2Hz频率方波

#elif (INT_TYPE == ALARM)

/**************** 报警中断设置演示 ****************/

Set_Alarm(sec_ALM|min_ALM|hor_ALM, &Alarm_init);//报警使能:时、分、秒

#elif (INT_TYPE == COUNTDOWN)

/*************** 倒计时中断设置演示 ***************/

cdInit.IM = 1; //设置为周期性中断

cdInit.d_clk = S_1s; //倒计时中断源选择1s

cdInit.init_val = 2; //倒计时初值设置为2

Set_CountDown(&cdInit);

#elif (INT_TYPE == DISABLE)

/****************** 禁止中断演示 *****************/

ClrINT(INTDE|INTAE|INTFE);

#endif

while( 1 )

{

RTC_ReadDate(&sysTime);

printf("%02X-%02X-%02X %02X:%02X:%02X 星期%02X\r\n", \

sysTime.year, sysTime.month, sysTime.day, sysTime.hour,\

sysTime.minute, sysTime.second, sysTime.week);

Delay(0x7FFFFF);//1秒延时

}

}

STM32例程部分驱动函数——中断调用函数:

/*********************************************

* 函数名:Set_CountDown

* 描 述:设置倒计时中断

* 输 入:CountDown_Init 倒计时中断结构体指针

* 输 出:无

********************************************/

void Set_CountDown(CountDown_Def *CountDown_Init)

{

u8 buf[6];

u8 tem=0xF0;

buf[0] = (CountDown_Init->IM<<6)|0xB4; //10H

buf[1] = CountDown_Init->d_clk<<4; //11H

buf[2] = 0; //12H

buf[3] = CountDown_Init->init_val & 0x0000FF; //13H

buf[4] = (CountDown_Init->init_val & 0x00FF00) >> 8;//14H

buf[5] = (CountDown_Init->init_val & 0xFF0000) >> 16;//15H

I2CWriteSerial(RTC_Address,CTR2,1,&tem);

I2CWriteSerial(RTC_Address,CTR2,6,buf);

}

/*********************************************

* 函数名:Set_Alarm

* 描 述:设置报警中断(闹钟功能)

* Enable_config:使能设置

* psRTC:报警时间的时间结构体指针

* 输 出:无

********************************************/

void Set_Alarm(u8 Enable_config, Time_Def *psRTC)

{

u8 buf[10];

buf[0] = psRTC->second;

buf[1] = psRTC->minute;

buf[2] = psRTC->hour;

buf[3] = 0;

buf[4] = psRTC->day;

buf[5] = psRTC->month;

buf[6] = psRTC->year;

buf[7] = Enable_config;

buf[8] = 0xFF;

buf[9] = 0x92;

I2CWriteSerial(RTC_Address,Alarm_SC,10,buf);

}

STM32例程中RTC.H文件(SD3077相关寄存器定义、时钟数据管脚定义及声明等)

#ifndef __RTC_H__

#define __RTC_H__

#include "stm32f10x.h"

#define SCL_H GPIOB->BSRR = GPIO_Pin_6

#define SCL_L GPIOB->BRR = GPIO_Pin_6

#define SDA_H GPIOB->BSRR = GPIO_Pin_7

#define SDA_L GPIOB->BRR = GPIO_Pin_7

#define SDA_read (GPIOB->IDR & GPIO_Pin_7)

enum Freq{F_0Hz, F32KHz, F4096Hz, F1024Hz, F64Hz, F32Hz, F16Hz, F8Hz, \

F4Hz, F2Hz, F1Hz, F1_2Hz, F1_4Hz, F1_8Hz, F1_16Hz, F_1s};

enum clk_Souce{S_4096Hz, S_1024Hz, S_1s, S_1min};

/*此结构体定义了时间信息包括年、月、日、星期、时、分、秒*/

typedef struct

{

u8 second;

u8 minute;

u8 hour;

u8 week;

u8 day;

u8 month;

u8 year;

} Time_Def;

/*此结构体定义了倒计时中断可供配置的频率源、IM和初值主要参数*/

typedef struct

{

enum clk_Souce d_clk;

u8 IM; //IM=1:周期性中断

u32 init_val;

} CountDown_Def;

/*

* 通过宏定义选择使用的RTC型号

* SD30XX_25XX -> 使用SD30或SD25系列

* SD20XX_24XX -> 使用SD20或SD24系列

*/

#define SD30XX_25XX

#undef SD20XX_24XX

/********************************************************/

#define TRUE 1

#define FALSE 0

#define H 1

#define L 0

#define Chg_enable 0x82

#define Chg_disable 0

/******************** Device Address ********************/

#define RTC_Address 0x64

/******************** Alarm register ********************/

#define Alarm_SC 0x07

#define Alarm_MN 0x08

#define Alarm_HR 0x09

#define Alarm_WK 0x0A

#define Alarm_DY 0x0B

#define Alarm_MO 0x0C

#define Alarm_YR 0x0D

#define Alarm_EN 0x0E

/******************** Control Register *******************/

#define CTR1 0x0F

#define CTR2 0x10

#define CTR3 0x11

/***************** Timer Counter Register ****************/

#define Timer_Counter1 0x13

#define Timer_Counter2 0x14

#define Timer_Counter3 0x15

/******************** Battery Register ********************/

#define Chg_MG 0x18 //充电管理寄存器地址

#define Bat_H8 0x1A //电量最高位寄存器地址

#define Bat_L8 0x1B //电量低八位寄存器地址

/*********************** ID Register **********************/

#define ID_Address 0x72 //ID号起始地址

/********************** 报警中断宏定义 *********************/

#define sec_ALM 0x01

#define min_ALM 0x02

#define hor_ALM 0x04

#define wek_ALM 0x08

#define day_ALM 0x10

#define mon_ALM 0x20

#define yar_ALM 0x40

/********************** 中断使能宏定义 **********************/

#define INTDE 0x04 //倒计时中断

#define INTAE 0x02 //报警中断

#define INTFE 0x01 //频率中断

/********************** 中断演示宏定义 **********************/

#define FREQUENCY 0 //频率中断

#define ALARM 1 //报警中断

#define COUNTDOWN 2 //倒计时中断

#define DISABLE 3 //禁止中断

/*************** 中断输出类型选择,请自行选择 ****************/

#define INT_TYPE COUNTDOWN //定义中断输出类型

/***********读写时间函数*************/

u8 RTC_WriteDate(Time_Def *psRTC);

u8 RTC_ReadDate(Time_Def *psRTC);

/*******I2C多字节连续读写函数********/

u8 I2CWriteSerial(u8 DeviceAddress,u8 Address,u8 length,u8 *ps);

u8 I2CReadSerial(u8 DeviceAddress,u8 Address,u8 length,u8 *ps);

/*********I2C端口初始化函数*********/

void IIC_Init(void);

/*********RTC中断配置函数*********/

void Set_CountDown(CountDown_Def *CountDown_Init);

void Set_Alarm(u8 Enable_config, Time_Def *psRTC);

void SetFrq(enum Freq F_Out);

void ClrINT(u8 int_EN);

#endif /* __RTC_H */

STM8例程中RTC.H文件(SD3077相关寄存器定义、时钟数据管脚定义及声明等)

#ifndef __RTC_H__

#define __RTC_H__

#include "type.h"

#define SCL(tmp)tmp?(PB_ODR |= 0x10):(PB_ODR&=0xef)

#define SDA(tmp)tmp?(PB_ODR |= 0x20):(PB_ODR&=0xdf)

#define SDAin() {PB_DDR&=0xdf;PB_CR1&=0xdf;} /*浮空输入(外部加上拉电阻)*/

#define SDAout(){PB_DDR|=0x20;PB_CR1&=0xdf;} /*开漏输出(外部加上拉电阻),使用推挽可能会有问题*/

/*

* 通过宏定义选择使用的RTC型号

* SD30XX_25XX -> 使用SD30或SD25系列

* SD20XX_24XX -> 使用SD20或SD24系列

*/

#define SD30XX_25XX

#undef SD20XX_24XX

enum Freq{F_0Hz, F32KHz, F4096Hz, F1024Hz, F64Hz, F32Hz, F16Hz, F8Hz, \

F4Hz, F2Hz, F1Hz, F1_2Hz, F1_4Hz, F1_8Hz, F1_16Hz, F_1s};

enum clk_Souce{S_4096Hz, S_1024Hz, S_1s, S_1min};

typedef struct

{

u8 second;

u8 minute;

u8 hour;

u8 week;

u8 day;

u8 month;

u8 year;

}Time_Def;

/*此结构体定义了倒计时中断可供配置的频率源、IM和初值主要参数*/

typedef struct

{

enum clk_Souce d_clk;

u8 IM; //IM=1:周期性中断

u32 init_val;

} CountDown_Def;

#define TRUE 1

#define FALSE 0

#define H 1

#define L 0

#define Chg_enable 0x82

#define Chg_disable 0

/******************** Device Address ********************/

#define RTC_Address 0x64

/******************** Alarm register ********************/

#define Alarm_SC 0x07

#define Alarm_MN 0x08

#define Alarm_HR 0x09

#define Alarm_WK 0x0A

#define Alarm_DY 0x0B

#define Alarm_MO 0x0C

#define Alarm_YR 0x0D

#define Alarm_EN 0x0E

/******************** Control register ********************/

#define CTR1 0x0F

#define CTR2 0x10

#define CTR3 0x11

/***************** Timer Counter Register ***********************/

#define Timer_Counter1 0x13

#define Timer_Counter2 0x14

#define Timer_Counter3 0x15

/******************** Battery register ********************/

#define Chg_MG 0x18 //充电管理寄存器地址

#define Bat_H8 0x1A //电量最高位寄存器地址

#define Bat_L8 0x1B //电量低八位寄存器地址

/**********************************************************/

#define ID_Address 0x72 //ID号起始地址

/********************** 报警中断宏定义 *********************/

#define sec_ALM 0x01

#define min_ALM 0x02

#define hor_ALM 0x04

#define wek_ALM 0x08

#define day_ALM 0x10

#define mon_ALM 0x20

#define yar_ALM 0x40

/********************** 中断使能宏定义 **********************/

#define INTDE 0x04 //倒计时中断

#define INTAE 0x02 //报警中断

#define INTFE 0x01 //频率中断

/********************** 中断演示宏定义 **********************/

#define FREQUENCY 0 //频率中断

#define ALARM 1 //报警中断

#define COUNTDOWN 2 //倒计时中断

#define DISABLE 3 //禁止中断

/*************** 中断输出类型选择,请自行选择 ****************/

#define INT_TYPE COUNTDOWN //定义中断输出类型

/********** I2C端口初始化函数 *********/

void IIC_Init(void);

/********** RTC读写时间函数 *********/

void I2CWriteDate(Time_Def *SetRTC);

void I2CReadDate(Time_Def *psRTC);

/****** I2C连续读写多字节函数 *******/

u8 I2CWriteSerial(u8 DeviceAddress, u8 Address, u8 length,u8 *ps);//I2C连续写多个字节

u8 I2CReadSerial(u8 DeviceAddress, u8 Address, u8 length,u8 *ps);//I2C连续读多个字节

/*********RTC中断配置函数*********/

void Set_CountDown(CountDown_Def *CountDown_Init);

void Set_Alarm(u8 Enable_config, Time_Def *psRTC);

void SetFrq(enum Freq F_Out);

void ClrINT(u8 int_EN);

#endif

后期会对这款芯片做一个实际的测试,驱动代码以及使用注意都会详细写出来。