请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:BQ2.7741万-G1 工具/软件:Starterware
您好,
AM读数无效校验和,无法获得预期读数。
我的代码:
#define BQ27441_ADDR 0x55 // taken from datasheet - page 13 #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <math.h> #include <fcntl.h> #include <linux/i2c-dev.h> #include <time.h> #include <sys/time.h> #include <curses.h> #include <wiringPi.h> typedefunsigned charbyte; intdeviceDescriptor; /* This function initializes the I2C device*/ voidinit_i2c(char*DeviceName) { printf("Initialising i2c device \n"); deviceDescriptor=open(DeviceName, O_RDWR); if(deviceDescriptor == -1) { printf("Error opening device '%s' \n",DeviceName); exit(-1); } } /* This function sends data to the I2C device*/ voidI2cSendData(byte addr,byte *data,intlen) { if(ioctl(deviceDescriptor,I2C_SLAVE, addr)) printf("I2cSendData_device : IOCTL Problem \n"); write(deviceDescriptor,data,len); } /* This function reads data from the I2C device*/ voidI2cReadData(byte addr,byte *data,intlen) { if(ioctl(deviceDescriptor,I2C_SLAVE, addr)) printf("I2cReadData_device : IOCTL Problem \n"); read(deviceDescriptor,data,len); } /* Convert the number to hexadecimal representation */ voidto_hex_16(char*output, unsigned n) { staticconstcharhex_digits[] = "0123456789abcdef"; output[0] = hex_digits[(n >> 12) & 0xF]; output[1] = hex_digits[(n >> 8) & 0xF]; output[2] = hex_digits[(n >> 4) & 0xF]; output[3] = hex_digits[(n & 0xF)]; output[4] = '\0'; } /* Computes the checksum by adding the values in the register and then subtracting from 255 */ staticintchecksum(byte *check_data) { intsum = 0; intii = 0; for(ii = 0; ii < 32; ii++) sum += check_data[ii+62]; sum &= 0xFF; return0xFF - sum; } /* getliner() reads one line from standard input and copies it to line array * (but no more than max chars) * It does not place the terminating \n line array. * Returns line length, or 0 for empty line, or EOF for end-of-file. */ intgetliner(charline[], intmax) { intnch = 0; intc; max = max - 1; /* Leave room for '\0' */ while((c = getchar()) != EOF) { if(c == '\n') break; if(nch < max) { line[nch] = c; nch = nch + 1; } } if(c == EOF && nch == 0) returnEOF; line[nch] = '\0'; returnnch; } intmain(intargc, char**argv) { inti, voltage, design_capacity, new_design_capacity, new_design_cap_hex; intdes_cap[10], cksum = 0; byte data[100], writeData[100], unseal_data[10], cfgupdate_data[10], flag_data[10], flag_out[10]; byte block_data_control[10], data_block_class[10], data_block[10], block_data_checksum[10]; byte block_data_checksum_data[10], design_capacity_loc[10], design_capacity_data[10]; byte soft_reset[10], seal_data[10]; floatremaining_batt_cap = 0.0; floatfull_charge_cap = 0.0; floatsoc = 0.0; floattemp = 0.0; floatcurrent = 0.0; charnew_design_cap[7], a[10], b[10], tmp[10]; printf("Inside main \n"); init_i2c("/dev/i2c-1"); writeData[0] = 0x00; writeData[1] = 0x04; unseal_data[0] = 0x00; unseal_data[1] = 0x00; unseal_data[2] = 0x80; cfgupdate_data[0] = 0x00; cfgupdate_data[1] = 0x13; cfgupdate_data[2] = 0x00; flag_data[0] = 0x06; block_data_control[0] = 0x61; block_data_control[1] = 0x00; data_block_class[0] = 0x3E; data_block_class[1] = 0x52; data_block[0] = 0x3F; data_block[1] = 0x00; block_data_checksum[0] = 0x60; design_capacity_loc[0] = 0x4A; soft_reset[0] = 0x00; soft_reset[1] = 0x42; soft_reset[2] = 0x00; seal_data[0] = 0x00; seal_data[1] = 0x20; seal_data[2] = 0x00; /* Unseal the gauge - Refer TRM - Pg-14 */ I2cSendData(BQ27441_ADDR, unseal_data, 3); // #1 I2cSendData(BQ27441_ADDR, unseal_data, 3); delay(5); printf("The gauge seems to be unsealed. \n"); I2cSendData(BQ27441_ADDR, cfgupdate_data, 3); // #2 delay(1000); I2cSendData(BQ27441_ADDR, flag_data, 1); // #3 delay(5); I2cReadData(BQ27441_ADDR, flag_out, 1); printf("The flag_out is: %x \n", flag_out[0]); if(CHECK_BIT(flag_out[0], 4)) { printf("The gauge is ready to be configured \n"); I2cSendData(BQ27441_ADDR, block_data_control, 2); // #4 delay(5); I2cSendData(BQ27441_ADDR, data_block_class, 2); // #5 delay(5); I2cSendData(BQ27441_ADDR, data_block, 2); // #6 delay(5); I2cSendData(BQ27441_ADDR, block_data_checksum, 1); // #7 delay(5); I2cReadData(BQ27441_ADDR, block_data_checksum_data, 1); delay(5); printf("The checksum_data: %x \n", block_data_checksum_data[0]); if(block_data_checksum_data[0] == 0xE8) { printf("The checksum is as expected. Config will proceed. \n"); I2cSendData(BQ27441_ADDR, design_capacity_loc, 1); // #8 delay(5); I2cReadData(BQ27441_ADDR, design_capacity_data, 2); delay(5); //printf("Design capacity data: %x and %x \n", design_capacity_data[0], design_capacity_data[1]); design_capacity = design_capacity_data[0]*16*16 + design_capacity_data[1]; delay(5); printf("The current design capacity is: %d mAh \n", design_capacity); printf("Set new design capacity in mAh (ENTER to continue) ?"); getliner(new_design_cap, 7); if(new_design_cap != EOF && new_design_cap[0] != 0) { printf("Trying to update the design capacity \n"); new_design_capacity = atoi(new_design_cap); // #9 printf("Trying to set new design capacity to: %d \n", new_design_capacity); to_hex_16(tmp, new_design_capacity); for(i = 0; i <= 3; i++) { printf("Output at position %d has %c \n", i, tmp[i]); } des_cap[0] = design_capacity_loc[0]; des_cap[1] = (tmp[0] - '0')*16 + (tmp[1] - '0'); des_cap[2] = (tmp[2] - '0')*16 + (tmp[3] - '0'); printf("Des cap 0: %d ", des_cap[0]); printf("Des cap 1: %d ", des_cap[1]); printf("Des cap 2: %d ", des_cap[2]); I2cSendData(BQ27441_ADDR, des_cap, 3); delay(1000); cksum = checksum(data); // #10 delay(1000); printf("New Checksum found is: %x ", cksum); block_data_checksum[1] = cksum; // #11 I2cSendData(BQ27441_ADDR, block_data_checksum, 2); delay(5); I2cSendData(BQ27441_ADDR, soft_reset, 3); // #12 delay(1000); //printf("Design Cap data 0: %x", data[72]); //printf("Design Cap data :1 %x", data[73]); //design_capacity = data[72]*16*16 + data[73]; I2cSendData(BQ27441_ADDR, flag_data, 1); // #13 delay(5); I2cReadData(BQ27441_ADDR, flag_out, 1); printf("The flag_out is: %x \n", flag_out[0]); if(!CHECK_BIT(flag_out[0], 4)) { printf("CFGUPDTE has been exited, configuration done. \n"); I2cSendData(BQ27441_ADDR, seal_data, 1); // #14 delay(5); printf("Gauge has been sealed and is ready for operation \n"); } //printf("New capacity set as: %d mAh \n", design_capacity); } else{ printf("Design capacity left unchanged. Now at %d mAh \n", design_capacity); } } else{ printf("The checksum is not as expected. Config halt. \n"); } } else{ printf("Cannot proceed with configuration. \n"); printf("The CFGUPDATE MODE has not been enabled yet. \n"); } while(true) { /* Reading the device registers */ I2cSendData(BQ27441_ADDR, writeData, 2); I2cReadData(BQ27441_ADDR, data, 100); voltage = data[4]*16*16 + data[3]; remaining_batt_cap = data[12]*16*16 + data[11]; full_charge_cap = data[14]*16*16 + data[13]; soc = (remaining_batt_cap/full_charge_cap)*100; temp = (data[2]*16*16 + data[1])/10.0 - 273.0; current = data[16]*16*16 + data[15]; printf("Voltage: %d mV\n", voltage); printf("Current: %f mA\n", current); printf("Remaining Battery Capacity: %f mAh\n", remaining_batt_cap); printf("Full Charge Capacity: %f mAh\n", full_charge_cap); printf("State of Charge: %f p.c. \n", soc); printf("Temperature: %f Deg C\n", temp); delay(10000); } close(deviceDescriptor); endwin(); return0; }控制台日志:
这里的标志是:10
校验和数据:ac