/* * @Description: file content * @Author: CK.Zh * @Date: 2020-04-27 18:01:58 * @LastEditors: CK.Zh * @LastEditTime: 2020-04-29 17:49:01 */ #include "coulomb.h" coulomb_t coulomb; //静态方法,检测设备是否就绪 static HAL_StatusTypeDef is_coulomb_ready() { return HAL_I2C_IsDeviceReady(&hi2c1,COULOMB_ADDR,3,20); } //静态方法,写寄存器 static HAL_StatusTypeDef coulomb_write_reg(uint8_t addr,uint8_t* pData) { return HAL_I2C_Mem_Write(&hi2c1,COULOMB_ADDR ,addr,1,pData, 1, 10); } //静态方法,读寄存器 static HAL_StatusTypeDef coulomb_read_reg(uint8_t addr,uint8_t* pData) { return HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,addr,1,pData, 1, 10); } /** * @description: 静态方法,字节拼接 * @param pData 数组指针 * @param msbIndex 高字节在数组中的位置 * @param lsbIndex 低字节在数组中的位置 * @return: */ static uint16_t uint8_to_uint16(uint8_t *pData,uint8_t msbIndex,uint8_t lsbIndex) { return ((pData[msbIndex]<<8) | pData[lsbIndex]); } /** * @description: 静态方法,字节拆解 * @param data * @return: */ static uint8_t uint16_to_uint8_msb(uint16_t data) { return ((data>>8) & 0xff); } /** * @description: 静态方法,字节拆解 * @param data * @return: */ static uint8_t uint16_to_uint8_lsb(uint16_t data) { return ((data ) & 0xff); } /** * @description: 初始化配置参数(寄存器上电后的缺省值) * @param {type} * @return: */ // void coulomb_write_config_load_default() // { // coulomb.write.raw.control = 0xEC; // coulomb.write.raw.accumulated_charge = 0x7fff; // coulomb.write.raw.charge_threshold_H = 0xffff; // coulomb.write.raw.charge_threshold_L = 0x0000; // coulomb.write.raw.voltage_threshold_H = 0xffff; // coulomb.write.raw.voltage_threshold_L = 0x0000; // coulomb.write.raw.current_threshold_H = 0xffff; // coulomb.write.raw.current_threshold_L = 0x0000; // coulomb.write.raw.temperature_threshold_H = 0xff; // coulomb.write.raw.temperature_threshold_L = 0x00; // } /** * @description: 初始化配置参数 * @param {type} * @return: */ void coulomb_write_config_load() { //控制寄存器配置 coulomb.write.actual.control.adc_mode = 0b00; coulomb.write.actual.control.prescaler = 0b111; coulomb.write.actual.control.alcc_configure = 0b10; coulomb.write.actual.control.shutdown = 0b00; //剩余容量重写入 coulomb.write.actual.accumulated_charge = 2; //充电阈值上限 coulomb.write.actual.charge_threshold_H = 20; //充电阈值下限 coulomb.write.actual.charge_threshold_L = 1; //电压阈值上限 coulomb.write.actual.voltage_threshold_H = 15; //电压阈值下限 coulomb.write.actual.voltage_threshold_L = 9.5; //电流阈值上限 coulomb.write.actual.current_threshold_H = 10; //电流阈值下限 coulomb.write.actual.current_threshold_L = -10; //温度阈值上限 coulomb.write.actual.temperature_threshold_H = 60; //温度阈值下限 coulomb.write.actual.temperature_threshold_L = -15; } /** * @description: 将准备写入的目标参数转化成寄存器格式 * @param {type} * @return: */ void coulomb_write_config_actual_to_raw() { //控制寄存器 coulomb.write.raw.control = (coulomb.write.actual.control.adc_mode << 6) | \ (coulomb.write.actual.control.prescaler << 3) | \ (coulomb.write.actual.control.alcc_configure << 1) | \ (coulomb.write.actual.control.shutdown ) ; //累计电量 coulomb.write.raw.accumulated_charge = (uint16_t)((coulomb.write.actual.accumulated_charge / 30.0) * 32767 + 32767); //充电阈值上限 coulomb.write.raw.charge_threshold_H = (uint16_t)((coulomb.write.actual.charge_threshold_H / 30.0) * 32767 + 32767); //充电阈值下限 coulomb.write.raw.charge_threshold_L = (uint16_t)((coulomb.write.actual.charge_threshold_L / 30.0) * 32767 + 32767); //电压阈值上限 coulomb.write.raw.voltage_threshold_H = (uint16_t)((coulomb.write.actual.voltage_threshold_H / 23.6) * 65535); //电压阈值下限 coulomb.write.raw.voltage_threshold_L = (uint16_t)((coulomb.write.actual.voltage_threshold_L / 23.6) * 65535); //电流阈值上限 coulomb.write.raw.current_threshold_H = (uint16_t)((coulomb.write.actual.current_threshold_H / 30.0) * 32767 + 32767); //电流阈值下限 coulomb.write.raw.current_threshold_L = (uint16_t)((coulomb.write.actual.current_threshold_L / 30.0) * 32767 + 32767); //温度阈值上限 coulomb.write.raw.temperature_threshold_H = ((uint16_t)((coulomb.write.actual.temperature_threshold_H + 273.15) / 510.0 * 65535)) & 0xFF00;//清空低字节 //温度阈值下限 coulomb.write.raw.temperature_threshold_L = ((uint16_t)((coulomb.write.actual.temperature_threshold_L + 273.15) / 510.0 * 65535)) & 0xFF00;//清空低字节 } /** * @description: 写入寄存器配置 * @param {type} * @return: */ bool coulomb_write_config() { uint8_t writeData[COULOMB_REG_NUM] = {0}; //控制寄存器 writeData[LTC2943_CONTROL_REG] = coulomb.write.raw.control; //累计电量 writeData[LTC2943_ACCUM_CHARGE_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.accumulated_charge); writeData[LTC2943_ACCUM_CHARGE_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.accumulated_charge); //充电阈值上限 writeData[LTC2943_CHARGE_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.charge_threshold_H); writeData[LTC2943_CHARGE_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.charge_threshold_H); //充电阈值下限 writeData[LTC2943_CHARGE_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.charge_threshold_L); writeData[LTC2943_CHARGE_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.charge_threshold_L); //电压阈值上限 writeData[LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.voltage_threshold_H); writeData[LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.voltage_threshold_H); //电压阈值下限 writeData[LTC2943_VOLTAGE_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.voltage_threshold_L); writeData[LTC2943_VOLTAGE_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.voltage_threshold_L); //电流阈值上限 writeData[LTC2943_CURRENT_THRESH_HIGH_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.current_threshold_H); writeData[LTC2943_CURRENT_THRESH_HIGH_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.current_threshold_H); //电流阈值下限 writeData[LTC2943_CURRENT_THRESH_LOW_MSB_REG] = uint16_to_uint8_msb(coulomb.write.raw.current_threshold_L); writeData[LTC2943_CURRENT_THRESH_LOW_LSB_REG] = uint16_to_uint8_lsb(coulomb.write.raw.current_threshold_L); //温度阈值上限 writeData[LTC2943_TEMPERATURE_THRESH_HIGH_REG] = uint16_to_uint8_msb(coulomb.write.raw.temperature_threshold_H); //温度阈值下限 writeData[LTC2943_TEMPERATURE_THRESH_LOW_REG] = uint16_to_uint8_msb(coulomb.write.raw.temperature_threshold_L); coulomb.ready = (is_coulomb_ready()==HAL_OK) ? true : false; if(coulomb.ready) { coulomb_write_reg(LTC2943_CONTROL_REG,&writeData[LTC2943_CONTROL_REG]); coulomb_write_reg(LTC2943_ACCUM_CHARGE_MSB_REG,&writeData[LTC2943_ACCUM_CHARGE_MSB_REG]); coulomb_write_reg(LTC2943_ACCUM_CHARGE_LSB_REG,&writeData[LTC2943_ACCUM_CHARGE_LSB_REG]); coulomb_write_reg(LTC2943_CHARGE_THRESH_HIGH_MSB_REG,&writeData[LTC2943_CHARGE_THRESH_HIGH_MSB_REG]); coulomb_write_reg(LTC2943_CHARGE_THRESH_HIGH_LSB_REG,&writeData[LTC2943_CHARGE_THRESH_HIGH_LSB_REG]); coulomb_write_reg(LTC2943_CHARGE_THRESH_LOW_MSB_REG,&writeData[LTC2943_CHARGE_THRESH_LOW_MSB_REG]); coulomb_write_reg(LTC2943_CHARGE_THRESH_LOW_LSB_REG,&writeData[LTC2943_CHARGE_THRESH_LOW_LSB_REG]); coulomb_write_reg(LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG]); coulomb_write_reg(LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG]); coulomb_write_reg(LTC2943_VOLTAGE_THRESH_LOW_MSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_LOW_MSB_REG]); coulomb_write_reg(LTC2943_VOLTAGE_THRESH_LOW_LSB_REG,&writeData[LTC2943_VOLTAGE_THRESH_LOW_LSB_REG]); coulomb_write_reg(LTC2943_CURRENT_THRESH_HIGH_MSB_REG,&writeData[LTC2943_CURRENT_THRESH_HIGH_MSB_REG]); coulomb_write_reg(LTC2943_CURRENT_THRESH_HIGH_LSB_REG,&writeData[LTC2943_CURRENT_THRESH_HIGH_LSB_REG]); coulomb_write_reg(LTC2943_CURRENT_THRESH_LOW_MSB_REG,&writeData[LTC2943_CURRENT_THRESH_LOW_MSB_REG]); coulomb_write_reg(LTC2943_CURRENT_THRESH_LOW_LSB_REG,&writeData[LTC2943_CURRENT_THRESH_LOW_LSB_REG]); coulomb_write_reg(LTC2943_TEMPERATURE_THRESH_HIGH_REG,&writeData[LTC2943_TEMPERATURE_THRESH_HIGH_REG]); coulomb_write_reg(LTC2943_TEMPERATURE_THRESH_LOW_REG,&writeData[LTC2943_TEMPERATURE_THRESH_LOW_REG]); } return coulomb.ready; } /** * @description: 将读取到的 状态类的 寄存器数据转换成真实数据 * @param {type} * @return: */ void coulomb_read_status_raw_to_actual() { //status 转换到 对应位 coulomb.read.actual.status.current_alret = ((coulomb.read.raw.status>>6) & 0b00000001) ? true : false; coulomb.read.actual.status.accumulated_charge_alert = ((coulomb.read.raw.status>>5) & 0b00000001) ? true : false; coulomb.read.actual.status.temperature_alret = ((coulomb.read.raw.status>>4) & 0b00000001) ? true : false; coulomb.read.actual.status.charge_alert_H = ((coulomb.read.raw.status>>3) & 0b00000001) ? true : false; coulomb.read.actual.status.charge_alert_L = ((coulomb.read.raw.status>>2) & 0b00000001) ? true : false; coulomb.read.actual.status.voltage_alert = ((coulomb.read.raw.status>>1) & 0b00000001) ? true : false; coulomb.read.actual.status.uvlo_alert = ( coulomb.read.raw.status & 0b00000001) ? true : false; //剩余电量转换 coulomb.read.actual.accumulated_charge = (coulomb.read.raw.accumulated_charge - 32767) / 32767.0 * 30 ; //电压转换 coulomb.read.actual.voltage = coulomb.read.raw.voltage / 65535.0 *23.6; //电流转换 coulomb.read.actual.current = (coulomb.read.raw.current - 32767) / 32767.0 * 30 ; //温度转换 coulomb.read.actual.temperature = (coulomb.read.raw.temperature / 65535.0 * 510 ) - 273.15; } /** * @description: 将读取到的 配置类的 寄存器数据转换成真实参数 * @param {type} * @return: */ void coulomb_read_config_raw_to_actual() { //control寄存器转换到对应位 coulomb.read.actual.control.adc_mode = ((coulomb.read.raw.control >> 6) & 0b00000011); coulomb.read.actual.control.prescaler = ((coulomb.read.raw.control >> 3) & 0b00000111); coulomb.read.actual.control.alcc_configure = ((coulomb.read.raw.control >> 1) & 0b00000011); coulomb.read.actual.control.shutdown = ( coulomb.read.raw.control & 0b00000001); //阈值累计充电转换 coulomb.read.actual.charge_threshold_H = (coulomb.read.raw.charge_threshold_H - 32767) / 32767.0 * 30; coulomb.read.actual.charge_threshold_L = (coulomb.read.raw.charge_threshold_L - 32767) / 32767.0 * 30; //电压阈值转换 coulomb.read.actual.voltage_threshold_H = coulomb.read.raw.voltage_threshold_H / 65535.0 *23.6; coulomb.read.actual.voltage_threshold_L = coulomb.read.raw.voltage_threshold_L / 65535.0 *23.6; //电流阈值转换 coulomb.read.actual.current_threshold_H = (coulomb.read.raw.current_threshold_H - 32767) / 32767.0 * 30 ; coulomb.read.actual.current_threshold_L = (coulomb.read.raw.current_threshold_L - 32767) / 32767.0 * 30 ; //温度阈值转换 coulomb.read.actual.temperature_threshold_H = (coulomb.read.raw.temperature_threshold_H / 65535.0 * 510 ) - 273.15; coulomb.read.actual.temperature_threshold_L = (coulomb.read.raw.temperature_threshold_L / 65535.0 * 510 ) - 273.15; } //读取原始寄存器数据 /** * @description: 读取状态类和配置类的寄存器(即所有寄存器) * @param {type} * @return: */ bool coulomb_read_status_and_config() { uint8_t readData[COULOMB_REG_NUM]; coulomb.ready = (is_coulomb_ready()==HAL_OK) ? true : false; if(coulomb.ready) { HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,0,1,readData, 1, 10); HAL_I2C_Mem_Read(&hi2c1,COULOMB_ADDR ,0,COULOMB_REG_NUM,&readData[1], COULOMB_REG_NUM, 100); coulomb.read.raw.status = readData[LTC2943_STATUS_REG]; coulomb.read.raw.control = readData[LTC2943_CONTROL_REG]; coulomb.read.raw.accumulated_charge = uint8_to_uint16(readData,LTC2943_ACCUM_CHARGE_MSB_REG,LTC2943_ACCUM_CHARGE_LSB_REG); coulomb.read.raw.charge_threshold_H = uint8_to_uint16(readData,LTC2943_CHARGE_THRESH_HIGH_MSB_REG,LTC2943_CHARGE_THRESH_HIGH_LSB_REG); coulomb.read.raw.charge_threshold_L = uint8_to_uint16(readData,LTC2943_CHARGE_THRESH_LOW_MSB_REG,LTC2943_CHARGE_THRESH_LOW_LSB_REG); coulomb.read.raw.voltage = uint8_to_uint16(readData,LTC2943_VOLTAGE_MSB_REG,LTC2943_VOLTAGE_LSB_REG); coulomb.read.raw.voltage_threshold_H = uint8_to_uint16(readData,LTC2943_VOLTAGE_THRESH_HIGH_MSB_REG,LTC2943_VOLTAGE_THRESH_HIGH_LSB_REG); coulomb.read.raw.voltage_threshold_L = uint8_to_uint16(readData,LTC2943_VOLTAGE_THRESH_LOW_MSB_REG,LTC2943_VOLTAGE_THRESH_LOW_LSB_REG); coulomb.read.raw.current = uint8_to_uint16(readData,LTC2943_CURRENT_MSB_REG,LTC2943_CURRENT_LSB_REG); coulomb.read.raw.current_threshold_H = uint8_to_uint16(readData,LTC2943_CURRENT_THRESH_HIGH_MSB_REG,LTC2943_CURRENT_THRESH_HIGH_LSB_REG); coulomb.read.raw.current_threshold_L = uint8_to_uint16(readData,LTC2943_CURRENT_THRESH_LOW_MSB_REG,LTC2943_CURRENT_THRESH_LOW_LSB_REG); coulomb.read.raw.temperature = uint8_to_uint16(readData,LTC2943_TEMPERATURE_MSB_REG,LTC2943_TEMPERATURE_LSB_REG); coulomb.read.raw.temperature_threshold_H = (readData[LTC2943_TEMPERATURE_THRESH_HIGH_REG]<<8) | 0x00;//补充低字节 coulomb.read.raw.temperature_threshold_L = (readData[LTC2943_TEMPERATURE_THRESH_LOW_REG]<<8) | 0x00;//补充低字节 } return coulomb.ready; } bool coulomb_read_alcc() { return HAL_GPIO_ReadPin(PMB_CLOULOMB_ALCC_GPIO_Port,PMB_CLOULOMB_ALCC_Pin); }