pcf8563_pcf8563中文资料 - CSDN
精华内容
参与话题
  • STM32 IIC通信简介+PCF8563时钟芯片示例

    万次阅读 2016-09-01 15:06:40
    IIC总线是嵌入式设备最常用的接口之一,包括51单片机在内的MCU一般都可以进行IIC通信。 IIC通信有3种类型的信号:开始信号,结束信号,和应答信号。 开始信号:SCL为高电平,SDA由高电平向低电平跳变,表示可以...

    IIC总线是嵌入式设备最常用的接口之一,包括51单片机在内的MCU一般都可以进行IIC通信。

    IIC通信有3种类型的信号:开始信号,结束信号,和应答信号。

    开始信号:SCL为高电平,SDA由高电平向低电平跳变,表示可以开始传输信号,进行通信了。

    结束信号:SCL为高电平,SDA由低电平向高电平跳变,表示传输信号的时间已经过了。

    应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。

    CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号。这个很容易理解,就好像人的交流(通信),要建立起通信,肯定需要开始条件,好像需要约定两个人都上线了才能通信,这就是开始信号。结束信号也一样,处理器不可能一直处于与其他IC通信的状态的。而应答信号,发送方把自己要发送的数据发送出去了,但不知道对方有没有收到,所以有些情况,需要等待接收方返回应答信号,告诉发送方我已经收到了,你可以继续发送下一条数据。


    值得注意的是,虽然大部分MCU都带有IIC总线接口,但实际应用中,使用的一般都是引脚模拟的IIC。


    以下分别介绍IIC配置的软件实现。

    引脚配置(初始化)

    //初始化IIC
    void IIC_Init(void)
    {					     
    	GPIO_InitTypeDef GPIO_InitStructure;
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
    	   
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);
    	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
    }

    #define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X80000000;}
    #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;}


    引脚模拟的IIC开始信号

    //产生IIC起始信号
    void IIC_Start(void)
    {
    	SDA_OUT();     //sda线输出
    	IIC_SDA=1;	  	  
    	IIC_SCL=1;
    	delay_us(4);
     	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
    	delay_us(4);
    	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
    }	  


    停止信号

    //产生IIC停止信号
    void IIC_Stop(void)
    {
    	SDA_OUT();//sda线输出
    	IIC_SCL=0;
    	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
     	delay_us(4);
    	IIC_SCL=1; 
    	IIC_SDA=1;//发送I2C总线结束信号
    	delay_us(4);							   	
    }

    应答信号

    //等待应答信号到来
    //返回值:1,接收应答失败
    //        0,接收应答成功
    u8 IIC_Wait_Ack(void)
    {
    	u8 ucErrTime=0;
    	SDA_IN();      //SDA设置为输入  
    	IIC_SDA=1;delay_us(1);	   
    	IIC_SCL=1;delay_us(1);	 
    	while(READ_SDA)
    	{
    		ucErrTime++;
    		if(ucErrTime>250)
    		{
    			IIC_Stop();
    			return 1;
    		}
    	}
    	IIC_SCL=0;//时钟输出0 	   
    	return 0;  
    }

    IIC通信发送一个字节的信号、接收一个字节的信号

    //产生ACK应答
    void IIC_Ack(void)
    {
    	IIC_SCL=0;
    	SDA_OUT();
    	IIC_SDA=0;
    	delay_us(2);
    	IIC_SCL=1;
    	delay_us(2);
    	IIC_SCL=0;
    }
    //不产生ACK应答		    
    void IIC_NAck(void)
    {
    	IIC_SCL=0;
    	SDA_OUT();
    	IIC_SDA=1;
    	delay_us(2);
    	IIC_SCL=1;
    	delay_us(2);
    	IIC_SCL=0;
    }					 				     
    //IIC发送一个字节
    //返回从机有无应答
    //1,有应答
    //0,无应答			  
    void IIC_Send_Byte(u8 txd)
    {                        
        u8 t;   
    	SDA_OUT(); 	    
        IIC_SCL=0;//拉低时钟开始数据传输
        for(t=0;t<8;t++)
        {              
           
    			if((txd&0x80)>>7)
    				IIC_SDA=1;
    			else
    				IIC_SDA=0;
    			txd<<=1; 	  
    			delay_us(2);  
    			IIC_SCL=1;
    			delay_us(2); 
    			IIC_SCL=0;	
    			delay_us(2);
        }	 
    } 	    
    //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
    u8 IIC_Read_Byte(unsigned char ack)
    {
    	unsigned char i,receive=0;
    	SDA_IN();//SDA设置为输入
        for(i=0;i<8;i++ )
    	{
            IIC_SCL=0; 
            delay_us(2);
    		IIC_SCL=1;
            receive<<=1;
            if(READ_SDA)receive++;   
    		delay_us(1); 
        }					 
        if (!ack)
            IIC_NAck();//发送nACK
        else
            IIC_Ack(); //发送ACK   
        return receive;
    }



    IIC接口的IC很多,常见常用的AT24C02,DS1302,PCF8563等都是IIC接口的。

    下面以PCF8563为例介绍如何使用MCU的IIC与其他器件进行通信。

    PCF8563是一款时钟芯片,具体的介绍请查看手册。时钟芯片大部分都是采用BCD编码的。先介绍一下BCD码和十进制码之间的转换。

    可以认为,BCD码就是十进制码变成十六进制。如:59(十进制)对应的BCD码是0x59 。 10 对应0x10 。 1 对应0x01 。


    互相转换的代码:

    unsigned char RTC_BinToBcd2(unsigned char BINValue)
    {
    	unsigned char bcdhigh = 0;
    	
    	while (BINValue >= 10)
    	{
    		bcdhigh++;
    		BINValue -= 10;
    	}
    	
    	return ((unsigned char)(bcdhigh << 4) | BINValue);
    }


    unsigned char RTC_Bcd2ToBin(unsigned char BCDValue)
    {
    	unsigned char tmp = 0;
    	
    	tmp = ((unsigned char)(BCDValue & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
    	return (tmp + (BCDValue & (unsigned char)0x0F));
    }


    根据手册,查得IIC器件的地址

    #define PCF8563_Write                            (unsigned char)0xa2  //写命令
    #define PCF8563_Read                             (unsigned char)0xa3  //读命令


    向PCF8563的某一寄存器写入某一数据。通信过程也是很明显的,先发出一个开始信号,表示开始传输的是数据了,发送一条读命令,告诉接收方(PCF8563)我要写入数据

    然后等待PCF8563回应说我知道了,你可以写入数据了。然后就再告诉对方写入哪里,等他的回应,最后告诉他要写入什么,同样也等待回应。写完了就可以结束这次通信了

    void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
    {
    	IIC_Start();
    	IIC_Send_Byte(PCF8563_Write);//发送写命令并检查应答位
    	while(IIC_Wait_Ack());
    	IIC_Send_Byte(REG_ADD);
    	IIC_Wait_Ack();
    	IIC_Send_Byte(dat);	//发送数据	
    	IIC_Wait_Ack();
    	IIC_Stop();
    } 

    unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
    {
    	u8 ReData,t=0;
    	IIC_Start( );
    	IIC_Send_Byte(PCF8563_Write);	//发送写命令并检查应答位
    	while(IIC_Wait_Ack( ));
    	IIC_Send_Byte(REG_ADD);	//确定要操作的寄存器
    	IIC_Wait_Ack();
    	IIC_Start();	//重启总线
    	IIC_Send_Byte(PCF8563_Read);	//发送读取命令
    	IIC_Wait_Ack();
    	ReData = IIC_Read_Byte(0);	//读取数据,加发送非应答
    	IIC_Stop();
    	return ReData;
    }

    /******************************************************************************
                                 参数寄存器地址宏定义
    ******************************************************************************/
    
    #define PCF8563_Address_Control_Status_1         (unsigned char)0x00  //控制/状态寄存器1
    #define PCF8563_Address_Control_Status_2         (unsigned char)0x01  //控制/状态寄存器2
    
    #define PCF8563_Address_CLKOUT                   (unsigned char)0x0d  //CLKOUT频率寄存器
    #define PCF8563_Address_Timer                    (unsigned char)0x0e  //定时器控制寄存器
    #define PCF8563_Address_Timer_VAL                (unsigned char)0x0f  //定时器倒计数寄存器
    
    #define PCF8563_Address_Years                    (unsigned char)0x08  //年
    #define PCF8563_Address_Months                   (unsigned char)0x07  //月
    #define PCF8563_Address_Days                     (unsigned char)0x05  //日
    #define PCF8563_Address_WeekDays                 (unsigned char)0x06  //星期
    #define PCF8563_Address_Hours                    (unsigned char)0x04  //小时
    #define PCF8563_Address_Minutes                  (unsigned char)0x03  //分钟
    #define PCF8563_Address_Seconds                  (unsigned char)0x02  //秒
    
    #define PCF8563_Alarm_Minutes                    (unsigned char)0x09  //分钟报警
    #define PCF8563_Alarm_Hours                      (unsigned char)0x0a  //小时报警
    #define PCF8563_Alarm_Days                       (unsigned char)0x0b  //日报警
    #define PCF8563_Alarm_WeekDays                   (unsigned char)0x0c  //星期报警

    <pre name="code" class="cpp">void pcf_reg_init(void)
    {
    	_PCF8563_Register_Typedef PCF8563_Register_Structrue;
    		
    	PCF8563_Register_Structrue.Control_Status_1=0x00;
    	PCF8563_Register_Structrue.Control_Status_2=0x02;
    	//默认时间设置
    	PCF8563_Register_Structrue.Years=0x16;
    	PCF8563_Register_Structrue.Months_Century=0x08;
    	PCF8563_Register_Structrue.WeekDays =0x01;
    	PCF8563_Register_Structrue.Days=0x08;
    	PCF8563_Register_Structrue.Hours=0x04;		
    	PCF8563_Register_Structrue.Minutes=0x03;
    	PCF8563_Register_Structrue.Seconds=0x55|(0<<7);
    	//默认闹钟设置
    	PCF8563_Register_Structrue.Hour_Alarm=0x03|(0<<7);
    	PCF8563_Register_Structrue.Minute_Alarm=0x05|(0<<7);
    	PCF8563_Register_Structrue.WeekDays_Alarm=0x01|(1<<7);	
    	PCF8563_Register_Structrue.Day_Alarm=0x08|(1<<7);
    		
    	//定时器默认设置
    	PCF8563_Register_Structrue.CLKOUT_Frequency=0x03;
    	PCF8563_Register_Structrue.Timer_Countdown_Value=0x00;
    	PCF8563_Register_Structrue.Timer_Control=0x03;
    		
    	PCF8563_SetRegister(PCF_Format_BCD,PCF_Century_20xx,&PCF8563_Register_Structrue);
    
    }


    
    
    其中最后一个函数就是往各个寄存器写入相应的值,这里不再贴代码了。






    展开全文
  • PCF8563+STM32程序

    2020-07-28 23:33:37
    PCF8563时钟的详细应用程序以及在STM32下的端口设置
  • 做时钟显示如果用单片机做,会产生很大的累积误差,本程序采用时钟芯片PCF8563 一:芯片主要电气特性: 1)大工作电压范围:1.0~5.5V 2)400KHz 的 I2C 总线接口(VDD=1.8~5.5V 时)。  时钟频率最大400...
    做时钟显示如果用单片机做,会产生很大的累积误差,本程序采用时钟芯片PCF8563

    一:芯片主要电气特性:
    1)大工作电压范围:1.0~5.5V
    2)400KHz 的 I2C 总线接口(VDD=1.8~5.5V 时)。 


    时钟频率最大400KH

    3)i2C 总线从地址:读,0A3H;写,0A2H .

    二:管脚

     

    电路接线图:


    单片机和PCF8563通信采用IIC协议,单片机读取时钟芯片内寄存器数据或者时钟芯片输出时间信息给单片机.
    本程序知识简单的显示时间,也没有加入芯片损坏延时判断应答子函数.,只是了解芯片使用方法

    IIC总线和LCD1602函数包属于标准代码。

    IIC协议子函数包

    #include <reg52.h>
    #include <intrins.h>
    #define uchar unsigned char
    #define uint unsigned int 

    sbit SDA=P2^2;   //SDA口设置
    sbit SCL=P2^3;   //SCL口设置


    void delay()    //略微延时  6us约>4.7us
    {
    _nop_();
      _nop_();
       _nop_();
        _nop_();
             _nop_();
              _nop_();
    }

    void iic_start()   //启动信号
    {
      SDA=1;
      SCL=1;
      delay();
      SDA=0;
      delay();
      SCL=0;

    }

    void iic_stop()  //停止信号
    {
    SDA=0;
    SCL=1;
    delay();
    SDA=1;
    delay();
    SCL=0;
    }

    void iic_ack()   //应答信号
    {
    uchar i=0;
    SCL=1;
    delay();
    while((SDA==1)&&(i<255))
    i++;
    SCL=0;
    delay();
    }

    void iic_send_byte(uchar bat)  //发送数据
    {
    uchar i,temp;
    temp=bat;
    for(i=0;i<=7;i++)
    {
      temp=temp<<1;
      SCL=0;
      SDA=CY;
      delay();
      SCL=1;
      delay();
    }
    SCL=0;
    delay();
    SDA=1;
    delay();
    }

    uchar iic_rev()  //接受数据
    {
      uchar temp,i;
      SCL=0;
      delay();
      SDA=1;
      for(i=0;i<=7;i++)
      {
       SCL=1;
       delay();
       temp=(temp<<1)|SDA;
       SCL=0;
       delay();
      }
      delay();
      return temp;
    }

    void iic_send_add_byte(uchar add,uchar bat) //向某个地址发送某数据
    {
    iic_start();
    iic_send_byte(0xa2);
    iic_ack();
    iic_send_byte(add);
    iic_ack();
    iic_send_byte(bat);
    iic_ack();
    iic_stop();
    }

    uchar iic_rec_add_byte(uchar add) //从某个地址读出数据
    {
       uchar temp;
       iic_start();
       iic_send_byte(0xa2);
       iic_ack();
       iic_send_byte(add);
       iic_ack();
       iic_start();
       iic_send_byte(0xa3);
       iic_ack();
       temp=iic_rev();
       iic_stop();
       return temp;
    }


    LCD1602函数包:

    **********************************/
    #define LCD1602_DATAPINS P0
    sbit LCD1602_E=P2^7;
    sbit LCD1602_RW=P2^5;
    sbit LCD1602_RS=P2^6;


    void Delay1us(uint a)
    {        
    uint b,c;
    for(c=a;c>0;c--)                
    for(b=110;b>0;b--);
    }

    void LCD1602_WriteCom(uchar com)          //写入命令
    {
            LCD1602_E=0;
            LCD1602_RS=0;
            LCD1602_RW=0;
            LCD1602_DATAPINS=com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
            Delay1us(10);
            LCD1602_E=1;
            Delay1us(10);
            LCD1602_E=0;
            Delay1us(10);
            LCD1602_DATAPINS=com<<4;
            Delay1us(10);
            LCD1602_E=1;
            Delay1us(10);
            LCD1602_E=0;
    }

    void LCD1602_WriteData(uchar dat)                        //写入数据
    {
            LCD1602_E=0;
            LCD1602_RS=1;
            LCD1602_RW=0;
            LCD1602_DATAPINS=dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
            Delay1us(10);
            LCD1602_E=1;
            Delay1us(10);
            LCD1602_E=0;
            LCD1602_DATAPINS=dat<<4;
            Delay1us(10);
            LCD1602_E=1;
            Delay1us(10);
            LCD1602_E=0;
    }

    void LCD1602_Init()                                                  //LCD初始化子程序
    {
            LCD1602_WriteCom(0x32);         //将8位总线转为4位总线
            LCD1602_WriteCom(0x28);         //在四位线下的初始化
            LCD1602_WriteCom(0x0c);  //开显示不显示光标
            LCD1602_WriteCom(0x06);  //写一个指针加1
            LCD1602_WriteCom(0x01);  //清屏
            LCD1602_WriteCom(0x80);  //设置数据指针起点
    }

    //----- 主函数---------
    #include <reg52.h>
    #include "lcd.h"
    #include "iic.h"

    //-----------延时用于稳定-------------
    void delay_kk(uint k)
    {
      while(k--);
    }

    //------------------------------BCD码讲解---
    比如十六进制数0x56  如果代表BCD码,则其就是代表10进制的56  但是在计算机里面如果用于计算他就是86(十进制),所以后面例出BCD转10进制子函数    PCF8563显示的数都是BCD码

     
    //-----------时间预设定值---------
    void time_init()
    {
       iic_send_add_byte(0x02,0x50);         //0秒
            iic_send_add_byte(0x03,0x59);         //0分钟    
        iic_send_add_byte(0x04,0x23);          //0小时             
             iic_send_add_byte(0x05,0x26);  //26号
             iic_send_add_byte(0x07,0x05);           //5月  20世纪的
             iic_send_add_byte(0x08,0x14);         //2014年
    }



    //----------------PCF8563初始化-----------------
    void pcf_init()
    {
            iic_send_add_byte(0x00,0x00);  //启动时钟
    }

    //----------------BCD转10进制-----------
    uchar bcd_dec(uchar bat)
    {
    uchar temp1,temp2,tol;
    temp1=bat&0x0f;
    temp2=(bat&0xf0)>>4;
    tol=temp2*10+temp1;
    return tol; 
    }

    //------------LCD1602显示:年,月,日,小时,分钟,秒,
    void display_time(uchar sec,min,hour,dat,moom,year)
    {
      LCD1602_WriteCom(0x80);
      LCD1602_WriteData('_');
    LCD1602_WriteData('2');
    LCD1602_WriteData('0');
    LCD1602_WriteData(year/10+48);
    LCD1602_WriteData(year%10+48);
    LCD1602_WriteData('/');
    LCD1602_WriteData(moom+48);
    LCD1602_WriteData('/');
    LCD1602_WriteData(dat/10+48);
    LCD1602_WriteData(dat%10+48);
      LCD1602_WriteCom(0xc4);
       LCD1602_WriteData(hour/10+48);
        LCD1602_WriteData(hour%10+48);
    LCD1602_WriteData(':');
    LCD1602_WriteData(min/10+48);
    LCD1602_WriteData(min%10+48);
    LCD1602_WriteData(':');
    LCD1602_WriteData(sec/10+48);
    LCD1602_WriteData(sec%10+48);
    }

    void main()
    {
       uchar sec,min,hour,dat,moom,year,sec1,min1,hour1,dat1,moom1,year1;  //PCF8563读出的变量和代转换成的十进制变量
       LCD1602_Init();
       iic_send_add_byte(0x00,0x20);  // 关闭时钟
      delay_kk(1000);
             time_init();    //时钟芯片初始时间设置
             pcf_init();
        delay_kk(1000);
      while(1)
      {
                sec=0x7f&iic_rec_add_byte(0x02);    //读取秒
             min=0x7f&iic_rec_add_byte(0x03);   //读取分钟
             hour=0x3f&iic_rec_add_byte(0x04);  //读取小时
             dat=0x3f&iic_rec_add_byte(0x05);   //读取天数
             moom=0x1f&iic_rec_add_byte(0x07);  //读取月
             year=0xff&iic_rec_add_byte(0x08);    //读取年
             sec1=bcd_dec(sec);                   //将读取的BCD码秒转换成十进制秒以便运算
             min1=bcd_dec(min);
             hour1=bcd_dec(hour);
             dat1=bcd_dec(dat);
             moom1=bcd_dec(moom);
             year1=bcd_dec(year);
             display_time(sec1,min1,hour1,dat1,moom1,year1);   //LCD1602显示时间
      }                                          







    展开全文
  • PCF8563 时钟芯片驱动代码

    千次阅读 2017-09-09 16:24:31
    //C文件 /**********************************************************************************************... * 文件名: PCF8563.c * 功能: STM32 PCF8563 高精度 RTC 芯片驱动 * 作者: cp1300@139.com *

    //C文件

    /*************************************************************************************************************
     * 文件名:			PCF8563.c
     * 功能:			STM32 PCF8563 高精度 RTC 芯片驱动
     * 作者:			cp1300@139.com
     * 创建时间:		2017-07-10
     * 最后修改时间:	2017-07-10
     * 详细:			使用软件IIC接口驱动
    					2017-07-13:通过写入PCF8563_REG_CLKOUT与读取PCF8563_REG_CLKOUT寄存器,发现某些不用的位会乱跳,最终发现时间寄存器也有同样的问题,需要把不用的位都屏蔽掉
    *************************************************************************************************************/
    #include "system.h"
    #include "delay.h"
    #include "PCF8563.h"
    #include "stdio.h"
    #include "SoftwareIIC.h"
    
    //月修正数据表
    static u8 const table_week[12] = {0,3,3,6,1,4,6,2,5,0,3,5}; 		  
    //平年的月份日期表
    static u8 const mon_table[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    static bool Is_Leap_Year(u16 year);
    
    
    rtc_timer ext_timer;	//外部RTC时钟
    static SIIC_HANDLE IIC_Handel;
    
    #define PCF8563_SDA_GPIOx 	GPIOC
    #define PCF8563_SCL_GPIOx 	GPIOC
    #define PCF8563_SDA_Bit 	1
    #define PCF8563_SCL_Bit	 	13
    
    
    
    
    //调试宏开关
    #define PCF8563_DBUG	1
    #if PCF8563_DBUG
    	#include "system.h"
    	#define PCF8563_Debug(format,...)	uart_printf(format,##__VA_ARGS__)
    #else
    	#define PCF8563_Debug(format,...)	/\
    /
    #endif	//PCF8563_DBUG
    
    
    //PCF8563 iic总线地址
    #define PCF8563_IIC_W_ADDR			0xA2
    #define PCF8563_IIC_R_ADDR			0xA3
    
    
    static u8 GetWeek(u16 year,u8 month,u8 day);	//获取2000-2099年之间的日期对应的星期
    static u32 DECtoBCD( u8 DEC);					//将数字转换为压缩BCD格式,最大支持99
    static u32 BCDtoDEC(u8 BCD);					//将压缩BCD转为DEC,最大支持99
    bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) ;		//读取PCF8563寄存器
    bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) ;	//写入PCF8563寄存器
    bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data);				//写单个寄存器
    
    
    /*************************************************************************************************************************
    *函数        	:	bool PCF8563_Init(void)
    *功能        	:	初始化PCF8563
    *参数        	:	无
    *返回        	:	FALSE:失败;TRUE:成功
    *依赖			: 	底层宏定义
    *作者       	:	cp1300@139.com
    *时间     		:	2017-07-10
    *最后修改时间	:	2017-07-10
    *说明        	:	无
    *************************************************************************************************************************/
    bool PCF8563_Init(void)
    {
    	u8 data;
    	
    	memset(&ext_timer,0,sizeof(rtc_timer));
    	if(SIIC_Init(&IIC_Handel,PCF8563_SDA_GPIOx, PCF8563_SCL_GPIOx, PCF8563_SDA_Bit, PCF8563_SCL_Bit, 1) == FALSE)
    	{
    		PCF8563_Debug("**********************PCF8563 初始化失败,IIC接口初始化失败!\r\n");
    		return FALSE;
    	}
    	
    	if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1, 0x08) == FALSE)	//启动时钟,开启掉电检测
    	{
    		PCF8563_Debug("**********************PCF8563 初始化失败,开启掉电监测功能失败!\r\n");
    		return FALSE;
    	}
    
    	if(PCF8563_ReadReg(PCF8563_REG_SECONDS, &data, 1) == FALSE)
    	{
    		PCF8563_Debug("**********************PCF8563 初始化失败,读取秒寄存器失败!\r\n");
    		return FALSE;
    	}
    	if(data & 0x80)	//秒 最高位为1,时钟芯片没有初始化 integrity of the clock information is no longer guaranteed
    	{
    		//初始化时钟芯片与时间
    		PCF8563_Debug("时钟芯片没有初始化,需要重新初始化时钟!\r\n");
    		if(PCF8563_SetTimer(2017,6,6,6,6,6)==FALSE)
    		{
    			PCF8563_Debug("时钟芯片没有初始化,需要重新初始化时钟!\r\n");
    		}
    	}
    	
    	PCF8563_GetTimer();		//更新时间
    	return TRUE;
    }
    
    /*************************************************************************************************************************
    *函数        	:	bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) 
    *功能        	:	读取PCF8563多个寄存器
    *参数        	:	RegIndex:寄存器地址,pData:读取到的值,RegNum:读取的寄存器数量
    *返回        	:	TRUE:通信成功;FALSE:通信失败
    *依赖			: 	底层宏定义
    *作者       	:	cp1300@139.com
    *时间     		:	2017-07-10
    *最后修改时间	:	2017-07-10
    *说明        	:	无
    *************************************************************************************************************************/
    bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) 
    {
    	u8 i;
    	
    	if(RegNum < 1) RegNum = 1;
    	if(RegNum > 16) RegNum = 16;								//限制读取的最大数量
    	
    	SIIC_Start(&IIC_Handel);									//发送起始信号
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE)	//发送写地址
    	{
    		PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)				//发送要读取的寄存器地址
    	{
    		PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	SIIC_Start(&IIC_Handel);									//发送起始信号	
    	
    	
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_R_ADDR)==FALSE)	//发送读取地址
    	{
    		PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	for(i = 0;i < RegNum;i ++)
    	{
    		if(i == (RegNum-1))										//最后一字节
    		{
    			pData[i] = SIIC_ReadByte(&IIC_Handel, FALSE);		//读取数据-最后一字节不发送ACK
    		}
    		else
    		{
    			pData[i] = SIIC_ReadByte(&IIC_Handel, TRUE);		//读取数据
    		}
    	}
    	
    	SIIC_Stop(&IIC_Handel);										//发送结束
    
    	return TRUE;
    }
    
    
    /*************************************************************************************************************************
    *函数        	:	bool PCF8563_ReadOneReg(PCF8563_REG_TYPE RegIndex, u8 *pData) 
    *功能        	:	读取PCF8563单个寄存器
    *参数        	:	RegIndex:寄存器地址,pData:读取到的值
    *返回        	:	TRUE:通信成功;FALSE:通信失败
    *依赖			: 	底层宏定义
    *作者       	:	cp1300@139.com
    *时间     		:	2017-07-10
    *最后修改时间	:	2017-07-13
    *说明        	:	无
    *************************************************************************************************************************/
    bool PCF8563_ReadOneReg(PCF8563_REG_TYPE RegIndex, u8 *pData) 
    {
    	SIIC_Start(&IIC_Handel);									//发送起始信号
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE)	//发送写地址
    	{
    		PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)				//发送要读取的寄存器地址
    	{
    		PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	SIIC_Start(&IIC_Handel);									//发送起始信号	
    	
    	
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_R_ADDR)==FALSE)	//发送读取地址
    	{
    		PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	*pData = SIIC_ReadByte(&IIC_Handel, FALSE);					//读取数据-最后一字节不发送ACK
    	
    	SIIC_Stop(&IIC_Handel);										//发送结束
    	return TRUE;
    }
    
    
    /*************************************************************************************************************************
    *函数        	:	bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) 
    *功能        	:	写PCF8563多个寄存器
    *参数        	:	RegIndex:寄存器地址,pData:写入的值,RegNum:写入的寄存器数量
    *返回        	:	TRUE:通信成功;FALSE:通信失败
    *依赖			: 	底层宏定义
    *作者       	:	cp1300@139.com
    *时间     		:	2017-07-10
    *最后修改时间	:	2017-07-10
    *说明        	:	无
    *************************************************************************************************************************/
    bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) 
    {
    	u8 i;
    
    	SIIC_Start(&IIC_Handel);									//发送起始信号
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE)	//发送写地址
    	{
    		PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
    		return FALSE;
    	}
    
    	/*if(SIIC_SendByte(&IIC_Handel, 0)==FALSE)				//发送要读取的寄存器地址
    	{
    		PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
    		return FALSE;
    	}*/
    	
    	if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)				//发送要写的寄存器地址
    	{
    		PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
    		return FALSE;
    	}
    	/*SIIC_Start(&IIC_Handel);									//发送起始信号						
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE)	//发送写地址
    	{
    		PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
    		return FALSE;
    	}*/
    	
    	for(i = 0;i < RegNum;i ++)
    	{
    		SIIC_SendByte(&IIC_Handel, pData[i]);					//发送数据
    	}
    	
    	SIIC_Stop(&IIC_Handel);										//发送结束
       
    	return TRUE;
    }
    
    
    /*************************************************************************************************************************
    *函数        	:	bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data)  
    *功能        	:	写PCF8563单个寄存器
    *参数        	:	RegIndex:寄存器地址,Data:写入的值
    *返回        	:	TRUE:通信成功;FALSE:通信失败
    *依赖			: 	底层宏定义
    *作者       	:	cp1300@139.com
    *时间     		:	2017-07-10
    *最后修改时间	:	2017-07-13
    *说明        	:	无
    *************************************************************************************************************************/
    bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data) 
    {
    	SIIC_Start(&IIC_Handel);									//发送起始信号
    	if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE)	//发送写地址
    	{
    		PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
    		return FALSE;
    	}
    	if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)				//发送要写的寄存器地址
    	{
    		PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
    		return FALSE;
    	}
    	
    	SIIC_SendByte(&IIC_Handel, Data);							//发送数据
    	
    	SIIC_Stop(&IIC_Handel);										//发送结束
       
    	return TRUE;
    }
    
    /*************************************************************************************************************************
    * 函数			:	bool PCF8563_GetTimer(void)
    * 功能			:	PCF8563获取时间
    * 参数			:	无
    * 返回			:	TRUE:成功,FALSE:失败
    * 依赖			:	底层宏定义
    * 作者			:	cp1300@139.com
    * 时间			:	2017-07-11
    * 最后修改时间 	: 	2017-07-11
    * 说明			: 	获取到的时间会更新到全局ext_timer
    *************************************************************************************************************************/
    bool PCF8563_GetTimer(void)
    {
    	u8 data[7];
    	u8 retry;
    	u8 temp;
    
    	
    	for(retry = 0;retry < 3;retry ++)
    	{
    		if(PCF8563_ReadReg(PCF8563_REG_SECONDS, data, 7) == TRUE)	//设置时间
    		{
    			if(data[0] & 0x80)	//时间无效
    			{
    				PCF8563_Debug("PCF8563 时间无效,需要重新初始化!\r\n");
    				PCF8563_SetTimer(2017,6,6,6,6,6);					//初始化设置时间
    			}
    			else
    			{
    				
    				//uart_printf("%02X,%02X,%02X,%02X,%02X,%02X,%02X\r\n",data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
    				temp = BCDtoDEC(data[0]&0x7F);
    				if(temp > 59) continue;				//秒钟范围不对
    				ext_timer.sec = temp;
    				temp = BCDtoDEC(data[1]&0x7F);
    				if(temp > 59) continue;				//分钟范围不对
    				ext_timer.min = temp;
    				temp = BCDtoDEC(data[2]&0x3F);
    				if(temp > 23) continue;				//小时范围不对
    				ext_timer.hour = temp;
    				temp = BCDtoDEC(data[3]&0x3F);
    				if(temp > 31||temp==0) continue;	//日期范围不对
    				ext_timer.date = temp;
    				temp = BCDtoDEC(data[4]&0x07);
    				if(temp > 6) continue;				//星期范围不对
    				ext_timer.week = temp+1;
    				temp = BCDtoDEC(data[5]&0x1F);
    				if(temp > 12||temp==0) continue;	//月份范围不对
    				ext_timer.month = temp;
    				ext_timer.year = BCDtoDEC(data[6])+2000;
    
    				return TRUE;
    			}
    		}
    		else
    		{
    			PCF8563_Debug("PCF8563 读取时间失败!\r\n");
    		}
    	}
    	return FALSE;
    }
    
    
    
    /*************************************************************************************************************************
    * 函数			:	bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec)
    * 功能			:	PCF8563时间设置
    * 参数			:	year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小时24小时,分钟,秒钟
    * 返回			:	TRUE:成功,FALSE:失败
    * 依赖			:	底层宏定义
    * 作者			:	cp1300@139.com
    * 时间			:	2017-07-11
    * 最后修改时间 	: 	2017-07-11
    * 说明			: 	
    *************************************************************************************************************************/
    bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec)
    {
    	u8 data[7];
    	
    	if(year < 2000) year = 2000;
    	if(year > 2099) year = 2099;
    	
    	data[0] = DECtoBCD(sec);	//秒
    	data[1] = DECtoBCD(min);	//分
    	data[2] = DECtoBCD(hour);	//小时
    	data[3] = DECtoBCD(date);	//日
    	data[4] = GetWeek(year, month, date)-1;	//星期
    	year -= 2000;
    	data[5] = DECtoBCD(month);	//月
    	data[6] = DECtoBCD(year);	//年
    	
    	PCF8563_WriteReg(PCF8563_REG_SECONDS, &data[0], 7);	//设置时间
    
    	
    	
    	if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1, 0x08) == FALSE)	//启动时钟,开启掉电检测
    	{
    		PCF8563_Debug("**********************PCF8563 设置失败,启动时钟失败!\r\n");
    		return FALSE;
    	}
    	
    	return TRUE;
    }
    
    
    
    
    
    
    
    /*************************************************************************************************************************
    * 函数			:	u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
    * 功能			:	PCF8563时间转换为秒(从1970开始)(注意:不可重入,请注意调用冲突)
    * 参数			:	year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小时24小时,分钟,秒钟
    * 返回			:	TRUE:成功,FALSE:失败
    * 依赖			:	底层宏定义
    * 作者			:	cp1300@139.com
    * 时间			:	2017-07-11
    * 最后修改时间 	: 	2017-07-17
    * 说明			: 	只能计算从2000年之后的秒,修改如果年,月,日不变,则无需重新计算,提高效率
    					注意:不可重入,请注意调用冲突
    *************************************************************************************************************************/
    u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
    {
    	u16 t;
    	u32 seccount = 0;
    	static u32 LastYearSec = 0;		//之前年对应的秒,如果年不变,则不用重新计算
    	static u32 LastMonSec = 0;		//当前年月份对应的秒数,如果月份不变,则不需要重新计算
    	static u32 LastDaySec = 0;		//当前日期对应的秒,如果日期不变,则不需要重新计算
    	static u16 LastYear = 0;		//之前的年如果不变,则只计算今年的秒
    	static u8 LastMon = 0;			//当前年之前的月份
    	static u8 LastDay = 0;			//之前的日期
    	
    	
    	
    	if(syear < 2000 || syear > 2099)
    		return 0;
    
    	//年变化了才重新计算
    	if(LastYear != syear)							//年发生了变化,重新计算
    	{
    		LastYear = syear;							//记录本次的年
    		LastYearSec = 0;
    		for(t = 1970;t < syear;t ++)				//把所有年份的秒钟相加
    		{
    			if(Is_Leap_Year(t))
    				LastYearSec += 31622400;			//闰年的秒钟数
    			else 
    				LastYearSec += 31536000;			  //平年的秒钟数
    		}
    	}
    
    	//月变化了才重新计算
    	if(LastMon != smon)								//月份有变化
    	{
    		LastMon = smon;								//记录本次的月份
    		smon -= 1;
    		LastMonSec = 0;
    		for(t = 0;t < smon;t ++)	   					//把前面月份的秒钟数相加
    		{
    			LastMonSec += (u32)mon_table[t] * 86400;	//月份秒钟数相加
    			if(Is_Leap_Year(syear) && t == 1)
    				LastMonSec += 86400;					//闰年2月份增加一天的秒钟数	   
    		}
    	}
    	//日期变化了才重新计算
    	if(LastDay != sday)
    	{
    		LastDay = sday;								//记录本次的日期
    		LastDaySec = (u32)(sday - 1) * 86400;		//把前面日期的秒钟数相加 
    	}
    	
    	seccount = LastYearSec+LastMonSec+LastDaySec;	//直接获取年对应的秒,不用每次计算
    
    	seccount += (u32)hour * 3600;					//小时秒钟数
        seccount += (u32)min * 60;	 					//分钟秒钟数
    	seccount += sec;								//最后的秒钟加上去
    	
    	return seccount;
    }
    
    
    
      
    /*************************************************************************************************************************
    * 函数			:	bool Is_Leap_Year(u16 year)
    * 功能			:	判断是否是闰年函数
    * 参数			:	year:年份
    * 返回			:	TRUE:是闰年,FALSE:不是闰年
    * 依赖			:	无
    * 作者			:	cp1300@139.com
    * 时间			:	2014-05-30
    * 最后修改时间	:	2014-05-30
    * 说明			: 	
    					月份   1  2  3  4  5  6  7  8  9  10 11 12
    					闰年   31 29 31 30 31 30 31 31 30 31 30 31
    					非闰年 31 28 31 30 31 30 31 31 30 31 30 31	
    *************************************************************************************************************************/
    static bool Is_Leap_Year(u16 year)
    {			  
    	if(year % 4 == 0) //必须能被4整除
    	{ 
    		if(year % 100 == 0) 
    		{ 
    			if(year % 400 == 0)
    				return TRUE;//如果以00结尾,还要能被400整除 	   
    			else 
    				return FALSE;   
    		}else 
    			return TRUE;   
    	}else 
    		return FALSE;	
    }
    
    
    //获取2000-2099年之间的日期对应的星期
    //功能描述:输入公历日期得到星期(只允许1901-2099年)
    //year,month,day:公历年月日 
    //返回值:星期号(1~7,代表周1~周日)																						 
    static u8 GetWeek(u16 year,u8 month,u8 day)
    {	
    	u16 temp2;
    	u8 yearH,yearL;
    	yearH=year/100;	yearL=year%100; 
    	// 如果为21世纪,年份数加100  
    	if (yearH>19)yearL+=100;
    	// 所过闰年数只算1900年之后的  
    	temp2=yearL+yearL/4;
    	temp2=temp2%7; 
    	temp2=temp2+day+table_week[month-1];
    	if (yearL%4==0&&month<3)temp2--;
    	temp2%=7;
    	if(temp2==0)temp2=7;
    	return temp2;
    }	
    
    
    
    
    //将数字转换为压缩BCD格式,最大支持99
    static u32 DECtoBCD( u8 DEC) 
    {
    	return ((u8)(DEC/10)<<4)+(DEC%10);
    }
    
    
    //将压缩BCD转为DEC,最大支持99
    static u32 BCDtoDEC(u8 BCD)
    {
    	return (u8)(BCD>>4)*10+(BCD&0x0f);
    }
    
    
    
    //使能系统命令行
    #if SYS_CMD_EN_
    #include "cmd.h"
    #include "string.h"
    
    const CMD_TYPE  CMD_GET_ExtTIME		=	{"TIME?", 0xCC5C410A, CMD_ExtGetTime, "\t\t获取系统时间"};
    const CMD_TYPE  CMD_GET_ExtDATE		=	{"DATE?", 0xB2704461, CMD_ExtGetDate, "\t\t获取系统日期"};
    const CMD_TYPE  CMD_SET_ExtTIME		=	{"TIME=", 0xCC5C4108, CMD_ExtSetTime, "\t\t设置系统时间 如(12:32:54):TIME=12 32 54"};
    const CMD_TYPE  CMD_SET_ExtDATE		=	{"DATE=", 0xB270445F, CMD_ExtSetDate, "\t\t设置系统日期 如(2014 6 8):TIME=2014 6 8"};
    
    //获取时间
    void CMD_ExtGetTime(char *pStr)
    {
    	//PCF8563_GetTimer();		//更新时间
    	cmd_printf("[获取时间成功]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
    }
    
    //获取日期
    void CMD_ExtGetDate(char *pStr)
    {
    	//PCF8563_GetTimer();		//更新时间
    	cmd_printf("[获取日期成功]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
    }
    
    //设置时间
    void CMD_ExtSetTime(char *pStr)
    {
    	u8 hour,min,sec;
    	u8 len;
    	char *p;
    	u8 num;
    	
    	len = strlen(pStr);	//获取长度
    	if(isStrNumAndSpc(pStr, len, 2) == FALSE)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	//小时
    	p = strstr(pStr," ");	//搜索空格
    	if(p == NULL)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	num = p - pStr;
    	if((num > 2) || (num == 0))
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	hour = CMD_StringToDec(pStr, num);
    	if(hour>23)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	
    	//分钟
    	pStr = p+1;
    	p = strstr(pStr," ");	//搜索空格
    	if(p == NULL)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	num = p - pStr;
    	if((num > 2) || (num == 0))
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	min = CMD_StringToDec(pStr, num);
    	if(min>59)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	//秒钟
    	pStr = p+1;
    	num = strlen(pStr);
    	if((num > 2) || (num == 0))
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	sec = CMD_StringToDec(pStr, num);
    	if(sec>59)
    	{
    		cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	
    	PCF8563_GetTimer();		//更新时间
    	if(PCF8563_SetTimer(ext_timer.year, ext_timer.month, ext_timer.date,hour, min, sec) == FALSE)
    	{
    		PCF8563_GetTimer();		//更新时间
    		cmd_printf("[时间设置失败]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
    	}
    	else
    	{
    		PCF8563_GetTimer();		//更新时间
    		cmd_printf("[时间设置成功]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
    	}
    	
    } 
    
    
    //设置日期
    void CMD_ExtSetDate(char *pStr)
    {
    	u16 year;
    	u8 month, date;
    	u8 len;
    	char *p;
    	u8 num;
    	
    	len = strlen(pStr);	//获取长度
    	if(isStrNumAndSpc(pStr, len, 2) == FALSE)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	//年
    	p = strstr(pStr," ");	//搜索空格
    	if(p == NULL)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	num = p - pStr;
    	if((num > 4) || (num == 0))
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	year = CMD_StringToDec(pStr, num);
    	if(year>9999)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	
    	//月
    	pStr = p+1;
    	p = strstr(pStr," ");	//搜索空格
    	if(p == NULL)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	num = p - pStr;
    	if((num > 2) || (num == 0))
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	month = CMD_StringToDec(pStr, num);
    	if(month>12)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	//日
    	pStr = p+1;
    	num = strlen(pStr);
    	if((num > 2) || (num == 0))
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	date = CMD_StringToDec(pStr, num);
    	if(date>31)
    	{
    		cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
    		return;
    	}
    	
    	PCF8563_GetTimer();		//更新时间
    	if(PCF8563_SetTimer(year, month, date, ext_timer.hour, ext_timer.min, ext_timer.sec) == FALSE)
    	{
    		PCF8563_GetTimer();		//更新时间
    		cmd_printf("[日期设置失败]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
    	}
    	else
    	{
    		PCF8563_GetTimer();		//更新时间
    		cmd_printf("[日期设置成功]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
    	}
    	
    } 
    
    
    #endif //SYS_CMD_EN_
    

    //,H文件

    /*************************************************************************************************************
     * 文件名:			PCF8563.h
     * 功能:			STM32 PCF8563 高精度 RTC 芯片驱动
     * 作者:			cp1300@139.com
     * 创建时间:		2017-07-10
     * 最后修改时间:	2017-07-10
     * 详细:			使用软件IIC接口驱动
    *************************************************************************************************************/
    #ifndef _PCF8563_H_
    #define _PCF8563_H_
    
    #include "system.h"
    
    #if(BOARD_SUPPORT)	//需要板级支持
    #include "board.h" 
    #else	//默认支持
    
    #endif
    
    
    //时间结构体
    typedef  struct 
    {
    	u8	hour; 		//小时
    	u8	min;	 	//分钟
    	u8	sec;		//秒			
    	u8  month;		//月
    	u8  date;		//日
    	u8  week;		//星期
    	u16 year;	 	//年
    }rtc_timer;
    extern rtc_timer ext_timer;	//外部RTC时钟
    
    
    //PCF8563 寄存器
    typedef enum
    {
    	PCF8563_REG_CONTROL1			=	0x00,	//控制寄存器1
    	PCF8563_REG_CONTROL2			=	0x01,	//控制寄存器2
    	PCF8563_REG_SECONDS				=	0x02,	//秒 seconds 00 to 59 coded in BCD
    	PCF8563_REG_MINUTES				=	0x03,	//分 minutes 00 to 59 coded in BCD
    	PCF8563_REG_HOURS				=	0x04,	//小时 hours 00 to 23 coded in BCD
    	PCF8563_REG_DAYS				=	0x05,	//日 days 01 to 31 coded in BCD
    	PCF8563_REG_WEEK				=	0x06,	//星期 weekdays 0 to 6 in BCD
    	PCF8563_REG_MONTHS				=	0x07,	//月份 months 01 to 12 coded in BCD
    	PCF8563_REG_YEARS				=	0x08,	//年份 years 00 to 99 coded in BCD
    	PCF8563_REG_ALARM_MINUTE		=	0x09,	//闹钟,分钟 minute alarm 00 to 59 coded in BCD
    	PCF8563_REG_ALARM_HOUR			=	0x0A,	//闹钟,小时 hour alarm 00 to 23 coded in BCD
    	PCF8563_REG_ALARM_DAY			=	0x0B,	//闹钟,日 day alarm 01 to 31 coded in BCD
    	PCF8563_REG_ALARM_WEEK			=	0x0C,	//闹钟,星期 weekday alarm 0 to 6 in BCD
    	PCF8563_REG_CLKOUT				=	0x0D,	//时钟输出设置
    	PCF8563_REG_TIME_CONTROL		=	0x0E,	//定时器设置
    	PCF8563_REG_TIME				=	0x0F,	//定时器倒计数值
    }PCF8563_REG_TYPE;
    
    
    bool PCF8563_Init(void);													//PCF8563初始化
    bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec);		//PCF8563时间设置
    bool PCF8563_GetTimer(void);												//更新时间
    
    u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);		//时间转换为秒,注意:不可重入,请注意调用冲突
    
    
    //使能系统命令行
    #if SYS_CMD_EN_
    #include "cmd.h"
    #include "string.h"
    
    
    
    extern const CMD_TYPE  CMD_GET_ExtTIME;
    extern const CMD_TYPE  CMD_GET_ExtDATE;
    extern const CMD_TYPE  CMD_SET_ExtTIME;
    extern const CMD_TYPE  CMD_SET_ExtDATE;
    
    
    //获取时间
    void CMD_ExtGetTime(char *pStr);
    //获取日期
    void CMD_ExtGetDate(char *pStr);
    //设置时间
    void CMD_ExtSetTime(char *pStr);
    //设置日期
    void CMD_ExtSetDate(char *pStr);
    
    #endif //SYS_CMD_EN_
    
    #endif /*_PCF8563_H_*/
    


    展开全文
  • 包含PCF8563芯片的驱动和测试的源程序,含有详细的注释,已经经过调试,可以直接使用到项目中
  • (1) 先把kernel 目录下.config pcf8563打开,且rk808关闭 (2) dts 配置,在根节点添加rtc_pcf8563节点。 之后再在硬件接口i2c 上添加pcf8563子节点。 (3) 在rtc_lib.c 文件中按图片修改: ...

    (1) 先把kernel 目录下.config pcf8563打开,且rk808关闭

    在这里插入图片描述
    (2) dts 配置,在根节点添加rtc_pcf8563节点。 之后再在硬件接口i2c
    上添加pcf8563子节点。
    在这里插入图片描述

    在这里插入图片描述

    (3) 在rtc-lib.c 文件中按图片修改:
    在这里插入图片描述

    之后在rtc-pcf8563.c 增加待机写闹钟函数
    static int pcf8563_rtc_setalarm_pwron(struct device *dev, struct rtc_time *tm)
    {

    struct i2c_client *client = to_i2c_client(dev);
    unsigned char buf[4];
    int err;
    
    printk("enter pcf8563 rtc setalarm pwron function\r\n");
    
    /* The alarm has no seconds, round up to nearest minute */
    if (tm->tm_sec) {
    	time64_t alarm_time = rtc_tm_to_time64(tm);
    
    	alarm_time += 60 - tm->tm_sec;
    	rtc_time64_to_tm(alarm_time, tm);
    }
    
    dev_info(dev, "%s, min=%d hour=%d wday=%d mday=%d "
    	, __func__,
    	tm->tm_min, tm->tm_hour, tm->tm_wday,
    	tm->tm_mday);
    
    
    //tm->tm_wday=tm->tm_wday+4;   // for app set to kernel 2020-05-07
    
    buf[0] = bin2bcd(tm->tm_min);
    buf[1] = bin2bcd(tm->tm_hour);
    buf[2] = bin2bcd(tm->tm_mday);
    buf[3] = (tm->tm_wday & 0x07);
    
    
    dev_info(dev, "%s, after min=%d hour=%d mday=%d wday=%d "
    	, __func__,
    	buf[0], buf[1], buf[2],
    	buf[3]);
    
    //err = pcf8563_write_block_data(client, PCF8563_REG_AMN, 4, buf);
    err = pcf8563_write_block_data(client, PCF8563_REG_AMN, 3, buf);
    if (err)
    	return err;
    
    
    printk("%s err=%d",__func__,err);
    
    return pcf8563_set_alarm_mode(client, 1);
    

    }

    将上面pcf8563_rtc_setalarm_pwron函数
    在这里插入图片描述

    本人创建QQ群,进QQ技术交流,QQ群:712288614

    展开全文
  • I2C-pcf8563

    千次阅读 2015-06-04 09:29:49
    linux 2.6.35.2 ——MX28添加pcf8563驱动 pcf8563硬件连接到核心板引出的I2C1引脚上。修改内核源码包,添加i2c下pcf8563的驱动。 通过终端命令hwclock可以操作pcf8563时钟芯片的读写,验证pcf8563驱动是否移植成功...
  • 硬件平台:RK3128 ...Rk3128 Android 6.0平台调试rtc芯片PCF8563,本以为很容易,结果碰到一些问题,在此记录下来。   一、添加设备信息 Dts中添加I2C设备:  rtc@51 {  compatible = "nxp,pcf8563";
  • PCF8563资料中文+英文

    2020-07-30 23:31:51
    内部包含两个文件,分别是pcf8563中文手册和英文手册,pdf版本清晰好用
  • STM32驱动PCF8563,使用模拟IIC

    千次阅读 2018-06-10 12:15:25
    #ifndef PCF8563_CFG_H #define PCF8563_CFG_H ////////////////////////////////////////////////////////////////////////////////////// //------------使用包含的头文件 #include "i2c_task.h" #...
  • PCF8563

    千次阅读 2013-06-28 15:29:32
    PCF8563的读地址 0xA2,  写地址 0xA3.  地址的前7位为从器件的实际地址,最后一位表示读写R/W的方向。  PCF8563初始化的时候,参考http://hi.baidu.com/wxsidbuojoblosq/item/508c1fc6b29ac90c0bd93afe,说是...
  • PCF8563完整程序

    2020-07-30 23:31:48
    PCF8563完整程序,已在ATMEGA32单片机验证通过,并用在多个项目上,可以直接在ATMEGA32上面移植使用
  • STM32模拟IIC读取PCF8563

    千次阅读 2018-12-17 14:27:28
    作者第一次开写博客,本着学习的态度,附上自己总结的代码,...PCF8563 的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。是一款性价比极高的...
  • [DIY]STM8S003的实时时钟[PCF8563]与红外进出门提醒器总体设计1.基础硬件DIY设计1).整体原理图:2).外部RTC[PCF8563]电路3).PCB电路4).3D_PCB2.单片机程序设计1)PCF8563 I2C通信程序2)main函数逻辑 [OLED的...
  • 修改linux内核3.2.0 的 rtc 驱动 rtc-pcf8563.c (源码位置: drivers/rtc), 实现 i2c 驱动层平台设备的动态生成, 而无需在板级初始化中注册 i2c 设备 资源包含两个文件: rtc-pcf8563.c 和 rtc-pcf8563内核源码.c, ...
  • 本文的RTC使用I2C接口操作pcf8563,这里针对pcf8563对Linux的RTC框架进行分析。  Linux常见的驱动在driver目录下都有一个文件夹,进入kernel主目录下的drivers/rtc,发现下面包含了许多芯片的RTC驱动,我们这里是...
  • stm32用IIC驱动PCF8563时钟芯片的程序,内附涉及到的延时函数,包括所有的宏定义,和PCF8563-CN芯片的中文手册PCF8563是低功耗的CMOS实时时钟/日历芯片,它提供一个可编程时钟输出,一个中断输出和掉电检测器,所有...
  • 基于PCF8563的电子时钟设计,原理图
  • PCF8563驱动程序(I2C)

    2020-07-30 23:31:54
    模拟I2C写入读取时钟芯片PCF8563中的日期时间 ,不包括定时中断和报警
  • STM32 PCF8563 时钟芯片

    2020-07-29 14:20:04
    stm32驱动PCF8563时钟芯片代码
1 2 3 4 5 ... 20
收藏数 554
精华内容 221
关键字:

pcf8563