[嵌入式開發模塊]DS3231時鐘芯片 驅動程序

版權聲明:本文爲博主(http://blog.csdn.net/lin_strong)原創文章,轉載請標明出處並事先取得博主同意 https://blog.csdn.net/lin_strong/article/details/80311683

剛剛寫完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,到最後一個寄存器後再指向第一個寄存器。
進行寫操作時第一個數據字節會對指針值進行修改。

驅動中提供的函數即封裝了這個過程。

代碼及測試

驅動代碼

頭文件:

/*
*******************************************************************************************
*
*
*                                   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;
  unsigned int BBSQW : 1;
  unsigned int EOSC  : 1;
} REG_CONTROL;

typedef struct{
  unsigned int A1IF   : 1;
  unsigned int A2IF   : 1;
  unsigned int BSY    : 1;
  unsigned int EN32kHz: 1;
  unsigned int        : 3;
  unsigned int OSF    : 1;
} REG_CTLSTAT;

typedef struct{
  unsigned int DATA : 7;
  unsigned int SIGN : 1;
} REG_AGOFSET;

typedef struct{
  char DATA;
} REG_TEMPMSB;

typedef struct{
  unsigned int      : 6;
  unsigned int DATA : 2;
} REG_TEMPLSB;

// type of module
typedef struct {
  REG_SEC  sec;
  REG_MIN  min;
  REG_HOUR hour;
  REG_DAY  day;
  REG_DATE date;
  REG_CMON cmon;
  REG_YEAR year;
} TIME_STRUCT,*pTIME_STRUCT;

typedef struct{
  REG_TEMPMSB integral;      // integral part
  REG_TEMPLSB fractional;    // fractional part
} TEMP_STRUCT,*pTEMP_STRUCT;

typedef struct{
  unsigned int errcode : 4; // see DS3231_ERR_XXX
  unsigned int commerr : 4; // hold the errcode by user defined iic functions.
} DS3231_ERRCODE;

/*
************************************************************************************
*                          FUNCTION PROTOTYPES  函數原型
************************************************************************************
*/

unsigned char DS3231_Init(void);
DS3231_ERRCODE DS3231_GetReg(DS3231REG_ADDR reg,unsigned char *rst);
DS3231_ERRCODE DS3231_SetReg(DS3231REG_ADDR reg,unsigned char value);
DS3231_ERRCODE DS3231_GetRegs(DS3231REG_ADDR reg,unsigned char *pBuf,unsigned short len);
DS3231_ERRCODE DS3231_SetRegs(DS3231REG_ADDR reg,unsigned char *pBuf,unsigned short len);

DS3231_ERRCODE DS3231_SetTime(pTIME_STRUCT val);
DS3231_ERRCODE DS3231_GetTime(pTIME_STRUCT rst);
DS3231_ERRCODE DS3231_GetTemp(pTEMP_STRUCT rst);

// 用戶需要實現這幾個函數以使模塊能與DS3231進行IIC通訊
// Arguments: calAddr      7bits calling address
//            pBuf         pointer to the send/recv buffer
//            len          length of datas to be send/recv
//            rst          pointer to the return value
//            val          the byte to send
// return   : 0            if success
//            1 - 15       errcode of IIC communication. 
//                         meaning of errcode of these functions should be exactly same. 
extern unsigned char IIC_ReadBurst(unsigned char calAddr,unsigned char *pBuf,unsigned short len);
extern unsigned char IIC_SendBurst(unsigned char calAddr,unsigned char *pBuf,unsigned short len);
extern unsigned char IIC_ReadByte(unsigned char calAddr,unsigned char *rst);
extern unsigned char IIC_SendByte(unsigned char calAddr,unsigned char val);

/*
************************************************************************************
*                          ERROR CHECK 錯誤檢查
************************************************************************************
*/


#endif  // of DS3231_DRIVER_H

源文件:

/*
*******************************************************************************************
*
*
*                                   DS3231 DRIVER MODULE
*                                  Freescale MC9S12XEP100
*                                      DS3231驅動模塊
*
* File : DS3231Driver.c
* By   : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date:  2018/05/14
* version: V1.0
* History: 2018/05/14  V1.0   the prototype
*********************************************************************************************
*/

/*
*********************************************************************************************
*                                       INCLUDES
*********************************************************************************************
*/
#include <string.h>
#include "DS3231Driver.h"

/*
*********************************************************************************************
*                                       LOCAL FUNCTION
*********************************************************************************************
*/

#define regCheck()     if(reg > DS3231REG_ADDR_MAX){err.errcode = DS3231_ERR_REG;  return err;}
#define lenCheck()     if(len > (DS3231REG_ADDR_MAX + 1) || len == 0){err.errcode = DS3231_ERR_ARG;  return err;}
/*
*********************************************************************************************
*                                       LOCAL VARIABLE
*********************************************************************************************
*/
// 發送緩存
static unsigned char Sendbuf[DS3231REG_ADDR_MAX + 2];

/*
*********************************************************************************************
*                                        DS3231_Init()
*
* Description : Initialize DS3231 support hardware(marco style).  初始化DS3231硬件
*
* Arguments   : 
*
* Return      : DS3231_ERR_NULL       if success.
*
* Note(s)     : 
*********************************************************************************************
*/

unsigned char DS3231_Init(void){
  return DS3231_ERR_NULL;
}

/*
*********************************************************************************************************
*                                        DS3231_getReg()
*
* Description : get a register value of DS3231.
*
* Arguments   : reg       the register to get value.
*               rst       return value of result.
*
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*                 DS3231_ERR_REG     if unknown register.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
*
* Note: 
*********************************************************************************************************
*/

DS3231_ERRCODE DS3231_GetReg(DS3231REG_ADDR reg,unsigned char *rst){
  DS3231_ERRCODE err = {0};
  unsigned char commerr;
  regCheck();
  if((commerr = IIC_SendByte(DS3231_CALLADDR,(unsigned char)reg)) == 0 &&  // 寫入寄存器指針
     (commerr = IIC_ReadByte(DS3231_CALLADDR,rst)) == 0){                  // 然後讀取一個字節
    err.errcode = DS3231_ERR_NULL;
  }else{
    err.errcode = DS3231_ERR_COMM;
  }
  err.commerr = commerr;
  return err;
}
/*
*********************************************************************************************************
*                                        DS3231_SetReg()
*
* Description : set a register of DS3231.
*
* Arguments   : reg       the register to get value.
*               rst       return value of result.
*
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*                 DS3231_ERR_REG     if unknown register.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
* Note: 
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_SetReg(DS3231REG_ADDR reg,unsigned char value){
  DS3231_ERRCODE err = {0};
  unsigned char commerr;
  regCheck();
  Sendbuf[0] = (unsigned char)reg;
  Sendbuf[1] = value;
  if((commerr = IIC_SendBurst(DS3231_CALLADDR,Sendbuf,2)) == 0)
    err.errcode =  DS3231_ERR_NULL;
  else
    err.errcode =  DS3231_ERR_COMM;
  err.commerr = commerr;
  return err;
}
/*
*********************************************************************************************************
*                                        DS3231_GetRegs()
*
* Description : get sereval registers' value of DS3231.
*
* Arguments   : reg      the first register to get value.
*               pBuf      return value of register.
*               len       how many registers to get value (1 - (DS3231REG_ADDR_MAX + 1))
*
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*                 DS3231_ERR_REG     if unknown register.
*                 DS3231_ERR_ARG     if len out of range.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
* Note: 
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_GetRegs(DS3231REG_ADDR reg,unsigned char *pBuf,unsigned short len){
  DS3231_ERRCODE err = {0};
  unsigned char commerr;
  regCheck();
  lenCheck();
  if((commerr = IIC_SendByte(DS3231_CALLADDR,(unsigned char)reg)) == 0 &&  // 寫入寄存器指針
     (commerr = IIC_ReadBurst(DS3231_CALLADDR,pBuf,len)) == 0){            // 然後讀取一個字節
    err.errcode = DS3231_ERR_NULL;
  }else{
    err.errcode = DS3231_ERR_COMM;
  }
  err.commerr = commerr;
  return err;
}
/*
*********************************************************************************************************
*                                        DS3231_SetRegs()
* 
* Description : set sereval registers' value of DS3231.
* 
* Arguments   : reg       the first register to set value.
*               pBuf      point to the value of registers to set.
*               len       how many registers to set value (1 - (DS3231REG_ADDR_MAX + 1))
* 
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*                 DS3231_ERR_REG     if unknown register 
*                 DS3231_ERR_ARG     if len out of range.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
*
* Note: 
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_SetRegs(DS3231REG_ADDR reg,unsigned char *pBuf,unsigned short len){
  DS3231_ERRCODE err = {0};
  unsigned char commerr;
  regCheck();
  lenCheck();
  Sendbuf[0] = (unsigned char)reg;
  memcpy(Sendbuf+1,pBuf,len);
  if((commerr = IIC_SendBurst(DS3231_CALLADDR,Sendbuf,len + 1)) == 0){  // 寫入寄存器指針
    err.errcode = DS3231_ERR_NULL;
  }else{
    err.errcode = DS3231_ERR_COMM;
  }
  err.commerr = commerr;
  return err;
}
/*
*********************************************************************************************************
*                                        DS3231_SetTime()
* 
* Description : set time of DS3231.
* 
* Arguments   : val       the time to set
* 
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
* Note: 
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_SetTime(pTIME_STRUCT val){
  return DS3231_SetRegs(RegAddr_Sec,(unsigned char *)val,sizeof(TIME_STRUCT));
}
/*
*********************************************************************************************************
*                                        DS3231_GetTime()
* 
* Description : get time of DS3231.
* 
* Arguments   : rst       the time result.
* 
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
* Note: 
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_GetTime(pTIME_STRUCT rst){
  return DS3231_GetRegs(RegAddr_Sec,(unsigned char *)rst,sizeof(TIME_STRUCT));
}
/*
*********************************************************************************************************
*                                        DS3231_GetTemp()
* 
* Description : get temperature measured by DS3231.
* 
* Arguments   : rst       return the temperature measured.
*                         = (rst->integral.DATA).(rst->fractional.DATA * 0.25)
*                         for example:
*                           if rst->integral.DATA = -4, rst->fractional.DATA = 3
*                           then  temperature = -4.75 C
*                           if rst->integral.DATA = 25, rst->fractional.DATA = 1
*                           then  temperature = +25.25 C
*
* Return      : .errcode:
*                 DS3231_ERR_NULL    if success.
*                 DS3231_ERR_COMM    if error.
*               .commerr:
*                 errcode returned by user defined IIC functions if DS3231_ERR_COMM.
* Note        : 1. DS3231 will measure temperature every 64 seconds once powered
*                  by Vcc or once communicated when powerd by battery.
*               2. you can also start the convertion by set CONV in Control 
*                  register.
*********************************************************************************************************
*/
DS3231_ERRCODE DS3231_GetTemp(pTEMP_STRUCT rst){
  return DS3231_GetRegs(RegAddr_TempMSB,(unsigned char *)rst,sizeof(TEMP_STRUCT));
}

DS3231_G/SetReg(s)對DS3231寄存器讀寫操作進行封裝。
模塊要求用戶按照要求提供錯誤碼風格的IIC通訊函數,並在發生通訊錯誤時把用戶函數的錯誤碼一同返回。

由於時間和溫度的使用較頻繁,提供了專門的讀寫函數。

下面給出代碼示例:

示例代碼

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "DS3231Driver.h"
#include "IIC.h"
#include <stdio.h>

typedef void (*near tIsrFunc)(void);
const tIsrFunc _vect @0xFFC0 = IIC_ISR;

#define BUS_CLOCK 32000000
void Delay(void) {
  unsigned int i,j;
  for(i = 0; i < 100; i++)
    for(j = 0; j < 50000; j++)
      ;
}
void INIT_PLL(void) 
{
    CLKSEL &= 0x7f;       //set OSCCLK as sysclk
    PLLCTL &= 0x8F;       //DisaKble PLL circuit
    CRGINT &= 0xDF;

    #if(BUS_CLOCK == 40000000) 
      SYNR = 0x44;
    #elif(BUS_CLOCK == 32000000)
      SYNR = 0x43;     
    #elif(BUS_CLOCK == 24000000)
      SYNR = 0x42;
    #endif 

    REFDV = 0x81;         //PLLCLK=2×OSCCLK×(SYNR+1)/(REFDV+1)=64MHz ,fbus=32M
    PLLCTL =PLLCTL|0x70;  //Enable PLL circuit
    asm NOP;
    asm NOP;
    while(!(CRGFLG&0x08)); //PLLCLK is Locked already
    CLKSEL |= 0x80;        //set PLLCLK as sysclk
}
char strbuf[100];
volatile TIME_STRUCT time;
volatile TEMP_STRUCT temp;
unsigned char* flag = (unsigned char*)0x3F80;
void main(void) {
// 18年5月11日星期五23點59分50秒
  time.year.year_td = 1; time.year.year_sd = 8;
  time.cmon.mon_td = 0;  time.cmon.mon_sd = 5;
  time.date.date_td = 1; time.date.date_sd = 1;
  time.day.day = 5;      time.hour.SYS24.is12sys = 0;
  time.hour.SYS24.hour_td = 2; time.hour.SYS24.hour_sd = 3;
  time.min.min_td = 5;   time.min.min_sd = 9;
  time.sec.sec_td = 5;   time.sec.sec_sd = 0;
  INIT_PLL();
  IIC_Init();
  DS3231_Init();
  EnableInterrupts;
  // 每次首次上電時設置當前時間
  if(*flag != 0xac){
    if(DS3231_SetTime(&time).errcode != DS3231_ERR_NULL)
      while(1);
    *flag = 0xac;        // RAM中的數據在保持上電狀態時即使系統重置也不會重置,但在上電重置時會重置
  }
  for(;;) {
    // 讀取當前時間和溫度,出任意錯則無限循環停止運行
    if(DS3231_GetTime(&time).errcode != DS3231_ERR_NULL)
      while(1);
    if(DS3231_GetTemp(&temp).errcode != DS3231_ERR_NULL)
      while(1);
    sprintf(strbuf,"year:%d%d month:%d%d date:%d%d day:%d,%d%d:%d%d:%d%d\r\nTemp:%d.%02d\r\n",
      time.year.year_td,time.year.year_sd,time.cmon.mon_td,time.cmon.mon_sd,
      time.date.date_td,time.date.date_sd,time.day.day,
      time.hour.SYS24.hour_td,time.hour.SYS24.hour_sd,
      time.min.min_td,time.min.min_sd,time.sec.sec_td,time.sec.sec_sd,
      temp.integral.DATA,temp.fractional.DATA * 25);
    Delay();
  }
}

// 實現驅動要求的函數
unsigned char IIC_ReadBurst(unsigned char calAddr,unsigned char *pBuf,unsigned short len){
  return IIC_Recv(calAddr,pBuf,len);
}
unsigned char IIC_SendBurst(unsigned char calAddr,unsigned char *pBuf,unsigned short len){
  return IIC_Send(calAddr,pBuf,len);
}
unsigned char IIC_ReadByte(unsigned char calAddr,unsigned char *rst){
  return IIC_RecvChar(calAddr,rst);
}
unsigned char IIC_SendByte(unsigned char calAddr,unsigned char val){
  return IIC_SendChar(calAddr,&val);
}

測試結果

後記

這次對DS3231進行了簡單的封裝,難免會有不足或者錯誤之處,敬請指出。

測試中使用的IIC函數是自己封裝的MC9S12XEP100的IIC模塊,正在完善中,應該馬上就會放出。

要求用戶提供IIC函數是爲了實現與硬件解耦,這樣不管實際平臺是怎麼樣的,用戶只要按照要求實現IIC通訊函數就可以使用這個驅動了。

簡介中完全參考Maxim的數據手冊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章