• RTC-IC-PCF2129


    一特点:

    -20~70度,SPI/I2C接口,1.2 V to 4.2 V ,可编程看门狗,时钟输出以便校准,闹钟输出,时间戳输出。低功耗高精度,电源切换,中断输出。

    SPI接口和I2C接口硬件接法:IFS和BSS连接则是I2C接法。

    时间戳输出:/TS低电平输入引脚当信号到来时将时间信息存到时间戳寄存器,此时通过接口可读出的时间即为此事件发生时的时间。

    闹钟输出:当前时间不断与设置的闹钟时间比较,匹配时产生标志,使能中断时通过/INT输出。

    电源切换:在VDD和Vbat上加系统电压和电池电压,内部可实现自动切换;也可将VCC和电池分别通过二极管连接到VDD上,此时Vbat一定要接地,并且软件电源管理的3位设置为111

    电池低电压输出:当低电压检测使能时,当电池电压低到一定值时则事件输出

    /*------------------------filename.h------------------------------------*/

    #ifndef __PCF2129_I2C_H
    #define __PCF2129_I2C_H
    /* head include ------------------------------------------------------------*/
    # include "stm32f10x.h"
    /* Exported types ------------------------------------------------------------*/

    typedef struct
    {
        unsigned char ucSLA;            //  从机地址(这是7位纯地址,不含读写控制位)
        unsigned char  ulAddr;           //  数据地址
        unsigned char *pcData;                   //  指向收发数据缓冲区的指针
        unsigned char usSize;          //  收发数据长度
    } tI2CM_DEVICE;
    typedef struct
    {
      unsigned char   s;         // 秒
      unsigned char   m;         // 分
      unsigned char   h;         // 小时
      unsigned char   d;         // 日
      unsigned char   wd;        // 星期
      unsigned char   mm;        // 月
      unsigned char   y;        // 年
    } dt_dat;

    /* Exported constants --------------------------------------------------------*/
    /*I2C实时时钟接口
    SCL                PD7
    SDA                PD6
    INT             PD5*/


    /* Exported macro ------------------------------------------------------------*/

    //  定义pcf2129(NXP RTC,I2C接口)
    #define  PCF2129_SLA            0xA2                     //  定义PCF2129的器件地址

    //#define  PCF2129_S              (u8)0x02            //  定义PCF2129的秒寄存器地址    
    //#define  PCF2129_M              (u8)0x03            //  定义PCF2129的分寄存器地址    
    //#define  PCF2129_H              (u8)0x04            //  定义PCF2129的小时寄存器地址  
    //#define  PCF2129_D              (u8)0x05            //  定义PCF2129的天寄存器地址    
    //#define  PCF2129_W              (u8)0x06            //  定义PCF2129的星期寄存器地址  
    //#define  PCF2129_Mo             (u8)0x07            //  定义PCF2129的月寄存器地址    
    //#define  PCF2129_Y              (u8)0x08            //  定义PCF2129的年寄存器地址低位
                                          
    #define  PCF2129_S              (u8)0x03            //  定义PCF2129的秒寄存器地址     
    #define  PCF2129_M              (u8)0x04            //  定义PCF2129的分寄存器地址     
    #define  PCF2129_H              (u8)0x05            //  定义PCF2129的小时寄存器地址   
    #define  PCF2129_D              (u8)0x06            //  定义PCF2129的天寄存器地址     
    #define  PCF2129_W              (u8)0x07            //  定义PCF2129的星期寄存器地址   
    #define  PCF2129_Mo             (u8)0x08            //  定义PCF2129的月寄存器地址     
    #define  PCF2129_Y              (u8)0x09            //  定义PCF2129的年寄存器地址低位


    //#define Second_alarm     0x0a
    //#define Minute_alarm     0x0b
    //#define Hour_alarm       0x0c
    //#define Day_alarm        0x0d
    //#define Weekday_alarm    0x0e
    //#define CLKOUT_ctl       0x0f
    //#define Watchdg_tim_ctl  0x10
    //#define Watchdg_tim_val  0x11
    //#define Timestp_ctl      0x12
    //#define Sec_timestp      0x13
    //#define Min_timestp      0x14
    //#define Hour_timestp     0x15
    //#define Day_timestp      0x16
    //#define Mon_timestp      0x17
    //#define Year_timestp     0x18
    //#define Aging_offset     0x19
    //#define Internal_reg     0x1a





    /* Exported functions --------------------------------------------------------*/

     
    void PCF2129_Init(void);                                                                                              
    void PCF2129_GetTime(void );
    void PCF2129_SetTime(dt_dat *date_time);
    #endif //__PCF2129_I2C_H

    //******************************file.c*************************************************
      * @file         file.c    
      * @author  
      * @version
      * @date    
      * @brief   This file contains the headers of the xx handlers.
      ******************************************************************************
      * @attention
      *
      *
      *******************************************************************************/
      /* Includes ------------------------------------------------------------------*/
    #include "PCF2129.h"
    #include "myiic.h"
    //#include "stm32f10x_pwr.h"
    //#include "stm32f10x_bkp.h"

    /* extern variables prototypes------------------------------------------------*/
    /* extern function prototypes ------------------------------------------------*/
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    /* Private macro -------------------------------------------------------------*/
    #define BCD_TO_HEX(bcd) ((((bcd)>>4)*10)+((bcd)&0x0F))
    #define HEX_TO_BCD(hex) ((((hex)/10)<<4)+((hex)%10))
    /* Private variables ---------------------------------------------------------*/
    u8 databuff[0x1c]={0};
    dt_dat dt;
    tI2CM_DEVICE PCF2129 = {PCF2129_SLA,      //  从机地址为PCF2129  
                                                    0x00,             //  数据地址为0x00
                                                    databuff,         //  指向收发数据缓冲区的指针
                                                    10};              //  突发发送10个字节数据;


    /* Private function prototypes -----------------------------------------------*/

    /* Private functions ---------------------------------------------------------*/
    /*******************************************************************************
    --- @brief  
    --- @param  None
    --- @retval None
    --- @note
    *******************************************************************************/

    static void IIC_Bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
    {
        u8 stringpos = 0;
        IIC_Start();
        //1表示无应答
        if(IIC_Send_Byte(dev_addr)== 1)
        {
            IIC_Stop();
        return;
        }    
        //发送设备地址+写信号
        if(IIC_Send_Byte(reg_addr)== 1)
        {
            IIC_Stop();
        return;
        }    
        //内部寄存器地址,
        //IIC_Wait_Ack();
        for (stringpos = 0; stringpos < cnt; stringpos++)
        {
            if(IIC_Send_Byte(reg_data[stringpos])== 1)
            {
                IIC_Stop();
                return;
            }
            //内部寄存器数据,
            //IIC_Wait_Ack();
        }
        IIC_Stop();
        //发送停止信号
    }
    void IIC_Bus_Read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
    {
        u8 stringpos = 0;
        IIC_Start();
        //起始信号
        if(IIC_Send_Byte(dev_addr)== 1)
        {
            IIC_Stop();
        return;
        }    
        //发送设备地址+写信号
        if(IIC_Send_Byte(reg_addr)== 1)
        {
            IIC_Stop();
        return;
        }    
        //发读命令
        IIC_Start();
        if(IIC_Send_Byte(dev_addr+1)== 1)
        {
            IIC_Stop();
        return;
        }        
        //发送设备地址+读信号
        
        for (stringpos = 0; stringpos < cnt; stringpos++)
        {
            if(stringpos != cnt -1)
                reg_data[stringpos]=IIC_Read_Byte(1);
            else            
                reg_data[stringpos]=IIC_Read_Byte(0);        
        }
        //IIC_NAck(); //最后一个字节读完发信号
        //IIC_Send_Ack(1);    
        IIC_Stop();    //停止信号
    }

    //  对tI2CM_DEVICE结构体变量设置与数据收发相关的成员(数据地址、数据缓冲区、数据大小)
    void I2CM_DeviceDataSet(tI2CM_DEVICE *pDevice, unsigned char ulAddr,
                                                   unsigned char  *pcData,
                                                   unsigned char usSize)
    {
        pDevice->ulAddr = ulAddr;
        pDevice->pcData = pcData;
        pDevice->usSize = usSize;
    }

    /*******************************************************************************
    --- @brief  初始化
    --- @param  None
    --- @retval None
    --- @note
    *******************************************************************************/
    extern void delay_us(u32 nus);
    void PCF2129_Init(void)
    {
        u8 x = 0;    
        IIC_Init();    
    //    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA6A6)
    //    {
    //        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    //    //后备域解锁
    //    PWR_BackupAccessCmd(ENABLE);
    //    //备份寄存器模块复位
    //        BKP_DeInit();    
    //        
    //        dt.s = 0;
    //        dt.m = 40;
    //        dt.h = 9;//12小时格式,真正的小时是&0X0F,其它2位是AMPM;或者4小时模式
    //        dt.d = 7;//
    //        dt.wd = 6;
    //        dt.mm =1 ;
    //        dt.y = 17;/*0~99*/
    //        PCF2129_SetTime(&dt);
    //            //配置完成后,向后备寄存器中写特殊字符0xA5A5
    //        BKP_WriteBackupRegister(BKP_DR1, 0xA6A6);
    //    }
    //    else
    //    {

    ////若后备寄存器没有掉电,则无需重新配置RTC
    //        //这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
    //        if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    //        {
    //                //这是上电复位
    //        }
    //        else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    //        {
    //                //这是外部RST管脚复位
    //        }
    //        //清除RCC中复位标志
    //        RCC_ClearFlag();
    //    }

        PCF2129_GetTime();
        if((dt.y ==0)&&(dt.mm ==0)&&(dt.wd ==0)&&(dt.d ==0)&&(dt.h ==0)&&(dt.m ==0)&&(dt.s ==0))
        {
            delay_us(2000000);/*2017.03.13初始化时如果读时间失败,重复操作2次以判断是否初始化过,中间间隔2S*/
            PCF2129_GetTime();
            if((dt.y ==0)&&(dt.mm ==0)&&(dt.wd ==0)&&(dt.d ==0)&&(dt.h ==0)&&(dt.m ==0)&&(dt.s ==0))
            {
                dt.s = 0;
                dt.m = 0;
                dt.h = 0;//12小时格式,真正的小时是&0X0F,其它2位是AMPM;或者4小时模式
                dt.d = 1;//
                dt.wd = 1;
                dt.mm =1 ;
                dt.y = 17;/*0~99*/
                PCF2129_SetTime(&dt);
            }
        }
        for (x=0; x < 7; x++)  //  清空数据缓冲区
            databuff[x+2] = 0;                                                
    }
    /*******************************************************************************
    --- @brief  读取时间
    --- @param  None
    --- @retval None
    --- @note
    *******************************************************************************/
    void PCF2129_GetTime(void )
    {    
        u8 x = 0;
        for (x=0; x < 7; x++)  //  清空数据缓冲区
            databuff[x+2] = 0;
        I2CM_DeviceDataSet(&PCF2129,  
                           0x02,
                           &databuff[2],
                           7);     
        IIC_Bus_Read(PCF2129.ucSLA, PCF2129.ulAddr, PCF2129.pcData, PCF2129.usSize);    
        dt.s = BCD_TO_HEX(databuff[PCF2129_S -1] & 0x7f);
        dt.m = BCD_TO_HEX(databuff[PCF2129_M -1] & 0x7f);
        dt.h = BCD_TO_HEX(databuff[PCF2129_H -1] & 0x1f);//12小时格式,真正的小时是&0X0F,其它2位是AMPM;或者4小时模式
        dt.d = BCD_TO_HEX(databuff[PCF2129_D -1] & 0x3f);//
        dt.wd = BCD_TO_HEX(databuff[PCF2129_W -1] & 0x07);
        dt.mm = BCD_TO_HEX(databuff[PCF2129_Mo -1] & 0x1f);
        dt.y = BCD_TO_HEX(databuff[PCF2129_Y -1] & 0x7f);/*0~99*/

    }
    /*******************************************************************************
    --- @brief  设置时间
    --- @param  None
    --- @retval None
    --- @note
    *******************************************************************************/
    void PCF2129_SetTime(dt_dat *date_time)
    {    

        databuff[0] = 0;    
      databuff[1] = 0;    
      databuff[2] |= (7<<5);/*2017.03.13 14:57功耗管理 单独VDD供电。*/
        databuff[PCF2129_S]     = HEX_TO_BCD(date_time->s);  
        databuff[PCF2129_M]     = HEX_TO_BCD(date_time->m);  
        databuff[PCF2129_H]     = HEX_TO_BCD(date_time->h);  
        databuff[PCF2129_D]     = HEX_TO_BCD(date_time->d);  
        databuff[PCF2129_W]     = HEX_TO_BCD(date_time->wd); /*PAD没有传相关参数,如果需要该参数,需要增加函数实现。*/
        databuff[PCF2129_Mo] = HEX_TO_BCD(date_time->mm);
        databuff[PCF2129_Y]  = HEX_TO_BCD(date_time->y);  
    //    databuff[10] = 0x80;             //秒报警控制及报警值设置。
    //  databuff[15] = 0x06;       //  设置CLKOUT为1Hz
    //  databuff[19] = 0x0C;       //  晶振老化补偿设为-4ppm    
        I2CM_DeviceDataSet(&PCF2129,  
                           0x0,
                           &databuff[0],
                           10);
        IIC_Bus_write(PCF2129.ucSLA, PCF2129.ulAddr, PCF2129.pcData, PCF2129.usSize);    
        //  定义I2C主机结构体:设置CLKOUT为1Hz    
    //  I2CM_DeviceDataSet(&PCF2129,
    //                     0x0F,
    //                     &databuff[15],
    //                     1);
    //  
    //  IIC_Bus_write(PCF2129.ucSLA, PCF2129.ulAddr, PCF2129.pcData, PCF2129.usSize);
    //    //  定义I2C主机结构体:设置晶振老化补偿设为-4ppm
    //  I2CM_DeviceDataSet(&PCF2129,  
    //                       0x19,
    //                       &databuff[19],
    //                       1);
    //  IIC_Bus_write(PCF2129.ucSLA, PCF2129.ulAddr, PCF2129.pcData, PCF2129.usSize);     
    }



  • 相关阅读:
    构建之法:第二次心得
    构建之法:第一次心得
    tomcat配置限制ip和建立图片服务器
    tomcat8.5优化配置
    java 操作 csv文件
    jsoup教学系列
    (转)js实现倒计时效果(年月日时分秒)
    本地启动tomcat的时候报java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
    使用mybatis执行oracle存储过程
    java 获取web登录者的ip地址
  • 原文地址:https://www.cnblogs.com/jieruishu/p/6544202.html
Copyright © 2020-2023  润新知