/* ********************************************************************************************************* * * 模块名称 : ds2782驱动 * 文件名称 : DS2782.c * 版 本 : V1.0 * 说 明 : * * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2019-02-022 Baiyang * * ********************************************************************************************************* */ #include "string.h" #include "math.h" #include <stdio.h> #include <stdlib.h> #include "gsdk_api.h" #include "bsp_ds2782.h" #include "gsdk_sdk.h" static gsdk_handle_t g_hi2c; /* * 函数名 Write_DS2782_Shadow_RAM * 功能 写DS2782影子寄存器 */ void Write_DS2782_Shadow_RAM(uint8_t reg_Addres,uint8_t data) { int ret; uint8_t data_reg_addr[] = {0x00, 0x00}; data_reg_addr[0] = reg_Addres; data_reg_addr[1] = data; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[1], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error1 (%ld)\n", ret); OEM_LOGE("I2C Transmit error2 (%d)\n", ret); } } /* * 函数名 Copy_Data_For_Shadow_RAM_To_EEPROM * 功能 将影子寄存器数据Copy至EEPROM * 详见数据手册 P26页 Function Command Protocol 章节 */ void Copy_Data_For_Shadow_RAM_To_EEPROM(uint8_t EEPROM_BLOCK) { int ret; uint8_t data_reg_addr[] = {0x00, 0x00}; data_reg_addr[0] = FCR; data_reg_addr[1] = EEPROM_BLOCK; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[1], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error3 (%ld)\n", ret); OEM_LOGE("I2C Transmit error4 (%d)\n", ret); } } /* * 函数名 Get_DS2782_STATUS * 功能 度状态寄存器 */ uint8_t Get_DS2782_STATUS() { uint8_t data; int ret; uint8_t data_reg_addr[2]; int timeout_ms = 5000; data_reg_addr[0] = STATUS; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address|I2C_WR, data_reg_addr, 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address|I2C_RD, &data, 1, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } return data; } /* * 函数名 Get_DS2782_Temperature * 红能 获取DS2782温度 放大十倍 */ uint16_t Get_DS2782_Temperature() { uint8_t data[2]; uint16_t Temperature=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = TEMPMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error5 (%ld)\n", ret); OEM_LOGE("I2C Transmit error6 (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error7 (%ld)\n", ret); OEM_LOGE("I2C Read error8 (%d)\n", ret); return -1; } Temperature+=data[0]<<3; Temperature+=data[1]>>5; Temperature*=0.125; return Temperature; } /* * 函数名 Get_DS2782_Voltage * 红能 获取DS2782电压 */ uint16_t Get_DS2782_Voltage() { uint8_t data[2]; uint16_t Voltage=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = VOLTMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } Voltage+=data[0]<<3; Voltage+=data[1]>>5; Voltage*=4.88; Voltage*=2; return Voltage; } /* * 函数名 Get_DS2782_Current * 功能 获取DS2782电流 */ int16_t Get_DS2782_Current() { uint8_t data[2]; int16_t Current=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = CURRENTMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } Current+=data[0]<<8; Current+=data[1]; Current=(int)(Current*1.5625/RSNSP_mOhm); //mA return Current; } /* * 函数名 Get_DS2782_RAAC * 功能 剩余绝对有效电量 (RAAC) [mAh] */ uint16_t Get_DS2782_RAAC() { uint8_t data[2]; uint16_t Remaining_Capacity=0; int ret; uint8_t data_reg_addr[] = {0x00}; int timeout_ms = 5000; data_reg_addr[0] = RAACMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } Remaining_Capacity+=data[0]<<8; Remaining_Capacity+=data[1]; return Remaining_Capacity; } /* * 函数名 Get_DS2782_RSAC * 功能 剩余绝对待机电量 (RSAC) [mAh] */ uint16_t Get_DS2782_RSAC() { uint8_t data[2]; uint16_t Remaining_Capacity=0; int ret; uint8_t data_reg_addr[] = {0x00}; int timeout_ms = 5000; data_reg_addr[0] = RSACMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } Remaining_Capacity+=data[0]<<8; Remaining_Capacity+=data[1]; return Remaining_Capacity; } /* * 函数名 Get_DS2782_RARC * 功能 剩余相对对有效电量 (RARC) [%] */ uint8_t Get_DS2782_RARC() { uint8_t data; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = RARC; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, &data, 1, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } return data; } /* * 函数名 Get_DS2782_RSRC * 功能 剩余相对待机电量 (RSRC) [%] */ uint8_t Get_DS2782_RSRC() { uint8_t data; int ret; uint8_t data_reg_addr[] = {0x00}; int timeout_ms = 5000; data_reg_addr[0] = RSRC; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, &data, 1, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } return data; } /* * 函数名 Get_DS2782_ACR * 功能 . 累计电流 (ACRMSB) [6.25μVh/RSNS] */ uint16_t Get_DS2782_ACR() { uint8_t data[2]; uint16_t ACR=0; int ret; uint8_t data_reg_addr[] = {0x00}; int timeout_ms = 5000; data_reg_addr[0] = ACRMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error (%ld)\n", ret); OEM_LOGE("I2C Transmit error (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error (%ld)\n", ret); OEM_LOGE("I2C Read error (%d)\n", ret); return -1; } ACR+=data[0]<<8; ACR+=data[1]; ACR=(int)(ACR*0.625); return ACR; } /* * 函数名 Get_DS2782_FULL(T) * 红能 获取DS2782当前温度下满电量 */ uint16_t Get_DS2782_FULL() { uint8_t data[2]; uint16_t full=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = FULLMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error5 (%ld)\n", ret); OEM_LOGE("I2C Transmit error6 (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error7 (%ld)\n", ret); OEM_LOGE("I2C Read error8 (%d)\n", ret); return -1; } full+=data[0]<<8; full+=data[1]; return full; } /* * 函数名 Get_DS2782_AE(T) * 红能 获取DS2782当前温度下满电量 */ uint16_t Get_DS2782_AE() { uint8_t data[2]; uint16_t AE=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = AEMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error5 (%ld)\n", ret); OEM_LOGE("I2C Transmit error6 (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error7 (%ld)\n", ret); OEM_LOGE("I2C Read error8 (%d)\n", ret); return -1; } AE+=data[0]<<8; AE+=data[1]; return AE; } /* * 函数名 Get_DS2782_SE(T) * 红能 获取DS2782当前温度下满电量 */ uint16_t Get_DS2782_SE() { uint8_t data[2]; uint16_t SE=0; int ret; int timeout_ms = 5000; uint8_t data_reg_addr[] = {0x00}; data_reg_addr[0] = AEMSB; ret = gsdk_i2c_write(g_hi2c, DS2782_8bit_Slave_Address, &data_reg_addr[0], 1); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Transmit error5 (%ld)\n", ret); OEM_LOGE("I2C Transmit error6 (%d)\n", ret); return -1; } ret = gsdk_i2c_read(g_hi2c, DS2782_8bit_Slave_Address, data, 2, timeout_ms); if (ret != GSDK_SUCCESS) { gsdk_syslog_printf("I2C Read error7 (%ld)\n", ret); OEM_LOGE("I2C Read error8 (%d)\n", ret); return -1; } SE+=data[0]<<8; SE+=data[1]; return SE; } void bsp_Init_DS2782() { gsdk_status_t status; //初始化I2C总线 status = gsdk_i2c_master_init(I2C_MASTER_2, I2C_FREQUENCY_400K, &g_hi2c);//welinkopen only support i2c master 2 or i2c master 1 if (status != GSDK_SUCCESS) { gsdk_syslog_printf("[PRINTF_DEMO]: failed to open i2c %d\n", status); } else { printf("****************************i2c open success*********************************\n"); } } void Module_DS2781_Set_Register(void) { uint8_t TEMP[2]; uint16_t TEMP_Word; /* 配置 Parameter EEPROM Memory Block 1 的 shadow RAM (影子寄存器) */ Write_DS2782_Shadow_RAM(CONTROL,0x00); //控制寄存器 Write_DS2782_Shadow_RAM(AB,0x00); //累计偏置 TEMP_Word=(uint16_t)Capacity*RSNSP_mOhm; //计算 老化容量 AC 单位 6.25μVh TEMP_Word=(int)(TEMP_Word/6.25); TEMP[0]=TEMP_Word>>8; TEMP[1]=TEMP_Word&0xFF; Write_DS2782_Shadow_RAM(ACMSB,TEMP[0]); //老化容量 AC Write_DS2782_Shadow_RAM(ACLSB,TEMP[1]); //老化容量 AC /*计算 充电电压VCHG AC 单位 为19.52mV */ TEMP[0]=(int)(Charge_Voltage/19.52); Write_DS2782_Shadow_RAM(VCHG,TEMP[0]); //充电电压VCHG /*写入AS,100% */ TEMP[0]= 0x80; Write_DS2782_Shadow_RAM(AS,TEMP[0]); //AS /*计算 最小充电电流 IMIN 单位 为50μV */ TEMP[0]=(int)(Minimum_Charge_Current*RSNSP_mOhm/50); Write_DS2782_Shadow_RAM(IMIN,TEMP[0]); //最小充电电流 IMIN /*计算 VAE 0x66 有效空电压 单位 为19.52mV */ TEMP[0]=(int)(Empty_Voltage/19.52); Write_DS2782_Shadow_RAM(VAE,TEMP[0]); // VAE 0x66 有效空电压 /*计算 IAE 0x67 有效空电流 单位 为200μV */ TEMP[0]=(int)(Empty_Current*RSNSP_mOhm/200); Write_DS2782_Shadow_RAM(IAE,TEMP[0]); // IAE 0x67 有效空电流 /*计算 RSNSP 0x69 采样电阻 单位 电导形式存储 */ TEMP[0]=(int)(1000/RSNSP_mOhm); Write_DS2782_Shadow_RAM(RSNSP,TEMP[0]); // RSNSP 0x69 采样电阻 TEMP_Word=(uint16_t)Capacity*RSNSP_mOhm; //计算 +40°C温度时的满电量值 6.25μVh TEMP_Word=(int)(TEMP_Word/6.25); TEMP[0]=TEMP_Word>>8; TEMP[1]=TEMP_Word&0xFF; /* Write_DS2782_Shadow_RAM(FULLSMSB,TEMP[0]); //+40°C温度时的满电量值 FULLS Write_DS2782_Shadow_RAM(FULLSLSB,TEMP[1]); //+40°C温度时的满电量值 FULLS Write_DS2782_Shadow_RAM(0x68, 0x06); Write_DS2782_Shadow_RAM(FULL3040,0x0E); // 满电量斜率 Write_DS2782_Shadow_RAM(FULL2030,0x11); // 满电量斜率 Write_DS2782_Shadow_RAM(FULL1020,0x31); // 满电量斜率 Write_DS2782_Shadow_RAM(FULL0010,0x36); // 满电量斜率 Write_DS2782_Shadow_RAM(AE3040,0x05); // 空电量斜率 Write_DS2782_Shadow_RAM(AE2030,0x09); // 空电量斜率 Write_DS2782_Shadow_RAM(AE1020,0x12); // 空电量斜率 Write_DS2782_Shadow_RAM(AE0010,0x25); // 空电量斜率 Write_DS2782_Shadow_RAM(SE3040,0x03); // 待机空电量斜率 Write_DS2782_Shadow_RAM(SE2030,0x03); // 待机空电量斜率 Write_DS2782_Shadow_RAM(SE1020,0x05); // 待机空电量斜率 Write_DS2782_Shadow_RAM(SE0010,0x15); // 待机空电量斜率 Write_DS2782_Shadow_RAM(RSGAINMSB, 0x04); Write_DS2782_Shadow_RAM(RSGAINLSB, 0x08); */ Copy_Data_For_Shadow_RAM_To_EEPROM(Copy_data_back_1); printf("\r\n 库仑计设置成功!!\r\n"); }