用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,剩下的会在下面跟上 |
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;
}
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( ¤t_time , &time , sizeof( struct t_rtc_time ) ) ;
}
}
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;
}
能不能把你的代码发给我,谢谢978821301@qq.com