目录
芯片管脚设置:
管脚说明:
原理框图:
芯片资料获取:
部分驱动代码:
主函数:
部分驱动函数——中断调用函数:
部分驱动函数——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; //倒计时中断源选择1scdInit.init_val = 2; //倒计时初值设置为2Set_CountDown(&cdInit);
#elif (INT_TYPE == DISABLE)
/****************** 禁止中断演示 *****************/ClrINT(INTDE|INTAE|INTFE);
#endifwhile( 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; //10Hbuf[1] = CountDown_Init->d_clk<<4; //11Hbuf[2] = 0; //12Hbuf[3] = CountDown_Init->init_val & 0x0000FF; //13Hbuf[4] = (CountDown_Init->init_val & 0x00FF00) >> 8;//14Hbuf[5] = (CountDown_Init->init_val & 0xFF0000) >> 16;//15HI2CWriteSerial(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_24XXenum 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
后期会对这款芯片做一个实际的测试,驱动代码以及使用注意都会详细写出来。