请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:BQ27441EVM-G1A 我正在尝试更新标称电池容量、一切正常、但当我请求地址0x60获取当前校验和时、我始终返回0。 (请注意、由于编程限制、我请求2个字节)。 如果没有此校验和、我将无法计算新的校验和、因此无法更新电池容量。
出什么问题了? 我可以自己计算校验和吗?
我的代码如下。 我获取校验和的部分在第204行附近。
/* FuelGaug.c * *创建日期:2017年1月6日 * 作者:amorg */ // BQ27441库 #include //电量监测计包括 #include //驱动程序库 #include //标准库包括 #include #include //全局变量 int NUM_OF_REC_Bytes = 0; //保留从电量监测 计 uint8_t RXData[maxNumOfRXBytes]接收的字节数; //从电量监测 计易失性 uint8_t rxFlag = 0接收到的无符号8位命令数组; //接收中断标记 静态易失性 uint32_t xferIndex; // RXData INDEX // I2C 主配置参数 const eUSCI_I2C_MasterConfig i2cConfig = { EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源 80000、 // SMCLK = 8MHz EUSCI_B_I2C_SET_DATA_RATE 100KBPS、 //所需的100kHz I2C 时钟 0、 //无字节计数器阈值 EUSCI_B_I2C_NO_AUTO_STOP //无自动停止 }; void FuelGauge_Setup() { //为 I2C 选择端口6 -将引脚4、5设置为输入主模块功能(UCB1SIMO/UCB1SDA、UCB1SOMI/UCB.S)。 #if SDApin =GPIO_PIN6 && I2Cport =GPIO_PORT_P6 MAP_GPIO_setPeripheralModuleFunctionInputPin (I2Cport、SDApin + SCLpin、GPIO_secondary 模块_function); #else MAP_GPIO_setPeripheralModuleFunctionInputPin (I2Cport、SDApin + SCLpin、GPIO_PRIMARY_MODULE_Function); #endif //以100kbs 的速率将 I2C 主设备初始化为 SMCLK,而不自动停止 MAP_I2C_initMaster (EUSCI_MODULE、&i2cConfig); //指定从机地址 MAP_I2C_setSlaveAddress (EUSCI_MODULE、BQ27441_I2C_ADDRESS); //将主机设置为发送模式 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Transmit 模式); //启用 I2C 模块以启动操作 MAP_I2C_enableModule (EUSCI_MODULE); //启用和清除中断标志,以便在定义页中产生发送中断 MAP_I2C_clearInterruptFlag (EUSCI_MODULE、EUSCI_B_I2C_Transmit INTERRUPT0 + EUSCI_B_I2C_Receive_INTERRUPT0); //启用主机接收中断 MAP_Interrupt_enableInterrupt (EUSCI_moduleINT); } void getStatus(){ int REDO = 0; //获取设备状态 //------ 发送--- 执行{ EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 REDO += MAP_I2C_masterSendMultiByteStartWithTimeout (EUSCI_MODULE、BQ27441_COMMAND_CONTROL、1000); REDO += MAP_I2C_masterSendMultiByteNextWithTimeout (EUSCI_MODULE、BQ27441_CONTRAL_STATUS、1000); REDO += MAP_I2C_masterSendMultiByteNextWithTimeout (EUSCI_MODULE、0x00、1000); REDO += MAP_I2C_masterSendMultiByteStopWithTimeout (EUSCI_MODULE、1000); }while (REDO!= 4); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; } void getFlags(){ //获取电流标志寄存器 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_FLAGS); //发送要读取的字节(低字节) //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; } void setUpdateMode(){ //设置配置更新模式 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_COMMAND_CONTROL); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、BQ27441_CONTRAL_SET_CFGUPDATE); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x00); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); //确保启用 CFGUPMODE。 可能最多需要1秒 while (1) //TODO 不良做法 //使用 flags()(0x06)轮询 Flags(Flags 寄存器,直到 { // CFG_MODE 标志为高电平 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_FLAGS); //发送要读取的字节(低字节) //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; if ((((RXData[0]& BQ27441_FLAG_CFGUPMODE)>> 4)=1) break; //检查 CFG 模式标志 } } void getDeviceType(){ //get 设备类型(0X0421) //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_COMMAND_CONTROL); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、BQ27441_CONTRAL_DEVICE_TYPE); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x00); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、0x00); //------ 接收--- //******** 注释********* num_of _REC_bytes = 2; // NUM_OF_REC_Bytes 只接受2或更大的值 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; } //TODO 在出现故障时退出 FuelGauge_SetBatteryCap (uint16_t batCap) { ////模块重置 // EUSCI_TXBuffer &= 0x00; //清除发送缓冲 器// map_I2C_masterSendMultiByteStart (eUSCI_MODULE、BQ27441_COMMAND_CONTROL); // map_I2C_masterSendMultiByteNext (eUSCI_MODULE、BQ27441_CONTRAL_RESET); // map_I2C_masterSendMultiByteNext (eUSCI_MODULE、 0x00); // map_I2C_masterSendMultiByteStop (eUSCI_MODULE); //------ 发送--- EUSCI_TXBuffer &= 0x00; MAP_I2C_masterSendSingleByte (EUSCI_MODULE、0x0A); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; getStatus(); getFlags(); setUpdateMode(); //启用块数据存储器控制(启用 RAM 访问) //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_extend_control); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x00); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); //访问状态子类 EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_DELEDAND_DATACLASS); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x52); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); //设置要访问的数据锁 EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_extend_DATABLOCK); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x00); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); //发送块校验和命令以检查校验和 EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_extended_CHECKSUM); //TODO 接收校验和、应为1个字节。 似乎没有收到这一信息。 //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; uint8_t OLD_CSUM = RXData[1]; //存储用于计算的旧校验和值 //TODO 我们应该只读取2个字节而不是32个字节。 根据手册、我们只需从2获取电池数据、我们就不必读取整个块 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、0x4A);//BQ27441_DELOCKDATA); //命令返回一个32字节的内存块 //------ 接收--- num_of _REC_bytes = 2;//32; //设置为接收32个字节 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; uint8_t OLD_DESCap_MSB = RXData[0]; //存储旧电池容量最高有效字节值以进行计算 uint8_t OLD_DESCap_LSB = RXData[1]; ///------------------------------ uint8_t batCap_msb = batCap >> 8; //将输入 batCap 向右移动8位以获取 MSByte uint8_t batCap_LSB = batCap; //截断 batCap 以获取 LSByte //设置新的电池电量 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、0x4A); //存储电池容量 MSByte 的存储器位置 MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、batCap_MSB); //这样做实际上不会设置电池容量,只需将其设置为它的样子!!!! 用于 Bat 容量的新 MSByte MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、0x4B); //存储电池容量 LSByte 的存储器位置 MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、batCap_LSB); //这样做实际上不会设置电池容量,只需将其设置为它的样子!!!! 用于 Bat 容量的新 LSByte MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); //计算新校验和 //too 您应该能够在不获取所有字节的情况下执行此操作、仅获取替换的字节。 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_extended_BLOCKDATA); //命令返回一个32字节的内存块 //------ 接收--- num_of _REC_bytes = 32; //设置为接收32个字节 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; ///------------------------------ uint8_t temp =(255 - old_CSUM - old_DESCap_MSB - old_DESCap_LSB)% 256; //计算新校验和 uint8_t new_CSUM = 255 -(temp + batCap_MSB + batCap_LSB)% 256); //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_extended_CHECKSUM); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、NEW _CSUM); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); getStatus(); getFlags(); //软复位 EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendMultiByteStart (EUSCI_MODULE、BQ27441_COMMAND_CONTROL); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、BQ27441_CONTRAL_SOFT_RESET); MAP_I2C_masterSendMultiByteNext (EUSCI_MODULE、0x00); MAP_I2C_masterSendMultiByteStop (EUSCI_MODULE); while (1) //使用 flags()(0x06)轮询 Flags(Flags 寄存器,直到 { // CFG_MODE 标志为高电平 //------ 发送--- EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_FLAGS); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; if ((((RXData[0]& BQ27441_FLAG_CFGUPMODE)>> 4)=0) break; //检查 CFG 模式标志 } getStatus(); getFlags(); } int FuelGauge_GetBatteryCap (void) { //------ 发送--- EUSCI_TXBuffer &= 0x00; MAP_I2C_masterSendSingleByte (EUSCI_MODULE、0x08); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; //------ 发送--- EUSCI_TXBuffer &= 0x00; MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_FUL_Capacity); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; uint8_t batCap_LSB = RXData[0]; uint16_t batCap_MSB = RXData[1]; uint16_t out =(batCap_MSB << 8)| batCap_LSB; 返回; } int FuelGauge_GetStateOfCharge (void) { //------ 发送--- EUSCI_TXBuffer &= 0x00; MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_SOC); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; uint8_t CHARGE_LSB = RXData[0]; uint16_t CHARGE_MSB = RXData[1]; uint16_t out =(CHARGE_MSB << 8)| CHARGE_LSB; 返回; } int FuelGauge_GetVoltage (void) { //------ 发送--- EUSCI_TXBuffer &= 0x00; MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_COMMAND_VOLTAGE); //------ 接收--- num_of _REC_bytes = 2; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_masterReceiveStart (EUSCI_MODULE); //开始接收 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 xferIndex = 0; //将 RXData 索引设置为0 while (rxFlag!= 1); //等待接收到接收中断标志 rxFlag = 0; uint8_t VOLTGE_LSB = RXData[0]; uint16_t VOLTGE_MSB = RXData[1]; uint16_t out =(VOLTGE_MSB << 8)| VOLTGE_LSB; 返回; } void EUSCIB3_Receive (void) { uint_fast16_t status; //标志状态 = MAP_I2C_getEnabledInterruptStatus (EUSCI_MODULE); //抓取触发 的任何标志 MAP_I2C_clearInterruptFlag (EUSCI_MODULE、STATUS); //清除被触发的中断标志 IF (STATUS & EUSCI_B_I2C_Receive_INTERRUPT0) //如果接收的中断标志已经被触发 { if (NUM_OF_REC_Bytes > 1) //如果接收字节数设置为大于1的值 { if (xferIndex = NUM_OF_REC_Bytes - 2) //当 xferIndex 位于第三个到最后一个字节上时 { MAP_I2C_masterReceiveMultiByteStop (EUSCI_MODULE); RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_MODULE); //接收字节并将字节存储到 RXData } 否则、如果(xferIndex = NUM_OF_REC_Bytes - 1) //当 xferIndex 位于第二个到最后一个字节上时 { RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_MODULE); //接收字节并将字节存储到 RXData 中 MAP_I2C_DisableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //禁用接收中断 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Transmit 模式); //将 I2C 模式设置为发送 xferIndex = 0; //清除 RXData 索引 rxFlag = 1; //将接收中断标志置为高电平 num_of _REC_bytes = 0; //清除 NUM_OF_REC_Bytes } 其他 //执行直到 xferIndex 在距 NUM_OF_REC_Bytes 长度2的范围内 { RXData[xferIndex++]= MAP_I2C_ReceivmasterMultiByteNext (EUSCI_MODULE); } } }