PCF8563时钟芯片驱动程序分享

电子说

1.2w人已加入

描述

  PCF8563时钟芯片简介

  PCF8563是PHILIPS公司推出的一款工业级内含I2C总线接口功能的具有极低功耗的多功能时钟/日历芯片。PCF8563的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。内部时钟电路、内部振荡电路、内部低电压检测电路(1.0V)以及两线制I2C总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性。同时每次读写数据后,内嵌的字地址寄存器会自动产生增量。当然作为时钟芯片,PCF8563亦解决了2000年问题。因而,PCF8563是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。

  PCF8563芯片主要电气特性

  1)大工作电压范围:1.0~5.5V

  2)400KHz 的 I2C 总线接口(VDD=1.8~5.5V 时)。

PCF8563

  时钟频率最大400KH

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

  PCF8563时钟芯片驱动程序

  //******************************************************

  //define

  //*****************************************************

  #define PCF8563_ADDR 0xa2 // PCF8563设备地址

  #define PCF8563_ENABLE 0x00 // 设置

  #define PCF8563_SUBADDR 0x02 // 时间地址

  #define PCF8563_NUMB 0x07 // 时间个数

  #define PCF8563_LOOPTIME 0x02 // 循环次数

  #define PCF8563_SECMASK 0x7f // second

  #define PCF8563_MINMASK 0x7f // minute

  #define PCF8563_HRMASK 0x3f // hour

  #define PCF8563_DAYMASK 0x3f // day

  #define PCF8563_WKMASK 0x07 // week

  #define PCF8563_MOMASK 0x1f // month

  #define PCF8563_YRMASK 0xff // year

  *

  void DELAY_US(Uint16 i)

  { Uint16 m,n;

  for(m=0;m《i;m++)

  {

  for(n=0;n《5;n++)

  {

  _nop_();

  }

  }

  } */

  /********************************************************

  ** 函数名称: void DELAY_MS(Uint16 i)

  ** 功能描述: 延时函数

  ** 输 入:延时毫秒数

  ** 输 出:无

  ********************************************************/

  //延时函数单位ms

  void DELAY_MS(Uint16 i)

  { Uint16 m,n; for(m=0;m《i;m++)

  {

  for(n=0;n《1000;n++)

  {

  _nop_();

  }

  }

  }

  ********************************************************

  ** 函数名称: InitCrt()

  ** 功能描述: SD2405的初始化

  ** 输 入:无 ** 输 出:无

  ********************************************************/

  void InitCrt() { //设备地址

  I2cDeviceAdd = PCF8563_ADDR; }

  /********************************************************

  ** 函数名称: CrtGetDateTime(struct SYSTEM_TIME *Time)

  ** 功能描述: 读取时间

  ** 说 明:将从PCF8563中读取的时间放入Time指向的结构中

  ** 输 入:无

  ** 输 出:无

  ********************************************************/

  void CrtGetDateTime(struct SYSTEM_TIME *Time) {

  Uint8 buf[8]; //设备地址

  I2cDeviceAdd = PCF8563_ADDR;

  SM_Receive (PCF8563_SUBADDR , buf, PCF8563_NUMB);

  Time-》time.ucSecond = buf[0]; //秒

  Time-》time.ucMinute = buf[1]; //分

  Time-》time.ucHour = buf[2]; //时

  屏蔽最高位 Time-》date.ucDay = buf[3]; //日

  Time-》Week = buf[4]; //星期 Time-》date.ucMonth = buf[5]; //月

  Time-》date.ucYear = buf[6]; //年

  }

  /******************************************************** ** 函数名称: CrtSetDateTime(struct SYSTEM_TIME *Time) ** 功能描述: 设置时间

  ** 说 明:将Time指向的结构中日期时间参数设置到sd24.5中

  ** 输 入:无 ** 输 出:无

  ********************************************************/

  void CrtSetDateTime(struct SYSTEM_TIME *Time)

  {

  Uint8 buf[8]; //设备地址

  I2cDeviceAdd = PCF8563_ADDR;

  //写入设置(时钟工作、关闭复位、关闭测试模式)

  buf[0] = PCF8563_ENABLE;

  SM_Send (0, buf, 0);

  //写入日期时间 buf[0] = Time-》time.ucSecond; //秒

  buf[1] = Time-》time.ucMinute; //分

  buf[2] = Time-》time.ucHour|0x80; //时 置为24小时格式

  buf[3] = Time-》date.ucDay; //日

  buf[4] = Time-》Week; //星期

  buf[5] = Time-》date.ucMonth; //月

  buf[6] = Time-》date.ucYear; //年

  SM_Send (PCF8563_SUBADDR, buf, PCF8563_NUMB);

  }

  4 新华龙C8051F022的IIC驱动程序

  //----------------------------------------------------------------------------- // Includes

  //-----------------------------------------------------------------------------

  #include 《c8051f020.h》 // SFR declarations #include 《stdio.h》

  #include 《king.h》

  #include 《DYSJ.h》

  #include 《I2C.H》

  #define SMB_FREQUENCY 10000L // Target SCL clock rate

  /******************************************************************************

  ** 函数名称:void SPI0_Init()

  ** 功能描述:I2C初始化程序

  ** 说 明:

  1. 置下降沿有效

  2. 置工作时钟2MHz

  3.

  ** 输 入:无

  ** 输 出:无

  *******************************************************************************/

  void I2C_Init() { SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge cycle

  SMB0CR = -80; //257 - (SYSCLK / (2 * SMB_FREQUENCY));

  EIE1 |= 2; // SMBus interrupt enable

  // EA = 1; // Global interrupt enable

  I2cSM_BUSY = 0; // Free SMBus for first transfer.

  }

  /******************************************************************************

  ** 函数名称:void SM_Send (Uint8 byte_address,Uint8 *SendBuf,Uint8 count)

  ** 功能描述:I2C写入程序

  ** 说 明:

  1. 等待空闲

  2. 写入数据

  3. 等待结束

  ** 输 入:地址byte_address、写入数据缓冲区*SendBuf、数量count

  ** 输 出:无

  *******************************************************************************/

  void SM_Send (Uint8 byte_address,Uint8 *SendBuf,Uint8 count)

  {

  ET0 = 0; //禁止中断

  ET2 = 0; //禁止中断

  while (I2cSM_BUSY); // 等待空闲

  I2cSM_BUSY = 1; // 置忙

  SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle

  I2cSendCount = count; // 置写入数量

  I2cRecCount = 0; // 读出数量清零

  I2cSendDPTR = SendBuf; // SMBus enabled, ACK on acknowledge cycle

  I2CWRITE; // Chip select + WRITE

  I2cMemAdd = byte_address;

  STO = 0;

  STA = 1; // 启动传输

  FeedWatchdog(); while (I2cSM_BUSY); // 等待空闲

  ET0 = 1; //允许中断

  ET2 = 1; //允许中断

  ******************************************************************************

  ** 函数名称:void SM_Receive (Uint8 byte_address,Uint8 *ReadBuf,Uint8 count)

  ** 功能描述:I2C读取程序

  ** 说 明:

  1. 等待空闲

  2. 置地址

  3. 读取数据

  3. 等待结束

  ** 输 入:地址byte_address、读取数据缓冲区*SendBuf、数量count

  ** 输 出:无

  *******************************************************************************

  /

  void SM_Receive (Uint8 byte_address,Uint8 *ReadBuf,Uint8 count)

  {

  ET0 = 0; //禁止中断

  ET2 = 0; //禁止中断

  while (I2cSM_BUSY); // 等待空闲

  I2cSM_BUSY = 1; // 置忙

  SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle

  I2cSendCount = 0; // 置写入数量

  I2CWRITE; // Chip select + WRITE

  I2cMemAdd = byte_address; //值地址偏移

  I2cRecCount = count; //要接收的数据个数

  I2cRecDPTR = ReadBuf; //指向要接收的数据区

  STO = 0;

  STA = 1; // Start transfer

  FeedWatchdog();

  while (I2cSM_BUSY); // 等待空闲

  ET0 = 1; //允许中断

  ET2 = 1; //允许中断

  }

  /******************************************************************************

  ** 函数名称:void SMBUS_ISR (void) interrupt 7

  ** 功能描述:I2C中断服务程序

  ** 说 明:

  1. 选择器件地址

  2. 置读写地址

  3. 读取或写入数据

  3. 置结束标志

  ** 输 入:无

  ** 输 出:无

  *******************************************************************************

  /

  void SMBUS_ISR (void) interrupt 7

  {

  switch (SMB0STA) // Status code for the SMBus (SMB0STA register)

  {

  // 主发送器/接收器:起始条件已发送

  // 在该状态发送的COMMAND 字的R/W 位总是为0(W),

  // 因为对于读和写操作来说都必须先写存储器地址。

  case SMB_START:

  SMB0DAT = I2cCOMMAND;

  // 写入含读写指令的设备地址

  STA = 0;

  // 清除启动标志

  break;

  //主发送器/接收器:重复起始条件已发送。

  // 该状态只应在读操作期间出现,在存储器地址已发送并得到确认之后

  case SMB_RP_START:

  I2CREAD; // 置设备读

  SMB0DAT = I2cCOMMAND; // 写入含读写指令的设备地址

  STA = 0;

  break;

  // 主发送器 设备地址+(W/R)已发出。收到ACK。

  case SMB_MTADDACK:

  SMB0DAT = I2cMemAdd; // 发送要写入的字节地址

  break;

  // 主发送器 从地址+W已发出。收到NACK。

  case SMB_MTADDNACK:

  /* if (I2cSendCount) // 传输结束

  {

  SMB0DAT = *I2cSendDPTR; //传送数据

  I2cSendDPTR++;

  I2cSendCount--;

  }

  else

  { if(I2cRecCount)

  {

  STO = 0;

  STA = 1;

  }

  else

  {

  STO = 1

  I2cSM_BUSY = 0; //发送停止,释放总线

  }

  }*/

  STO = 1;

  STA = 1;

  break;

  // 数据字节已经发出,收到ACK

  case SMB_MTDBACK:

  if (I2cSendCount) // 传输结束

  {

  SMB0DAT = *I2cSendDPTR; //传送数据

  I2cSendDPTR++;

  I2cSendCount--;

  }

  else

  {

  if(I2cRecCount)

  { STO = 0;

  STA = 1;

  }

  else

  {

  STO = 1;

  I2cSM_BUSY = 0; //发送停止,释放总线

  } }

  break;

  // 数据字节已经发出,收到NACK

  case SMB_MTDBNACK:

  STO = 1;

  STA = 1;

  break;

  // 主发送器 竞争失败

  case SMB_MTARBLOST:

  STO = 1;

  STA = 1;

  break;

  // 从地址+R已经发出,收到ACK

  case SMB_MRADDACK:

  SysBuff[500]=8;

  //if (counter == 1) //只接收一个字节时要设置接收后就NACK

  //{

  // AA = 0;

  // NACK sent on acknowledge cycle.

  //}

  break;

  // 从地址+R已经发出,收到NACK

  case SMB_MRADDNACK:

  STO = 0;

  STA = 1;

  break; // 数据字节收到,ACK已经发出

  case SMB_MRDBACK:

  if (I2cRecCount == 1)

  {

  AA = 0;

  // 收到最后一个字节前准备设置最后一个字节不应答

  }

  I2cRecCount--;

  *I2cRecDPTR = SMB0DAT;

  I2cRecDPTR++;

  break;

  // 数据字节收到,NACK已经发出

  case SMB_MRDBNACK:

  *I2cRecDPTR = SMB0DAT;

  STO = 1;

  I2cSM_BUSY = 0; // Free SMBus

  break;

  // 未知状态或总线错误

  default:

  STO = 1; // Reset communication.

  I2cSM_BUSY = 0;

  break;

  }

  SI=0; // clear interrupt flag

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
luowuping597 02-15
0 回复 举报
正好在做一个基于8563的时钟,参考学习一下,谢谢楼主分享! 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分