你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f030c8 读pcf8563

[复制链接]
songwei2030 提问时间:2015-7-22 09:08 /
用stm32f030c8硬件iic 读pcf8563 实时时钟,在初步调试的时候就出现了问题,每次过8s就会week month数据就变了,很有规律,没找出什么原因,求助啊

下面是程序,希望大家给予指正,谢谢。


/*********************************************************************************
Function   : InitializeI2cGpio
Description: 初始化i2c的GPIO
Input      : 无
Output     : 无
Return     : 无
Others     :  
*********************************************************************************/
static bool InitializeI2cGpio ( unsigned char type )
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    if( type >= I2Cn )
        return false;

    /* Enable SCK and SDA GPIO clocks */
    RCC_AHBPeriphClockCmd(ST_I2C_CLK_GPIO_CLK_TABLE[type] | ST_I2C_SDA_GPIO_CLK_TABLE[type] , ENABLE);

    GPIO_PinAFConfig(ST_I2C_CLK_GPIO_PORT_TABLE[type], ST_I2C_CLK_SOURCE_TABLE[type], ST_I2C_CLK_AF_TABLE[type]);
    GPIO_PinAFConfig(ST_I2C_SDA_GPIO_PORT_TABLE[type], ST_I2C_SDA_SOURCE_TABLE[type], ST_I2C_SDA_AF_TABLE[type]);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;//sw
   // GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    /* I2C SCK pin configuration */
    GPIO_InitStructure.GPIO_Pin = ST_I2C_CLK_PIN_TABLE[type];
    GPIO_Init(ST_I2C_CLK_GPIO_PORT_TABLE[type], &GPIO_InitStructure);

    /* I2C SDA pin configuration */
    GPIO_InitStructure.GPIO_Pin = ST_I2C_SDA_PIN_TABLE[type];
    GPIO_Init(ST_I2C_SDA_GPIO_PORT_TABLE[type], &GPIO_InitStructure);

    return true;
}

/*********************************************************************************
Function   : InitializeI2cConfig
Description: 初始化硬件I2C配置
Input      : clock = true 8M_400k false 8M_100k
Output     : 无
Return     : 无
Others     :
*********************************************************************************/
static bool InitializeI2cConfig ( unsigned char type ,bool clock )
{
    I2C_InitTypeDef   I2C_InitStructure;

    if( type >= I2Cn )
        return false;

   /* Enable the I2C periph source*/
   // RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
    RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);//48MHZSW
    RCC_APB1PeriphClockCmd(ST_I2C_CLK_TABLE[type], ENABLE); //Enable I2C1 Clock
    //初始I2C时钟 SW
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
    I2C_InitStructure.I2C_DigitalFilter = 0x00;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    if( clock )
       // I2C_InitStructure.I2C_Timing = EE_I2C_8MHZ_400KHZ_TIMING;//晶振修改为8MHZ sw
          I2C_InitStructure.I2C_Timing =  0x30E32E44;//0x00A0184D;//48M-400K
    else
        I2C_InitStructure.I2C_Timing = EE_I2C_8MHZ_100KHZ_TIMING;

    I2C_Init(ST_I2C_TABLE[type], &I2C_InitStructure);

    I2C_Cmd(ST_I2C_TABLE[type], ENABLE);

    return true;
}

*********************************************************************************
Function   : InitializeI2c
Description: 初始化i2c
Input      : 无
Output     : 无
Return     : 无
Others     :  
*********************************************************************************/
void  InitializeI2c ( bool clock )
{
    for(unsigned char i=0;i<I2Cn;i++)
    {

       InitializeI2cGpio(i);
       InitializeI2cConfig(i , clock );

    }
}

上面是初始化硬件IIC,剩下的会在下面跟上
收藏 评论6 发布时间:2015-7-22 09:08

举报

6个回答
songwei2030 回答时间:2015-7-22 09:09:00
*******************************************************************************
Function   : I2CDeviceRecv
Description: I2C主机接收数据
Input      : 无
Output     : 无
Return     : 无
Others     :  
*******************************************************************************/
unsigned char I2CDeviceRecv( struct t_iic_device *p_device )
{  
    uint32_t timeout = 0;
    uint32_t data_num;
    unsigned char  data;
   
    I2C_LOSE_POWE_HANDLE();
   
    if (( p_device->reg_len == 0) || ( p_device->data_len == 0))
        return I2C_OPERATE_FAIL ;
   
    if ( p_device->reg_len > 4 )
        return I2C_OPERATE_FAIL ;
   
    add_index  = p_device->reg_len;
    data_index = 0;
   
    /* Test on BUSY Flag */
    timeout = E2PROM_LONG_TIMEOUT;
    while( I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_BUSY) != RESET )
    {
        //操作前先喂狗
        FeedIWDG();
        FeedOSWDG();
        I2C_LOSE_POWE_HANDLE();
        if((timeout--) == 0)
            return I2C_OPERATE_FAIL;
    }
   
    /* Configure slave address, nbytes, reload and generate start */
    I2C_TransferHandling(p_device->iic_base, p_device->dev_addr, p_device->reg_len, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
   
    /* Wait until TXIS flag is set */
    timeout = E2PROM_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_TXIS) == RESET)
    {
        //操作前先喂狗
        FeedIWDG();
        FeedOSWDG();
        I2C_LOSE_POWE_HANDLE();
        if((timeout--) == 0)
            return I2C_OPERATE_FAIL;
    }
   
    /* Send memory address */
    while( add_index )
    {
        I2C_SendData( p_device->iic_base , p_device->p_reg_addr[add_index-1] );
        add_index--;
        
        if( add_index == 0 )
        {
            /* Wait until TC flag is set */
            timeout = E2PROM_LONG_TIMEOUT;
            while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_TC) == RESET)
            {
                //操作前先喂狗
                FeedIWDG();
                FeedOSWDG();
                I2C_LOSE_POWE_HANDLE();
                if((timeout--) == 0)
                    return I2C_OPERATE_FAIL;
            }
        }
        else
        {
            /* Wait until TC flag is set */
            timeout = E2PROM_LONG_TIMEOUT;
            while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_TXIS) == RESET)
            {
                //操作前先喂狗
                FeedIWDG();
                FeedOSWDG();
                I2C_LOSE_POWE_HANDLE();
                if((timeout--) == 0)
                    return I2C_OPERATE_FAIL;
            }
        }
    }
   
    data_num   = (p_device->data_len)/255;
    data = (p_device->data_len)%255;
    while( data_num )
    {
        data_index = 255;        
        /* Configure slave address, nbytes, reload, end mode and start or stop generation */
        I2C_TransferHandling(p_device->iic_base, p_device->dev_addr, data_index, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
        
        /* Wait until all data are received */
        while ( data_index )
        {
            /* Wait until RXNE flag is set */
            timeout = E2PROM_LONG_TIMEOUT;
            while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_RXNE) == RESET)   
            {
                //操作前先喂狗
                FeedIWDG();
                FeedOSWDG();
                I2C_LOSE_POWE_HANDLE();
                if((timeout--) == 0)
                    return I2C_OPERATE_FAIL;
            }
            
            /* Read data from RXDR */
            *(p_device->p_data) = I2C_ReceiveData(p_device->iic_base);
            /* Point to the next location where the byte read will be saved */
            (p_device->p_data)++;
            
            /* Decrement the read bytes counter */
            data_index--;
        }
        data_num--;        
    }
   
    data_index = data;
    if( data_index !=0 )
    {
        /* Configure slave address, nbytes, reload, end mode and start or stop generation */
        I2C_TransferHandling(p_device->iic_base, p_device->dev_addr, (unsigned char)data_index, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
        
        /* Wait until all data are received */
        while ( data_index )
        {   
            /* Wait until RXNE flag is set */
            timeout = E2PROM_LONG_TIMEOUT;
            while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_RXNE) == RESET)   
            {
                //操作前先喂狗
                FeedIWDG();
                FeedOSWDG();
                I2C_LOSE_POWE_HANDLE();
                if((timeout--) == 0)
                    return I2C_OPERATE_FAIL;
            }
            
            /* Read data from RXDR */
            *(p_device->p_data) = I2C_ReceiveData(p_device->iic_base);
            /* Point to the next location where the byte read will be saved */
            (p_device->p_data)++;
            
            /* Decrement the read bytes counter */
            data_index--;
        }
    }   
   
   
    /* Wait until STOPF flag is set */
    timeout = E2PROM_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(p_device->iic_base, I2C_ISR_STOPF) == RESET)   
    {
        //操作前先喂狗
        FeedIWDG();
        FeedOSWDG();
        I2C_LOSE_POWE_HANDLE();
        if((timeout--) == 0)
            return I2C_OPERATE_FAIL;
    }
   
    /* Clear STOPF flag */
    I2C_ClearFlag(p_device->iic_base, I2C_ICR_STOPCF);
   
    /* If all operations OK */
    return I2C_OPERATE_SUCC;
}
songwei2030 回答时间:2015-7-22 09:10:05
RTC时钟的初始化
void InitializeTimerManage( void )
{
   unsigned char config1 = 0x00;
                                  /*reg_ctrl1
                                          STOP = 0;SW*/
   unsigned char config2 = 0x01;
                                        /*Reg_ctrl2
                                            AIE = 0;
                                            TIE = 1;
                                          TI/TP = 0; SW */
   unsigned char timer1 = 0x82;     /*reg_timer
                                     TE = 1
                                     tiemr source clock  = 1 hz*/
   
    unsigned week ;
    struct t_rtc_time time ;
    struct t_date* p_data   = ( struct t_date* )(&(time.week)) ;
    struct t_clock* p_clock = ( struct t_clock* )(&(time.sec)) ;
    WritePCF8563( PCF8563_REG_CTRL1 , 1 , &config1); //使能RTC
    ReadPCF8563( PCF8563_REG_CTRL1 , 1 , &config1);   
    WritePCF8563( PCF8563_REG_CTRL2 , 1 , &config2);  //使能AIE TIEsw
    ReadPCF8563( PCF8563_REG_CTRL2 , 1 , &config2);
    WritePCF8563(PCF8563_TIME_CTRL , 1 , &timer1);
     ReadPCF8563(PCF8563_TIME_CTRL , 1 , &timer1);
    //读取成功
    if( ReadRTCTime( (unsigned char*)&time ) )
    {      
        
            memcpy( &time , &const_rtc_time , sizeof(struct t_rtc_time) );
  
        WriteRTCTime( (unsigned char*)&time );  
        ReadRTCTime ( (unsigned char*)&time );
        time.week = week ;
        
        memcpy( &current_time , &time , sizeof( struct t_rtc_time ) ) ;
  
    }
}
songwei2030 回答时间:2015-7-22 09:12:25
这个是我验证pcf8563时做的代码验证
bool ReadPCF8563( uint32_t offset , uint32_t len , unsigned char* p_data )
{  
   
    unsigned char  reg_add ,loop  = 3;
    unsigned char  result = false;

    while( loop-- )
    {
        //读取失败
       //if ( I2CDeviceRecv( &iic_deviece ) )
         if (I2C1_Read_NBytes(PCF8563_I2C_ADDR_READ, 0x02, 7, p_data));
      
        {
            result = true;
            break;
        }
    }

    return result;
}
stary666 回答时间:2015-7-22 09:25:42
之前用过1768读写8563
songwei2030 回答时间:2015-7-22 09:43:35
stary666 发表于 2015-7-22 09:25
之前用过1768读写8563

能不能把你的代码发给我,谢谢978821301@qq.com
stary666 回答时间:2015-7-22 12:21:30
公司不能上QQ

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版