我正在尝试与 BQ27441电池电量监测计通信。 我的 I2C 通信在大多数情况下工作正常、但代码中有一个部分需要接收单字节校验和(其他情况和错误发生)。 当我使用 driverlib 函数接收单个字节时、我会得到2个字节!
我已附加了 driverlib 安装代码、问题代码和中断代码。
我还包括了 I2C 线路上发生的情况的逻辑分析仪输出。 正如您在下面看到的、我为寄存器写入0x60、然后我尝试读取一个字节、我返回0x00+ACK 和0x00+NACK。
设置:
- I2C 引脚6.6和6.7
- 1K 上拉
- 100kbps
- 总线上只有 BQ27441
- 该代码最初来自驱动程序库示例、但经过大量修改、以满足我们的需求
问题代码:
//发送块校验和命令以检查校验和 EUSCI_TXBuffer &= 0x00; //清除发送缓冲区 MAP_I2C_masterSendSingleByte (EUSCI_MODULE、BQ27441_extended_CHECKSUM); num_of _REC_bytes = 1; MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Receive_mode); //设置为接收模式 MAP_I2C_enableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //启用接收中断 uint8_t OLD_CSUM = MAP_I2C_ReceivmasterSingleByte (EUSCI_MODULE); rxFlag = 0; MAP_I2C_DisableInterrupt (EUSCI_MODULE、EUSCI_B_I2C_Receive_INTERRUPT0); //禁用接收中断 MAP_I2C_setMode (EUSCI_MODULE、EUSCI_B_I2C_Transmit 模式); //将 I2C 模式设置为发送 xferIndex = 0; //清除 RXData 索引
设置代码:
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 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); } }否则{ rxFlag = 1; //将接收中断标志置为高电平 num_of _REC_bytes = 0; //清除 NUM_OF_REC_Bytes } }