主题中讨论的其他器件:MSPM0G3507、 BQ79600-Q1
工具/软件:
我在BMS项目中、遇见菊花链通信的问题!μ s
整个BMS系统构成如下:μ s
整个BMS系统、由MCU μ BQ79758芯片构成、MCU选用MSPM0G3507芯片。MCU与BQ79600芯片之间通过SPI通信连接、BQ79600芯片通过COMHP μ COMHN通过变压器连接至BQ79758芯片的COMHP μ F/COMHN、BQ79758芯片的COMLP与COMLN断开不作连接。μ F
具体操作如下:μ s
系统上电后按照手册《BQ79600-Q1软件设计参考》进行唤醒与自动地址分配。先唤醒BQ79600芯片、检测其DVDD与AVDD电压(电压正常抬起在规定范围)、表示成功唤醒。紧接着发送Tone信号去唤醒BQ79758芯片、Tone信号如图一所示、随后监控BQ79758芯片的DVDD与AVDD电压、检测到其电压抬升到规定电压范围、此时、可表明BQ79758芯片成功唤醒。唤醒之后执行自动分配地址函数、函数如下:μ s
//*************************
//自动寻址序列
//*************************
空 SpiAutoAddress (空)
{
//对 SNCHRONIZE 所有菊花链器件 DLL 进行虚拟写入(如果在此之前发生器件复位)
SpiWriteReg (0、OTP_ECC_DATAIN1、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN2、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN3、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN4、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN5、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN6、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN7、0x00、1、FRMWRT_STK_W);
SpiWriteReg (0、OTP_ECC_DATAIN8、0x00、1、FRMWRT_STK_W);
//启用自动寻址模式
SpiWriteReg (0、CONTROL1、0x01、1、FRMWRT_ALL_W);
//为每个板设置地址
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
SpiWriteReg (0、DIR0_ADDR、currentBoard、1、FRMWRT_ALL_W);
}
//广播写入以将所有器件设置为堆栈器件
SpiWriteReg (0、COMM_CTRL、0x02、1、FRMWRT_ALL_W);
//将堆栈中最高的器件设置为堆栈和栈顶
SpiWriteReg (TOTALBOARDS-1、COMM_CTRL、0x03、1、FRMWRT_SGL_W);
// SYNCRHONIZE 带一个抛出读取的 DLL
SpiReadReg (0、OTP_ECC_DATAIN1、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN2、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN3、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN4、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN5、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN6、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN7、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN8、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
//可选:读回所有设备地址
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
SpiReadReg (currentBoard、DIR0_ADDR、autoaddr_response_frame_Base、1、0 FRMWRT_SGL_R);
}
//可选:读取寄存器地址0x2001并验证该值是否为0x14
SpiReadReg (0、0x2001、autoaddr_Response_frame、1、0、 FRMWRT_SGL_R);
返回;
}
执行完这个函数之后、执行 μ s
WriteReg (0、0x2005、0x0、1、FRMWRT_SGL_W);
WriteReg (0、0x700、0xA5、1、FRMWRT_ALL_W);
delayms (20);//20ms
WriteReg (0、0x701、0x20、1、FRMWRT_ALL_W);
WriteReg (0、FAULT_MSK2、0x40、1、WriteType);
以上就是目前调试执行的相关函数。μ s
遇见的问题:μ s
正常运行完上诉功能函数之后、BQ79758芯片是不会进入ShutDown模式、但是执行完上诉功能函数之后、2S时间到来的时候任然会进入ShutDown模式、通过检测BQ79758芯片的DVDD与AVDD电平在2S后拉低为0得出。μ s
做过的尝试:μ s
首先单独对BQ79600芯片的SPI通信进行测试、通过改写其独有的寄存器再读取对比、验证BQ79600与MCU之间的SPI通信无异常、同时BQ79758芯片可以成功被唤醒、也进一步验证了MCU与BQ79600芯片之间的SPI通信无异常。μ s
在BQ79758芯片数据手册里面看到、一旦BQ79758芯片被成功唤醒就可以执行广播写命令。所以、这里直接尝试、在将BQ79758芯片通过Tone唤醒之后、就发送禁用BQ79758芯片超时功能的指令 μ s
WriteReg (0、0x2005、0x0、1、FRMWRT_SGL_W);
WriteReg (0、0x700、0xA5、1、FRMWRT_ALL_W);
delayms (20);//20ms
WriteReg (0、0x701、0x20、1、FRMWRT_ALL_W);
WriteReg (0、FAULT_MSK2、0x40、1、WriteType);
实际测试后发现、执行完上诉指令后2S后仍然会进入ShutDown模式、通过检测AVDD与DVDD电平可以得出BQ79758芯片进入了ShutDown模式。μ s
BQ79758芯片自动分配地址功能函数里面有读BQ79758芯片和BQ79600芯片的寄存器值的指令。
//可选:读回所有设备地址
for (currentBoard=0;currentBoard<TOTALBOARDS;currentBoard++)
{
SpiReadReg (currentBoard、DIR0_ADDR、autoaddr_response_frame_Base、1、0 FRMWRT_SGL_R);
}
//可选:读取寄存器地址0x2001并验证该值是否为0x14
SpiReadReg (0、0x2001、autoaddr_Response_frame、1、0、 FRMWRT_SGL_R);
这里发现、BQ79600芯片的DIR0 Ω ADDR寄存器值可以读取、BQ79600芯片的0X2001寄存器值可以读取、但是BQ79758芯片的DIRO Ω ADDR寄存器值读取不了。Ω
目前的疑问点:μ s
BQ79758芯片与BQ79600芯片的唤醒标志是否可以依靠芯片的DVDD与AVDD引脚去判断。另外、是否存在即使两个芯片的DVDD与AVDD电压被抬起到要求的电压范围内、芯片任然未成功唤醒的情况。μ s
BQ79758芯片手册提到、芯片唤醒之后就可以接收广播指令。那么是否意味着芯片唤醒之后、就可以直接发送禁用超时功能的指令(指令如下)。这样操作是否符合要求。如果符合要求、这样操作之后BQ79758还会因为Active工作模式下的2S默认超时功能而进入ShutDown状态。μ s
WriteReg (0、0x2005、0x0、1、FRMWRT_SGL_W);
WriteReg (0、0x700、0xA5、1、FRMWRT_ALL_W);
delayms (20);//20ms
WriteReg (0、0x701、0x20、1、FRMWRT_ALL_W);
WriteReg (0、FAULT_MSK2、0x40、1、WriteType);
BQ79758芯片手册提到、Active工作模式下、2S内接收到有效指令会重置超时计数器。这里提到的有效指令是如何定义的。是不是只要协议层通过即认为是有效指令(CRC等)、即使他发送的目的寄存器是无效。例如在自动分配地址下、首先会发送8个虚拟指令去同步时钟、这种指令是否也认为是有效的指令。
系统之前是级联的三个BQ79758芯片、我进行自动地址分配或者是唤醒之后直接发送超时禁用指令。我检测第三个BQ79758芯片的COMM端口的差分信号、对其数据进行解析、发现是可以收到其相关指令。但是BQ79758芯片任然会在指令停止之后的2S后进入ShutDown状态。这里我想提问的点是、物理连接上的最后一个BQ79758芯片已经可以正常接收到相应的指令、是不是意味前前面两个BQ79758芯片、已经正常识别。如果已经正常识别该指令、是不是意味着正常识别该指令的BQ79758芯片就一定能够正常执行该指令。如果不能正常识别该指令、那么又如何解释该指令会向后级芯片发送、这里会不会存在这样一种情况、即使BQ79758芯片不能正确识别该指令、任然可以向后级芯片转发该指令。(也就是、BQ79758芯片的物理通信路径与内部数字电路是完全独立开来的、只有正确识别指令后才会执行相关的指令动作、以及向后级芯片转发、如果不能正确识别指令、也会通过物理通信路径向后级芯片发送该指令)。
测试的过程发现在执行自动地址分配的过程、执行读取函数 μ s
// SYNCRHONIZE 带一个抛出读取的 DLL
SpiReadReg (0、OTP_ECC_DATAIN1、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN2、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN3、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN4、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN5、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN6、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN7、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
SpiReadReg (0、OTP_ECC_DATAIN8、autoaddr_Response_frame、1、0、 FRMWRT_STK_R);
的时候、MCU与BQ79600芯片之间的SPI通信出现、没发送一个SPI读取指令、SPI的RDY引脚就被拉低、直到MCU检测到通信超时后发送COMM Ω CLEAR命令后才会被拉高。随后发送第二个读取命令、SPI的RDY引脚就被拉低、直到MCU检测到通信超时后发送COMM Ω CLEAR命令后才会被拉高。后面依次都是这样。这个一直处于拉低状态是否是因为这几个寄存器是虚拟的寄存器导致的。同时、在自动分配地址阶段即使他是虚拟的寄存器地址也会向后级芯片传递吗?Ω
6.除此之外、关于MSPM0G3507芯片的SPI通信、在这个项目中、需要MCU先发送读命令、发送完之后、还需要发送虚拟数据产生时钟信号去读取BQ79600芯片的数据、但是在之前发送读命令的时候、MCU的FIFO里面有数据了、所以这里、我想要在发送虚拟数据接收来自BQ79600芯片的数据之前清空FIFO、那么这个清空FIFO的函数叫什么、在那个文件可以找到。Ω
最后关于菊花链通信、可以提供一下展开的清晰的波形图、便于我们对比波形、查看差分信号的电平阈值与byte时间、bie时间。
如上所述、麻烦给一下指导和建议。μ s
谢谢!μ s