一、芯片及I2C初始化

        英集芯IP2366,封装QFN40,集成AFC/FCP/PD2.0/PD3.0/PD3.1输入快充协议,可以通过Type-C口上的DPC/DMC/CC1/CC2向快充适配器申请快充电压,会自动调节充电电流大小,来适应不同负载能力的适配器。输入输出快充协议和同步升降压转换器的锂电池充放电管理芯片,充放电功率高达140W。

       IP2366的高集成度与丰富功能,只需一个电感实现同步降升压功能,在应用时仅需极少的外围器件,有效减小整体方案的尺寸,降低BOM成本。

        IP2366可以定制设置不同的电池类型、充满电压和充电电流,可以支持2/3/4/5/6串磷酸铁锂或锂电池充电。

        IP2366的同步开关充放电系统,最大充电电流可达5A或100W充电输入,充电效率最高到96%,放电功率高达140W,可通过定制设置最大充放电功率。

         IP2366内置IC温度、电池 NTC温度和输入电压控制检测环路,可以根据不同功率充电器,智能调节充电电流。

        IP2366支持低功耗模式,进入低功耗模式后,待机电流降低到5μA。进入低功耗模式后,插入充电器可自动唤醒充电,放电需要按下EN键唤醒;

        IP2366内置14bit ADC,可以精确测量充电输入电压和电流,电池电压和电流;可通过I2C获取充放电电压、充电电流等信息。

       硬件可参考其手册标准原理图即可,可硬件电阻配置其充满电压、最大功率,简单便捷:

       软件则只需简单软件I2C即可读取寄存器各数据,做好电量显示等充放电管理。

二、程序源码

ip2366.c

#include "ip2366.h"
#include "main.h"

stIP2366Data IP2366Data;
uint8_t temp_ip[5];

//  IP_SCL   PB0
//  IP_SDA	 PB1

//IP_IIC
void IP2366_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = IP_SCL_PIN | IP_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(IP_GPIO_PORT, &GPIO_InitStructure); 
    
	IP_SDA_HIGH();
	IP_SCL_HIGH();
}

void delay_us_i2c(void)
{
	uint8_t i;

	/* 
	 	下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。
		CPU主频72MHz时,在内部Flash运行, MDK工程不优化
		循环次数为10时,SCL频率 = 205KHz 
		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
        
    IAR工程编译效率高,不能设置为7
	*/
	for (i = 0; i < 21; i++);
}

void delay_50us_i2c(void)
{
	uint8_t i;

	/* 
	 	下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。
		CPU主频72MHz时,在内部Flash运行, MDK工程不优化
		循环次数为10时,SCL频率 = 205KHz 
		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
        
    IAR工程编译效率高,不能设置为7
	*/
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
	for (i = 0; i < 10; i++);
}

/*************************************************
void I2C_Start(void)
*************************************************/
void IIC2_Start(void)
{
	IP_SDA_HIGH();
	delay_us_i2c();
	IP_SCL_HIGH();
	delay_us_i2c();
	IP_SDA_LOW();
	delay_us_i2c();
	IP_SCL_LOW();
	delay_us_i2c();
}

/************************************************
void Stop_I2c(void)
*************************************************/
void IIC2_Stop(void)
{
	IP_SDA_LOW();
	delay_us_i2c();
	IP_SCL_HIGH();
	delay_us_i2c();
	IP_SDA_HIGH();
}

/**************************************************
void Send_Byte(unsigned char send)
***************************************************/
void IIC2_Send_Byte(uint8_t _ucByte)
{
 	uint8_t i;
	IP_SDA_OUT();
	/* 先发送字节的高位bit7 */
	for (i = 0; i < 8; i++)
	{		
		if (_ucByte & 0x80)
		{
			IP_SDA_HIGH();
		}
		else
		{
			IP_SDA_LOW();
		}
		delay_us_i2c();
		IP_SCL_HIGH();
		delay_us_i2c();	
		IP_SCL_LOW();
		if (i == 7)
		{
			 IP_SDA_HIGH(); // 释放总线
		}
		_ucByte <<= 1;	/* 左移一个bit */
		delay_us_i2c();
	} 
}


/**************************************************************
unsigned char Receive_Byte(void)
***************************************************************/
unsigned char IIC2_Read_Byte(void)
{
	uint8_t i;
	uint8_t value;
	IP_SDA_IN();

	/* 读到第1个bit为数据的bit7 */
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		IP_SCL_HIGH();
		delay_us_i2c();
		if (READ_IP_SDA !=0)
		{
			value++;
		}
		IP_SCL_LOW();
		delay_us_i2c();
	}
	IP_SDA_OUT();
	return value;
}

/***********************************************************************************
void Ack_I2c(void) 器件发送应答信号 ack=0非应答 ack=1应答
************************************************************************************/
void IIC2_Wait_Ack(void)
{
	IP_SDA_LOW();
	IP_SCL_HIGH();
	delay_us_i2c();
	IP_SCL_LOW();
	delay_us_i2c();
	IP_SDA_HIGH();
}

void IIC2_Wait_NoAck(void)
{
	IP_SDA_HIGH();
	IP_SCL_HIGH();
	delay_us_i2c();
	IP_SCL_LOW();
	delay_us_i2c();
}


uint8_t IP2366_ReadOneByte(uint16_t ReadAddr)
{
	uint8_t temp=0;		  	    																 
	IIC2_Start();  
	IIC2_Send_Byte(IP2366_ADR_WRITE_);
	IIC2_Wait_Ack(); 
	delay_50us_i2c();
	IIC2_Send_Byte(ReadAddr);   //发送读地址
	IIC2_Wait_Ack();	    
	delay_50us_i2c();
	IIC2_Start();  
	IIC2_Send_Byte(IP2366_ADR_READ_);
	IIC2_Wait_Ack();	 
	delay_50us_i2c();
	temp=IIC2_Read_Byte();	
	IIC2_Wait_NoAck();
	IIC2_Stop();								//产生一个停止条件	     
	return temp;
}

void IP2366_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite)
{				   	  	    																 
	IIC2_Start();  
	IIC2_Send_Byte(IP2366_ADR_WRITE_);
	IIC2_Wait_Ack();
	IIC2_Send_Byte(WriteAddr);					//发送地址
	IIC2_Wait_Ack();	   	 										  		   
	IIC2_Send_Byte(DataToWrite);     //发送字节							   
	IIC2_Wait_Ack();  		    	   
	IIC2_Stop();//产生一个停止条件 
	delay_us_i2c();	
}

unsigned int IP2366_Get_IpData(void)
{
	uint8_t flag=1;
	switch (IP2366Data.IP_Step)
	{
		case 0:
			IP2366Data.S_Bat_StateCtrl_0 = IP2366_ReadOneByte(IP2366_STATE_CTL0_);	
			IP2366Data.IP_Step = 1;
		break;	
		case 1:
			IP2366Data.S_Bat_StateCtrl_1 = IP2366_ReadOneByte(IP2366_STATE_CTL1_);	
			IP2366Data.IP_Step = 2;
		break;
		case 2:
			IP2366Data.S_Bat_StateCtrl_2 = IP2366_ReadOneByte(IP2366_STATE_CTL2_);	
			IP2366Data.IP_Step = 3;
		break;
		case 3:
			IP2366Data.V_Bat_Data0 = IP2366_ReadOneByte(IP2366_BATVADC_DAT0);	
			IP2366Data.IP_Step = 4;
		break;
		case 4:
			IP2366Data.V_Bat_Data1 = IP2366_ReadOneByte(IP2366_BATVADC_DAT1);	
			IP2366Data.IP_Step = 5;	
		break;
		case 5:
			IP2366Data.V_Sys_Data0 = IP2366_ReadOneByte(IP2366_VSYSVADC_L);	
			IP2366Data.IP_Step = 6;
		break;
		case 6:
			IP2366Data.V_Sys_Data1 = IP2366_ReadOneByte(IP2366_VSYSVADC_H);	
			IP2366Data.IP_Step = 7;
		break;
		case 7:
			IP2366Data.I_Bat_Data0 = IP2366_ReadOneByte(IP2366_IBATIADC_L);	
			IP2366Data.IP_Step = 8;
		break;
		case 8:
			IP2366Data.I_Bat_Data1 = IP2366_ReadOneByte(IP2366_IBATIADC_H);	
			IP2366Data.IP_Step = 9;
		break;
		case 9:
			IP2366Data.P_Sys_PowData0 = IP2366_ReadOneByte(IP2366_VSYS_POW_L);	
			IP2366Data.IP_Step = 10;
		break;
		case 10:
			IP2366Data.P_Sys_PowData1 = IP2366_ReadOneByte(IP2366_VSYS_POW_H);	
			IP2366Data.IP_Step = 0;
		break;
//		case 11:
//			IP2366Data.S_TypeC = IP2366_ReadOneByte(IP2366_TYPEC_STATE0);	
//			IP2366Data.IP_Step = 12;
//		break;
//		case 12:
//			IP2366Data.V_GPIO0_Data0 = IP2366_ReadOneByte(IP2366_VGPIO0_NTC_L);	
//			IP2366Data.IP_Step = 13;
//		break;
//		case 13:
//			IP2366Data.V_GPIO0_Data1 = IP2366_ReadOneByte(IP2366_VGPIO0_NTC_H);	
//			IP2366Data.IP_Step = 14;
//		break;
//		case 14:
//			IP2366Data.T_TimeNode1 = IP2366_ReadOneByte(IP2366_TIMENODE1);	
//			IP2366Data.IP_Step = 15;
//		break;
//		case 15:
//			IP2366Data.T_TimeNode2 = IP2366_ReadOneByte(IP2366_TIMENODE2);	
//			IP2366Data.IP_Step = 16;
//		break;
//		case 16:
//			IP2366Data.T_TimeNode3 = IP2366_ReadOneByte(IP2366_TIMENODE3);	
//			IP2366Data.IP_Step = 17;
//		break;
//		case 17:
//			IP2366Data.T_TimeNode4 = IP2366_ReadOneByte(IP2366_TIMENODE4);	
//			IP2366Data.IP_Step = 18;
//		break;
//		case 18:
//			IP2366Data.T_TimeNode5 = IP2366_ReadOneByte(IP2366_TIMENODE5);	
//			IP2366Data.IP_Step = 0;
//		break;
		default:
			IP2366Data.IP_Step = 0;
		break;
	}

ip2366.h

#ifndef _IP_2366_h
#define _IP_2366_h
#include "main.h"

#define IP_GPIO_PORT	GPIOB

#define IP_SCL_PIN		GPIO_Pin_6//GPIO_Pin_0			/* 连接到SCL时钟线的GPIO */
#define IP_SDA_PIN		GPIO_Pin_7//GPIO_Pin_1			/* 连接到SDA数据线的GPIO */

#define IP_SCL_HIGH() 	GPIO_SetBits(IP_GPIO_PORT, IP_SCL_PIN)			/* SCL = 1 */
#define IP_SCL_LOW() 	GPIO_ResetBits(IP_GPIO_PORT, IP_SCL_PIN)		/* SCL = 0 */

#define IP_SDA_HIGH() 	GPIO_SetBits(IP_GPIO_PORT, IP_SDA_PIN)			/* SDA = 1 */
#define IP_SDA_LOW() 	GPIO_ResetBits(IP_GPIO_PORT, IP_SDA_PIN)		/* SDA = 0 */
#define READ_IP_SDA  	GPIO_ReadInputDataBit(IP_GPIO_PORT, IP_SDA_PIN)	/* 读SDA口线状态 */

#define IP_SDA_IN()  	{GPIOB->CRL &= 0X0FFFFFFF;GPIOB->CRL |= (u32)8<<28;}	//PB7输入模式
#define IP_SDA_OUT() 	{GPIOB->CRL &= 0X0FFFFFFF;GPIOB->CRL |= (u32)3<<28;}	//PB7输出模式



#define IP2366_ADR_WRITE_     0xEA
#define IP2366_ADR_READ_      0xEB
#define IP2366_ADDR_          0xEA

#define IP2366_STATE_CTL0_    0x31 // 充电状态控制寄存器
#define IP2366_STATE_CTL1_    0x32 // 充电状态控制寄存器
#define IP2366_STATE_CTL2_    0x33 // 输入 PD 状态控制寄存器

#define IP2366_ADR_WRITE     0xEA
#define IP2366_ADR_READ      0xEB
#define IP2366_ADDR          0xEA

#define IP2366_SYS_CTL0      0x00 // charge 使能寄存器
#define IP2366_SYS_CTL1      0x01 // 串联节数设置、电池类型、电流设置模式
#define IP2366_SYS_CTL2      0x02 // VSET 充满电压设定
#define IP2366_SYS_CTL3      0x03 // ISET 充电功率或电流设置
#define IP2366_SYS_CTL6      0x06 // 涓流充电电流设置
#define IP2366_SYS_CTL8      0x08 // 停充电流和再充电阈值设置
#define IP2366_SYS_CTL9      0x09 // 待机使能和低电电压设置
#define IP2366_SYS_CTL10     0x0A // 电池低电电压设置
#define IP2366_SYS_CTL11     0x0B // 输出使能寄存器

#define IP2366_TYPEC_CTL8    0x22 // TYPE-C 模式控制寄存器
#define IP2366_TYPEC_CTL9    0x23 // 输出 PDO 电流设置寄存器
#define IP2366_TYPEC_CTL10   0x24 // 5VPDO 电流设置寄存器
#define IP2366_TYPEC_CTL11   0x25 // 9VPDO 电流设置寄存器
#define IP2366_TYPEC_CTL12   0x26 // 12VPDO 电流设置寄存器
#define IP2366_TYPEC_CTL13   0x27 // 15VPDO 电流设置寄存器
#define IP2366_TYPEC_CTL14   0x28 // 20VPDO 电流设置寄存器
#define IP2366_TYPEC_CTL23   0x29 // PPS1 PDO 电流设置寄存器
#define IP2366_TYPEC_CTL24   0x2A // PPS2 PDO 电流设置寄存器
#define IP2366_TYPEC_CTL17   0x2B // 输出 PDO 设置寄存器

#define IP2366_STATE_CTL0    0x31 // 充电状态控制寄存器
#define IP2366_STATE_CTL1    0x32 // 充电状态控制寄存器
#define IP2366_STATE_CTL2    0x33 // 输入 PD 状态控制寄存器
#define IP2366_TYPEC_STATE0  0x34 // 系统状态指示寄存器
#define IP2366_MOS_STATE     0x35 // 输入 MOS 状态指示寄存器
#define IP2366_STATE_CTL3    0x38 // 系统过流指示寄存器

#define IP2366_BATVADC_DAT0  0x50 // VBAT 电压
#define IP2366_BATVADC_DAT1  0x51 // VBAT 电压
#define IP2366_VSYSVADC_L    0x52 // VSYS 电压
#define IP2366_VSYSVADC_H    0x53 // VSYS 电压
#define IP2366_IVBUS_IADC    0x54 // 充电输入电流

#define IP2366_TIMENODE1     0x69 // 时间戳寄存器第一位
#define IP2366_TIMENODE2     0x6A // 时间戳寄存器第二位
#define IP2366_TIMENODE3     0x6B // 时间戳寄存器第三位
#define IP2366_TIMENODE4     0x6C // 时间戳寄存器第四位
#define IP2366_TIMENODE5     0x6D // 时间戳寄存器第五位

#define IP2366_IBATIADC_L    0x6E // 电芯端电流
#define IP2366_IBATIADC_H    0x6F // 电芯端电流
#define IP2366_ISYS_IADC     0x70 // IVSYS 端电流
#define IP2366_VSYS_POW_L    0x74 // VSYS 端功率
#define IP2366_VSYS_POW_H    0x75 // VSYS 端功率

#define IP2366_INTC_IADC     0x77 // NTC 输出电流寄存器
#define IP2366_VGPIO0_NTC_L  0x78 // NTC端电压
#define IP2366_VGPIO0_NTC_H  0x79 // NTC端电压

#define IP2366_VGPIO1_ISET   0x7A // 电流设置
#define IP2366_VGPIO2_VSET   0x7C // 单节电压设置
#define IP2366_VGPIO3_FCAP   0x7E // 电池容量设置
#define IP2366_VGPIO4_BATNUM 0x80 // 电池节数设置

//IO方向设置
//#define IP_SDA_IN()  	{GPIOB->CRL &= 0XFFFFFF0F;GPIOB->CRL |= (u32)8<<4;}	//PB1输入模式
//#define IP_SDA_OUT() 	{GPIOB->CRL &= 0XFFFFFF0F;GPIOB->CRL |= (u32)3<<4;}	//PB1输入模式

typedef struct
{
	u8		IP_Step;			//读取步骤 

	u8		S_Bat_StateCtrl_0;	//0x31	
	u8		S_Bat_StateCtrl_1;	//0x32	
	u8		S_Bat_StateCtrl_2;	//0x33	
	
	u8		V_Bat_Data0;		//0x50,mV
	u8		V_Bat_Data1;		//0x51,mV
	
	u8		V_Sys_Data0;		//0x52,mV
	u8		V_Sys_Data1;		//0x53,mV
	
	u8		T_TimeNode1;		//0x69
	u8		T_TimeNode2;		//0x6A
	u8		T_TimeNode3;		//0x6B
	u8		T_TimeNode4;		//0x6C
	u8		T_TimeNode5;		//0x6D

	u8		I_Bat_Data0;		//0x6E,mA
	u8		I_Bat_Data1;		//0x6F,mA

	u8		P_Sys_PowData0;		//0x74,10mW
	u8		P_Sys_PowData1;		//0x75,mW

	u8		V_GPIO0_Data0;		//0x78,mV
	u8		V_GPIO0_Data1;		//0x79,mV

	u32		S_Bat;		//state
	u16     V_Bat;		//mV
	u16     V_Sys;		//mV
	u16     I_Bat;		//mA
	u16     P_Sys;		//mW
	u8		S_TypeC;	//state
	u16		V_Gpio;		//mV
}stIP2366Data;

extern stIP2366Data IP2366Data;


extern uint8_t IP2366_ReadOneByte(uint16_t ReadAddr);
extern void IP2366_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite);
extern unsigned int IP2366_Get_IpData(void);
extern void IP2366_Init(void);

#endif

main.c

#include "main.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"

u32 SysTick_Cnt = 0;
u16 Timer10ms_Cnt = 0;
u8 	IP2366_Step = 0;
s32 Pressure_Value[80];
u32 VBATValue = 0;
u32 IP2366_STATE_CTL0_VALUE = 0;
u32 IP2366_BATVADC_DAT0_VALUE = 0;
u32 IP2366_BATVADC_DAT1_VALUE = 0;
u8 IP2366_InitOk_Flag = 0;
u8 Charger_NoLoad_Flag = 0;
u8 Charger_State = BAT_NoCharger;
u8 timer_ADC_IOV_HIGH_CNT = 0;
u8 timer_ADC_IOV_LOW_CNT = 0;
float Depth_Sum;
MachInfoDrv MachInfo;
struct Mag mag_info;

void SysTick_Configuration(void);
void RTC_Configuration(void);
void EXTI_Configuration(void);

int main(void)
{
	SysTick_Configuration();			//SysTick 10ms

	vUsart1_Debug_Init();				//
	
	GPIO_EXTI_Config();
	Gpio_Init();
	ADC1_Init();
	
	TIM3_NVIC_Init(9, 7199);			//cycle 1ms			Button detection
	TIM4_NVIC_Init(2499, 7199);			//cycle 250ms		LED blinking control
	
	IP2366_Init();

	SysTick_Cnt = 1;
	Timer10ms_Cnt = 1;
	
	printf("\r\n power on ... \r\n");

	while(1)
	{
		if((Timer10ms_Cnt%5) == 0)		//100ms
		{
			if(IP2366_InitOk_Flag)
			{
				IP2366_Get_IpData();
			}
			IP2366Data.S_Bat = IP2366Data.S_Bat_StateCtrl_0 + (0x0000FF00&(IP2366Data.S_Bat_StateCtrl_1<<8)) + (0x00FF0000&(IP2366Data.S_Bat_StateCtrl_2<<16));
			IP2366Data.V_Bat = IP2366Data.V_Bat_Data0 + (0xFF00&(IP2366Data.V_Bat_Data1<<8));
			IP2366Data.V_Sys = IP2366Data.V_Sys_Data0 + (0xFF00&(IP2366Data.V_Sys_Data1<<8));
			IP2366Data.I_Bat = IP2366Data.I_Bat_Data0 + (0xFF00&(IP2366Data.I_Bat_Data1<<8));
			IP2366Data.P_Sys = (IP2366Data.P_Sys_PowData0 + (0xFF00&(IP2366Data.P_Sys_PowData1<<8)))*10;
			IP2366Data.V_Gpio = IP2366Data.V_GPIO0_Data0 + (0xFF00&(IP2366Data.V_GPIO0_Data1<<8));
		}

		if(Timer10ms_Cnt >= 20)		//20*10ms
		{
			Timer10ms_Cnt = 0;
				
			VBATValue = GetVBATValue();

			if(IP2366_INT_HIGH)	// IP2366 唤醒成功,可正常访问
			{
				IP2366_InitOk_Flag = 1;
			}
			
		}

		if(LED_Cnt >= 50)	//500ms亮 500ms灭
		{
			LED_Cnt = 0;
			Battery_Display(IP2366Data.V_Bat,BAT_Charging,IP2366Data.S_Bat);
		}


		if(Charger_NoLoad_Cnt >= 100)	//100*10ms     1s
		{	
			Charger_NoLoad_Cnt = 0;
			printf("Adc= %dmv S_Bat= 0x%3x V_Bat= %dmV V_Sys= %dmV I_Bat= %dmA P_Sys= %dmW  ",VBATValue,IP2366Data.S_Bat,IP2366Data.V_Bat,IP2366Data.V_Sys,IP2366Data.I_Bat,IP2366Data.P_Sys);
//			printf("Adc= %dmv S_Bat= 0x%3x S_TypeC= 0x%x V_Bat= %dmV V_Sys= %dmV I_Bat= %dmA P_Sys= %dmW V_Gpio= %dmV T_TN_1-5=0x%x 0x%x 0x%x 0x%x 0x%x  ",VBATValue,IP2366Data.S_Bat,IP2366Data.S_TypeC,IP2366Data.V_Bat,IP2366Data.V_Sys,IP2366Data.I_Bat,IP2366Data.P_Sys,IP2366Data.V_Gpio,IP2366Data.T_TimeNode1,IP2366Data.T_TimeNode2,IP2366Data.T_TimeNode3,IP2366Data.T_TimeNode4,IP2366Data.T_TimeNode5);
		}
/*
		if((timer_ADC_IOV_LOW_CNT +  timer_ADC_IOV_HIGH_CNT) >= 35)		//35*200 7s
		{
			if((timer_ADC_IOV_LOW_CNT >= 3) && (timer_ADC_IOV_HIGH_CNT >= 3))
			{
				Charger_State = BAT_NoCharger;
			}else {
				Charger_State = BAT_Charging;
			}
			timer_ADC_IOV_LOW_CNT = 0;
			timer_ADC_IOV_HIGH_CNT = 0;
		}
*/

	}
}


/**
  * @brief  Configures the SysTick to generate an interrupt each 500 ms.
  * @param  None
  * @retval None
  */
void SysTick_Configuration(void)
{
  /* SysTick interrupt each 10 ms with SysTick Clock equal to (HCLK/8) */
  if (SysTick_Config((SystemCoreClock/8) / 100))      //(SystemCoreClock/8)=1s
  { 
    /* Capture error */ 
    while (1);
  }

  /* Select AHB clock(HCLK) divided by 8 as SysTick clock source */
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);

  /* Set SysTick Preemption Priority to 1 */
  NVIC_SetPriority(SysTick_IRQn, 0x04);
}

/**
  * @brief  Configures RTC clock source and prescaler.
  * @param  None
  * @retval None
  */
void RTC_Configuration(void)
{
  /* Check if the StandBy flag is set */
  if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)   //
  {/* System resumed from STANDBY mode */

    /* Clear StandBy flag */
    PWR_ClearFlag(PWR_FLAG_SB);

    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();
    /* No need to configure the RTC as the RTC configuration(clock source, enable,
       prescaler,...) is kept after wake-up from STANDBY */
  }
  else
  {/* StandBy flag is not set */

    /* RTC clock source configuration ----------------------------------------*/
    /* Reset Backup Domain */
    BKP_DeInit();
	  
	 /* Enable LSI OSC */
    RCC_LSICmd(ENABLE); 
	  
	    /* Wait till LSI is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
    {
    }
	
	/* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);

    /* RTC configuration -----------------------------------------------------*/
    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();
	
    /* Set the RTC time base to 1s */
    RTC_SetPrescaler(40000); 
	
    /* Wait until last write operation on RTC registers has finished */
    RTC_WaitForLastTask();
		
		/* Enable the RTC Alarm interrupt */
	RTC_ITConfig(RTC_IT_ALR, ENABLE);
	/* Wait until last write operation on RTC registers has finished */
	RTC_WaitForLastTask();
		
  }
}

/**
  * @brief  Configures EXTI Lines.
  * @param  None
  * @retval None
  */
void EXTI_Configuration(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	/* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */
	EXTI_ClearITPendingBit(EXTI_Line17);
	EXTI_InitStructure.EXTI_Line = EXTI_Line17;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	/* 2 bits for Preemption Priority and 2 bits for Sub Priority */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

三、注意IP2366的I2C时序有些特殊,需要做特定的延时处理才能正常读取到寄存器数据

1、读取操作时各个位置增加50us延时

2、I2C频率设在100-200k合适;

3、结束读取后增加nack信号,防止读不出下一个数据。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐