打印

PCF8563不稳定

[复制链接]
7398|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 shuibaihe0506 于 2015-8-5 14:05 编辑

1.现象:时钟芯片有时通信正常,有时无应答(示波器查应答管脚一直为高电平,检测不到低电平),原来测试正常的片子隔一段时间后不正常了,再重新操作有可能又恢复正常

3.一般情况下如芯片出现异常采取以下措施:
1)重新焊接芯片一般可以恢复正常,个别情况下需要把芯片焊下来重新焊接,当时可以正常使用,过一段时间后又不正常了

2)补焊晶振和匹配电容,

3)更换备用电池,

4)匹配电容原来用的是15PF,后来更换为9pf,仍然有上述现象

以上措施仅能使芯片当时恢复正常,隔一段时间后又有故障出现

驱动程序我看过了,没有问题,如果有问题的话补焊应该也不会起作用,到底是哪里出现问题了呢?求高手指点


程序
:/*****************************************************************/
/*文件名:PCF8563IIC.c
*整体描述:单片机硬件IIC软件,字节方式,主方式
*          IIC接口:
*作者:
*状态:  通过
*****************************************************************/
#include "pcf8563.h"
#include "stm32f10x_lib.h"

/*-----------------/////////////////设置时间//////////////////-----------------------------*/

uint8 RTCSet(void)
{

  if(!RTCWriteByte(0x08,Hex2Dcb(SysTime.Year[0])))  return 2;
  if(!RTCWriteByte(0x07,Hex2Dcb(SysTime.Month)))  return 2;
  if(!RTCWriteByte(0x05,Hex2Dcb(SysTime.Date)))    return 2;
  if(!RTCWriteByte(0x02,Hex2Dcb(SysTime.Second)))  return 2;
  if(!RTCWriteByte(0x03,Hex2Dcb(SysTime.Minute)))  return 2;
  if(!RTCWriteByte(0x04,Hex2Dcb(SysTime.Hour)))    return 2;

  if(!RTCWriteByte(0x00,0)) return 2;
  if(!RTCWriteByte(0x01,0x12)) return 2;//SET THE CONTROL AND STATUS REGISTER2

  return 1;
}
/*------------------------------------------------------------
FUNC        :
PARA        :
RETRUN      :
PARA DESCRI :
status      : OK
data        : 2005.09.07
COPYRIGHT   : BITTYPHOON .BJKCSS
-------------------------------------------------------------*/

void RTCinitI2c(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
  GPIO_InitStructure.GPIO_Pin =  RTC_SDA_PIN | RTC_SCL_PIN ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_RTC_DET, &GPIO_InitStructure);


}
void RTC_SDA_IN(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStruct.GPIO_Pin = RTC_SDA_PIN;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  /*这里一定要设成输入上拉,否则不能读出数据*/
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init( GPIOB, &GPIO_InitStruct );
}
void RTC_SDA_OUT(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
  GPIO_InitStruct.GPIO_Pin = RTC_SDA_PIN;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init( GPIOB, &GPIO_InitStruct );
}



/*-------------------------------------------------------------
FUNC        : write a Byte to the register or register of pcf8653
PARA        : unsigned char RTCRegAddr,unsigned char data
RETRUN      : NO
PARA DESCRI : RTCRegAddr, the addr of pcf8653 register ;
              data: data to be writed
status      : OK
data        :
COPYRIGHT   :
-------------------------------------------------------------*/
uint8  RTCWriteByte(unsigned char RTCRegAddr,unsigned char  data)
{

  RTCI2cStart();
  if(!RTCI2cSendOneByte(0xA2)) return 0;
  if(!RTCI2cSendOneByte(RTCRegAddr)) return 0;
  if(!RTCI2cSendOneByte(data))return 0;
  RTCI2cStop();
  return 1;
}


/*------------------------------------------------------------
FUNC        : read a data from the register of pcf8653
PARA        : unsigned char RTCRegAddr
RETRUN      : unsigned char data
PARA DESCRI : data; data read from the pcf8653 register
status      :
data        :
COPYRIGHT   :
-------------------------------------------------------------*/
uint8 RTCReadByte(uint8 RTCRegAddr)
{
  uint8 d_read=0;
  RTCI2cStart();
  RTCI2cSendOneByte(0xa2);
  RTCI2cSendOneByte(RTCRegAddr);  
  RTCI2cStart();
  RTCI2cSendOneByte(0xA3);
  d_read=RTCI2cReceiveOneByte();
  RTCI2cAckSend(1);
  Delay(DELAY_TIME);
  RTCI2cStop();
  return(d_read);
}


/*------------------------------------------------------------
FUNC        : produce the start signal for the i2c bus
PARA        :
RETRUN      :
PARA DESCRI :
status      : OK
data        :
COPYRIGHT   :
-------------------------------------------------------------*/
void RTCI2cStart(void)
{
  RTCinitI2c();
  RTC_SDA_1;

  RTC_SCL_1;
  Delay(DELAY_TIME);
  RTC_SDA_0;
  Delay(DELAY_TIME);
  RTC_SCL_0;
}
/*-----------------------------------------------------------
FUNC        : i2c bus stop signal produce module
PARA        : NO
PARA DESCRI : NO
status      : OK
data        :
COPYRIGHT   :
--------------------------------------------------------------*/
void RTCI2cStop(void)
{
  RTC_SDA_OUT();
  RTC_SDA_0;
  RTC_SCL_1;
  Delay(DELAY_TIME);
  RTC_SDA_1;
  Delay(DELAY_TIME);
}
/*------------------------------------------------------------
FUNC        : send one byte to the i2c bus
PARA        : unsigned char data
RETRUN      : NO
PARA DESCRI : data; data sent to the i2c bus
status      : OK
data        :
COPYRIGHT   :
-----------------------------------------------------------*/
uint8  RTCI2cSendOneByte(unsigned char data)
{
  char i=0;
  RTC_SDA_OUT();
  for(i=8;i>0;i--)
  {
    if(((data>>(i-1))&0x1)==0x1)
      GPIO_SetBits  ( GPIO_RTC_DET, RTC_SDA_PIN );
    else
      GPIO_ResetBits( GPIO_RTC_DET, RTC_SDA_PIN );
    Delay(DELAY_TIME);
    RTC_SCL_1;
    Delay(DELAY_TIME);
    RTC_SCL_0;
    Delay(DELAY_TIME);
  }

  return RTCI2cAckCheck();
}
/*------------------------------------------------------------
FUNC        : read a data from the i2c bus
PARA        : no
RETRUN      : unsigned char data
PARA DESCRI : data; data read from the i2c bus
status      : OK!
data        :
COPYRIGHT   :
-----------------------------------------------------------*/
uint8 RTCI2cReceiveOneByte(void)
{
  uint8 i=0;
  uint8 data_1=0;
  RTC_SDA_IN();
   for(i=0;i<8;i++)
  {
    RTC_SCL_1;
    Delay(DELAY_TIME);
    data_1 |= ((GET_SDA_IN())<<(7-i));
    Delay(DELAY_TIME);
    RTC_SCL_0;
    Delay(DELAY_TIME);
  }

  return(data_1);
}


uint8 GET_SDA_IN(void)
{
  if(GPIO_ReadInputDataBit( GPIOB, RTC_SDA_PIN ))
    return 1;
  else
    return 0;
}
/*--------------------------------------------------------------
FUNC        : check the ack signal of slave i2c device
PARA        : no
RETRUN      : no
PARA DESCRI :
status      : OK!
data        : 2005.07.12
COPYRIGHT   : BITTYPHOON .BJKCSS
---------------------------------------------------------------*/
uint8 RTCI2cAckCheck(void)
{
  uint16 nError=0x7FFF;
  RTC_SDA_IN();
  RTC_SCL_1;
  Delay(DELAY_TIME);//
  while(GET_SDA_IN() ==1)//
  {
    nError--;
    if(nError==0)  {break;  }
  }
  if(GET_SDA_IN() == 1)
    nError = 0;
  else
    nError = 0x7fff;
  RTC_SCL_0;
  Delay(DELAY_TIME);
  if(nError==0)  
    return NO;
  else
    return YES;
}
/*--------------------------------------------------------------
FUNC        : check the ack signal of slave i2c device
PARA        : no
RETRUN      : no
PARA DESCRI :
status      : OK!
data        :
COPYRIGHT   :
---------------------------------------------------------------*/
void RTCI2cAckSend(uint8 AckData)
{

  RTC_SDA_OUT();
  if(AckData==1)  
    GPIO_SetBits  ( GPIO_RTC_DET, RTC_SDA_PIN );
  else
    if(AckData==0)
       GPIO_ResetBits  ( GPIO_RTC_DET, RTC_SDA_PIN );

  Delay(DELAY_TIME);
  RTC_SCL_1;
  Delay(DELAY_TIME);
  RTC_SCL_0;
}

uint8 Dec2Hex(uint8 dec)
{
  uint8 temp0;
  temp0 = (dec >> 4) *10;
  dec &= 0x0f;
  dec += temp0;
  return dec;
}

uint8 Hex2Dcb(uint8 hex)
{
  uint8 dcb;
  dcb =((hex/10)<<4)+(hex%10);
  return dcb;
}

void Delay(uint16 DelayTime)
{
  uint16 i;
  for (i = 0; i < DelayTime; i++)
  {
  }
}


相关帖子

沙发
gx_huang| | 2015-8-5 13:31 | 只看该作者
PCB太脏了,漏电,焊接问题。换正宗的芯片。

使用特权

评论回复
板凳
ayb_ice| | 2015-8-5 13:33 | 只看该作者
如果不是假货
还是怀疑程序吧,这芯片我好多项目都用的

使用特权

评论回复
地板
lfc315| | 2015-8-5 13:38 | 只看该作者
原理图 PCB 实物,一个都没看到,不好说

使用特权

评论回复
5
shuibaihe0506|  楼主 | 2015-8-5 13:43 | 只看该作者
gx_huang 发表于 2015-8-5 13:31
PCB太脏了,漏电,焊接问题。换正宗的芯片。

芯片是正品,反复补焊过焊接没有问题,绝大部分补焊可以短时间内恢复正常工作,时间长了故障又出现了

使用特权

评论回复
6
gx_huang| | 2015-8-5 13:48 | 只看该作者
所以,要贴出原理图和程序,一一排除了。
无非就是电源、晶体、I2C。

使用特权

评论回复
7
shuibaihe0506|  楼主 | 2015-8-5 14:08 | 只看该作者
gx_huang 发表于 2015-8-5 13:48
所以,要贴出原理图和程序,一一排除了。
无非就是电源、晶体、I2C。

这个电路在别的电路板上应用时,没有出现过这种问题,这次的布件由于空间的限制,晶振和芯片没在一面

使用特权

评论回复
8
lfc315| | 2015-8-5 14:09 | 只看该作者
是通信不上,还是时间走错了,还是两者都有?

使用特权

评论回复
9
shuibaihe0506|  楼主 | 2015-8-5 14:16 | 只看该作者
lfc315 发表于 2015-8-5 14:09
是通信不上,还是时间走错了,还是两者都有?

通信不上,芯片没有应答,正常时:晶振两脚对地电压分别是0.45V,0.05V,出现异常时:0.52V,0.38V

使用特权

评论回复
10
lfc315| | 2015-8-5 14:23 | 只看该作者
看来是停振了?

使用特权

评论回复
11
shuibaihe0506|  楼主 | 2015-8-5 14:36 | 只看该作者
lfc315 发表于 2015-8-5 14:23
看来是停振了?

示波器看不到波形,确实停振了,最初按照晶振起振不稳定来处理,晶振外壳接地,更换小的匹配电容都不行,还有什么原因会引起这种不稳定的现象呢?

使用特权

评论回复
12
lfc315| | 2015-8-5 14:50 | 只看该作者
芯片8脚对地加个电容是不是好点?
一般容易出问题的就是晶振,不同厂家的可能激励功率不一样;要是原来处于勉强满足状态,现在布板什么的稍变化可能就出问题了;
另外看看芯片手册,有没有要特别注意的地方。
另外这个芯片好像有国产仿造的,别买到假货了。

使用特权

评论回复
13
ningling_21| | 2015-8-5 15:04 | 只看该作者
IIC总线上拉电阻100K太大,换成4.7K试试

使用特权

评论回复
14
jjjyufan| | 2015-8-5 15:15 | 只看该作者
我也觉得100k 太大了 驱动不正常
换10k 另外 10R 也大了点 再并个10R 试试

使用特权

评论回复
15
shuibaihe0506|  楼主 | 2015-8-5 15:27 | 只看该作者
jjjyufan 发表于 2015-8-5 15:15
我也觉得100k 太大了 驱动不正常
换10k 另外 10R 也大了点 再并个10R 试试

晶振不起振所以驱动不正常,还是驱动不正常所以晶振不起振,应该是前者吧,现在测得的现象是每次出现问题的时候晶振都没有起振,那应该不是驱动的问题吧

使用特权

评论回复
16
lfc315| | 2015-8-5 15:29 | 只看该作者
上拉电阻值,看每个引脚的功能来定,看看IIC波形就知道上拉是不是合适了;

使用特权

评论回复
17
lfc315| | 2015-8-5 15:38 | 只看该作者
shuibaihe0506 发表于 2015-8-5 15:27
晶振不起振所以驱动不正常,还是驱动不正常所以晶振不起振,应该是前者吧,现在测得的现象是每次出现问题 ...

这个原因难说,两种可能性都有吧;
1。通讯不正常,导致配置芯片设置信息时出错,芯片时钟有没有可能不工作不起振?
2。不起振时,芯片内部会不会因为没有时钟而不工作?
是哪种情况,要看芯片内部相关部分是怎么设计的;
其实很多时候问一下芯片厂家的技术支持就解决了。

使用特权

评论回复
18
51soho| | 2015-8-5 16:17 | 只看该作者
8脚加个对地0.1uf电容.
2脚加一个对地15pf电容
上拉电阻根据波形来定.

使用特权

评论回复
19
songchenping| | 2015-8-5 17:07 | 只看该作者
对于楼主的画图功力真是不敢恭维啊。

使用特权

评论回复
20
lfc315| | 2015-8-5 17:10 | 只看该作者
51soho 发表于 2015-8-5 16:17
8脚加个对地0.1uf电容.
2脚加一个对地15pf电容
上拉电阻根据波形来定.

印象中,这个芯片是只需要外接1个电容的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝