GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);
I2C_Init(I2C_Mode_I2C, 100000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, MASTER_ADDR); //初始化了 I2C 接口,设置了通信速率为 100kHz
-
初始化SDA/SCL,配置为上拉输入模式,根据芯片手册,需要时会自动开漏输出
![1149ad9b-b78f-408c-ab91-800312fb34ea]()
-
I2C_Init:
I2C_Mode:支持主模式/从模式
I2C_ClockSpeed:最大400KHz
I2C_DutyCycle:快速模式中时钟线的占空比
I2C_Ack:使能ACK
I2C_AckAddr:ACK 7位或10位地址
I2C_OwnAddress1:本机地址 -
以电量计为例使用硬件I2C读取寄存器数值过程
__HIGH_CODE
uint8_t KP691000_Read_Data(uint8_t slave_adress, uint8_t reg_adress, uint8_t *cb_data, uint16_t len)
{uint32_t temp_data =0;GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, MASTER_ADDR); //初始化了 I2C 接口,设置了通信速率为 400kHztimeout_count_1ms = 0;while(I2C_GetFlagStatus(I2C_FLAG_BUSY) != RESET) //循环检查 I2C 总线是否忙碌,直到不再忙碌为止{if(timeout_count_1ms >I2C_TIMEOUT_MS) {I2C_GenerateSTOP(ENABLE);return FALSE;}}//发送寄存器地址I2C_GenerateSTART(ENABLE); //生成起始信号,开始 I2C 通信
// first time send slave address to wake uptimeout_count_1ms = 0;while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)) //检查是否成功进入主模式。{if(timeout_count_1ms >I2C_TIMEOUT_MS){I2C_GenerateSTOP(ENABLE);return FALSE;}}I2C_Send7bitAddress(KP691000_SLAVE_ADDR_7BIT, I2C_Direction_Transmitter); //发送从设备地址,指定为发送模式I2C_GenerateSTOP(ENABLE);DelayMs(1);// must delay
// second time send slave addressI2C_GenerateSTART(ENABLE); //生成起始信号,开始 I2C 通信timeout_count_1ms = 0;while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)) //检查是否成功进入主模式。{if(timeout_count_1ms >I2C_TIMEOUT_MS){I2C_GenerateSTOP(ENABLE);return FALSE;}}I2C_Send7bitAddress(KP691000_SLAVE_ADDR_7BIT, I2C_Direction_Transmitter); //发送从设备地址,指定为发送模式timeout_count_1ms = 0;while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //检查是否成功进入主发送模式{if(timeout_count_1ms >I2C_TIMEOUT_MS){I2C_GenerateSTOP(ENABLE);return FALSE;}}
//send dataif(I2C_GetFlagStatus(I2C_FLAG_TXE) != RESET){I2C_SendData(reg_adress);}
//read dataI2C_GenerateSTART(ENABLE);timeout_count_1ms = 0;while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT)){if(timeout_count_1ms >I2C_TIMEOUT_MS){I2C_GenerateSTOP(ENABLE);return FALSE;}}I2C_Send7bitAddress(KP691000_SLAVE_ADDR_7BIT, I2C_Direction_Receiver); //发送7位从机地址timeout_count_1ms = 0;while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){if(timeout_count_1ms >I2C_TIMEOUT_MS){I2C_GenerateSTOP(ENABLE);return FALSE;}}
//receive datafor(uint8_t i = 0; i < len; i++){if(i == len - 1){I2C_AcknowledgeConfig(DISABLE);}timeout_count_1ms = 0;while (!I2C_GetFlagStatus(I2C_FLAG_RXNE)) {if (timeout_count_1ms > I2C_TIMEOUT_MS) {I2C_GenerateSTOP(ENABLE);I2C_AcknowledgeConfig(ENABLE);return FALSE;}}cb_data[i] = I2C_ReceiveData();}I2C_GenerateSTOP(ENABLE);I2C_AcknowledgeConfig(ENABLE); // 恢复默认 ACK 状态return TRUE;
}
/*** @brief read 0x20 reg data* * @return uint8_t */
uint8_t Get_IntgData()
{uint8_t buf[20];if(KP691000_Read_Data(KP691000_SLAVE_ADDR_7BIT, 0x20, buf, 20)){uint16_t voltage = (buf[1] << 8) | buf[0]; // mVint16_t current = (buf[3] << 8) | buf[2]; // mAint16_t temp_ext = (buf[5] << 8) | buf[4]; // 0.1°Cint16_t temp_int = (buf[7] << 8) | buf[6]; // 0.1°Cuint16_t rsoc = (buf[9] << 8) | buf[8]; // 0.01%uint16_t soh = (buf[11] << 8) | buf[10]; // %uint16_t cycles = (buf[13] << 8) | buf[12]; // 次uint16_t coulomb = (buf[15] << 8) | buf[14]; // mAhuint16_t time_empty = (buf[17] << 8) | buf[16]; // minuint16_t time_full = (buf[19] << 8) | buf[18]; // minPRINT("voltage is %d mV\n current is %d mA\n ex_temp is %d\n in_temp is %d\n rsoc is %d\n soh is %d\n \
cycles is %d\n coulomb is %d mAh\n time_empty is %d\n time_full is %d\n",\voltage, current, temp_ext, temp_int, rsoc, soh, cycles, coulomb,time_empty, time_full);PRINT("---------------------------------------\n");return TRUE;}return FALSE;}

