历史上的今天
今天是:2024年11月11日(星期一)
2019年11月11日 | [嵌入式开发模块]DS3231时钟芯片 驱动程序
2019-11-11 来源:eefocus
刚刚写完DS3231时钟芯片的驱动程序。这里开源出来供大家使用。需要的自取。
先简单介绍下这个芯片,然后直接给驱动代码以及示例代码。
DS3231简介
简介
DS3231是一款低成本、高精度I2C实时时钟(RTC),具有集成的温补晶体振荡器(TCXO)和晶体。该器件包含电池输入端,断开主电源时认可保持精确的计时。其提供年、月、日、星期、时、分、秒信息,提供有效期到2100年的闰年补偿。
其带有两个提供不同精度的日历闹钟,可在指定时刻在引脚上产生中断信号。
支持快速(400kHz)I2C接口通讯。
时钟精度在0℃到+40℃为±2ppm,即一个月可能偏离5s多;在-40℃到+85℃为±3.5ppm。
除了时钟外,还提供精度为±3℃的数字温度传感器输出,内部会使用这个温度传感器自动进行补偿以保证时间精度。
典型工作电路

框图

寄存器
DS3231提供如下寄存器:

与DS3231的控制和交互就是通过存取这几个寄存器来实现的,驱动代码中提供了所有寄存器的结构体以及对寄存器的存取函数。
具体寄存器的意义请自己参照数据手册。
与芯片的I2C通讯
I2C通讯的基本原理可以见我的上一个文章https://blog.csdn.net/lin_strong/article/details/80259571,翻译的MC9S12XEP100的数据手册,里头有对I2C通讯的详细描述。



DS3231的主叫地址固定为0b1101000,其内部存在一个寄存器指针,指向下一次读/写的寄存器,每次读/写一次后指针都会自增1,到最后一个寄存器后再指向第一个寄存器。
进行写操作时第一个数据字节会对指针值进行修改。
驱动中提供的函数即封装了这个过程。
代码及测试
驱动代码
DS3231Driver.h
/*
*******************************************************************************************
*
*
* DS3231 DRIVER MODULE
* Freescale MC9S12XEP100
* DS3231驱动模块
*
* File : DS3231Driver.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2018/05/14
* version: V1.0
* History: 2018/05/14 V1.0 the prototype
*********************************************************************************************
*/
#ifndef DS3231_DRIVER_H
#define DS3231_DRIVER_H
/*
********************************************************************************************
* MISCELLANEOUS
********************************************************************************************
*/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
/*
******************************************************************************************
* CONSTANT
******************************************************************************************
*/
// address of register
typedef enum{
RegAddr_Sec, // Seconds 00-59
RegAddr_Min, // Minutes 00-59
RegAddr_Hour, // Hours 1–12 + AM/PM 00–23
RegAddr_Day, // Day 1 - 7
RegAddr_Date, // Data 01-31
RegAddr_CMon, // Century and month Century + 01–12
RegAddr_Year, // Year 00 - 99
RegAddr_Sec_A1, // Alarm 1 Seconds 00-59
RegAddr_Min_A1, // Alarm 1 Minutes 00-59
RegAddr_Hour_A1,// Alarm 1 Hours 1–12 + AM/PM 00–23
RegAddr_Da_A1, // Alarm 1 Day/Date 1 - 7 / 1 – 31
RegAddr_Min_A2, // Alarm 2 Minutes 00-59
RegAddr_Hour_A2,// Alarm 2 Hours 1–12 + AM/PM 00–23
RegAddr_Da_A2, // Alarm 2 Day/Date 1 - 7 / 1 – 31
RegAddr_Control,// Control
RegAddr_CtlStat,// Control/Status
RegAddr_AgOfset,// Aging offset
RegAddr_TempMSB,// MSB of Temp
RegAddr_TempLSB,// LSB of Temp
}DS3231REG_ADDR;
#define DS3231REG_ADDR_MAX RegAddr_TempLSB
/*
*******************************************************************************************
* CONFIGURE 主配置
*******************************************************************************************
*/
#define DS3231_CALLADDR 0b1101000 // DS32331的主叫地址
/*
****************************************************************************************
* ERROR CODES
****************************************************************************************
*/
#define DS3231_ERR_NULL 0 // if success
#define DS3231_ERR_COMM 1 // any error in communication
#define DS3231_ERR_REG 2 // wrong register
#define DS3231_ERR_ARG 3 // if wrong argument
/*
******************************************************************************************
* TYPE DEFINE
******************************************************************************************
*/
// struct of DS3231 register
typedef struct {
unsigned int sec_sd: 4; // ones digit of second 秒的个位
unsigned int sec_td: 3; // tens digit of second 秒的十位
unsigned int : 1;
} REG_SEC;
typedef struct {
unsigned int min_sd: 4; // ones digit of minute 分的个位
unsigned int min_td: 3; // tens digit of minute 分的十位
unsigned int : 1;
} REG_MIN;
typedef union {
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:1; // tens digit of hour 分的个位
unsigned int isPM :1; // whether is pm
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int :1;
}SYS12;
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:2; // tens digit of hour 分的个位
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int :1;
}SYS24;
} REG_HOUR;
typedef struct {
unsigned int day : 3; // the day of the week
unsigned int : 5;
} REG_DAY;
typedef struct {
unsigned int date_sd: 4; // ones digit of second 秒的个位
unsigned int date_td: 2; // tens digit of second 秒的十位
unsigned int : 2;
} REG_DATE;
typedef struct {
unsigned int mon_sd: 4; // ones digit of month 月的个位
unsigned int mon_td: 1; // tens digit of month 月的个位
unsigned int : 2;
unsigned int century:1; // hundreds digit of year
} REG_CMON;
typedef struct {
unsigned int year_sd: 4; // ones digit of year 月的个位
unsigned int year_td: 4; // tens digit of year 月的个位
} REG_YEAR;
typedef struct {
unsigned int sec_sd: 4; // ones digit of second 秒的个位
unsigned int sec_td: 3; // tens digit of second 秒的十位
unsigned int A1M1 : 1;
} REG_SEC_A1;
typedef struct {
unsigned int min_sd: 4; // ones digit of minute 分的个位
unsigned int min_td: 3; // tens digit of minute 分的十位
unsigned int A1M2 : 1;
} REG_MIN_A1;
typedef union {
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:1; // tens digit of hour 分的个位
unsigned int isPM :1; // whether is pm
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int A1M3 :1;
}SYS12;
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:2; // tens digit of hour 分的个位
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int A1M3 :1;
}SYS24;
} REG_HOUR_A1;
typedef union {
struct{
unsigned int day : 4; // the day of the week
unsigned int : 2;
unsigned int isDY : 1; // day selected
unsigned int A1M4 : 1;
}DAY;
struct{
unsigned int date_sd: 4; // ones digit of date
unsigned int date_td: 2; // tens digit of date
unsigned int isDY : 1; // day selected
unsigned int A1M4 : 1;
}DATE;
} REG_DA_A1;
typedef struct {
unsigned int min_sd: 4; // ones digit of minute 分的个位
unsigned int min_td: 3; // tens digit of minute 分的十位
unsigned int A2M2 : 1;
} REG_MIN_A2;
typedef union {
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:1; // tens digit of hour 分的个位
unsigned int isPM :1; // whether is pm
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int A2M3 :1;
}SYS12;
struct{
unsigned int hour_sd:4; // ones digit of hour 分的个位
unsigned int hour_td:2; // tens digit of hour 分的个位
unsigned int is12sys:1; // whether is 12 hours system.
unsigned int A2M3 :1;
}SYS24;
} REG_HOUR_A2;
typedef union {
struct{
unsigned int day : 4; // the day of the week
unsigned int : 2;
unsigned int isDY : 1; // day selected
unsigned int A2M4 : 1;
}DAY;
struct{
unsigned int date_sd: 4; // ones digit of date
unsigned int date_td: 2; // tens digit of date
unsigned int isDY : 1; // day selected
unsigned int A2M4 : 1;
}DATE;
} REG_DA_A2;
typedef struct{
unsigned int A1IE : 1;
unsigned int A2IE : 1;
unsigned int INTCN : 1;
unsigned int RS1 : 1;
unsigned int RS2 : 1;
unsigned int CONV : 1;
上一篇:STM8 I/O口模拟I2C
下一篇:STM8S103之IO复用
史海拾趣
|
用tcpDebugShow()查看的结果中第一列的数字是什么含义? 如下,第一列的数字表示什么? -> tcpDebugShow 1665138688 user CLOSED 1665138688 user CLOSED 643760896 user CLOSED 643760896 input LISTEN ...… 查看全部问答> |
|
使用GetAdaptersAddresses获取DNS遇到的问题 在文件中使用了GetAdaptersAddresses函数,遇到了以下问题: BUILD: [01:0000000089:ERRORE] error C2065: \'PIP_ADAPTER_ADDRESSES\' : undeclared identifier 其中我已经添加了该函数需要的头文件Iptypes.h,其路径在resouces中是正确的. 但是我 ...… 查看全部问答> |
|
STM8单片机,PD0口产生中断与PD2口产生中断都转向同一个中断服务函数吗? 若PD0口产生中断与PD2口产生中断都转向同一个中断服务函数,那么如何让单片机区别该中断是PD0口还是PD2口产生的?… 查看全部问答> |
|
wolverine大家已经很熟悉了,今天看到这个是MSP430FR5738.它到底有什么特别之处呢?先看看指标,基本是430的标准配置。 重点就在封装上:有一个24WCSP的封装,简单的讲就是一个BGA的封装。ball的间距是0.4m.翻看了手册,这个芯片面积是2mmx2.2mm ...… 查看全部问答> |
|
关于“压采”,能做的项目征集,大家帮忙想想,都能做点儿啥啊,服务三农,造福后代,吼吼,说的有点空了。 。。 最近冀州政府大力支持此类项目,也想搞搞什么滴,大家帮帮忙哇… 查看全部问答> |




