This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F5529:使用电池BoosterPack BOOSTXL-BATPAKII时通过I2C的MSP430F5529通信问题

Guru**** 2535710 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/571471/msp430f5529-msp430f5529-communication-issue-over-i2c-with-battery-boosterpack-boostxl-batpakii

部件号:BQ2.7441万-G1MSP430F5529BOOSTXL-BATPAKMKII</s>5529

大家好,

我设置它的方式是MSP430将与 辅助电池增压器组进行主通信。 我已经开发了源代码,它有两个函数用于初始化I2C通信,另一个函数用于获取电池容量。 代码运行,我可以在逻辑上看到它也获得了正确的读取和写入地址。 这是我第一个使用I2C的项目,所以我 对它不是很了解。 在命令代码的第二个字节上,我收到NAK。 我 也没有收到任何返回的数据。  我们将非常感谢您提供任何帮助,帮助您找出问题所在。 提前感谢!

/*
初始化MSP430F5529 LP和Battery
* Booster pack
*/
static void ioport_i2c_init(void)
{
//分配I2C引脚WFP 4.2 (SCL)和WFP 4.1 (SDA)
P4SEL ||(BIT2 | BIT1);
// P4DIR ||(BIT1);

// SMCLK,软件重置启用
UCB1CTL1 || UCSSEL_2 | UCSSWRST;

//主模式,I2C模式,同步模式,10位地址从属模式
UCB1CTL0 = UCMST | UCMODE_3 | UCSYNC;//| UCSLA10;

//波特率:SMCLK (25MHz)/(400kHz)= 62.5 = 0x3E
UCB1BR0 = 0x3E;
UCB1BR1 = 0x00;

//从属地址
UCB1I2CSA = 0x55;

//清除软件重置,以启用操作
UCB1CTL1 ==~UCSWRST;
}/*


此功能获取剩余电池容量。
*
**@返回
*补偿电池剩余容量。 单位为mAh。
*/
uint8_t ioport_GET_BATTERY_capacity (void)
{
//发送器,发送启动条件
UCB1CTL1 || UCTR | UCTXSTT;

//传送中断标志轮询。
while (!(UCB1IFG和UCTXIFG)) //如果UCTXIFG == 0,则等待
{
; //等待TXBUF为空
}

IF (UCB1IFG和UCTXIFG)
{
//发送数据的第一个字节
UCB1TXBUF = 0x02;
printf("sent 0x0d \n");
}
否则
{
printf("Transmit Interrupt pending \n");}


//传送中断标志轮询。
while (!(UCB1IFG和UCTXIFG)) //如果UCTXIFG == 0,则等待
{
; //等待TXBUF为空
}

IF (UCB1IFG和UCTXIFG)
{
//发送数据的第二个字节
UCB1TXBUF = 0x03;
printf("sent 0x0c \n");
}
否则
{
printf("Transmit Interrupt pending \n");}


/*
//传送中断标志轮询。
while (!(UCB1IFG和UCTXIFG)) //如果UCTXIFG == 0,则等待
{
; //等待TXBUF为空
}

IF (UCB1IFG和UCTXIFG)
{
//发送第三个字节的数据
UCB1TXBUF = 0x01;
printf("sent 0x01 \n");
}
否则
{
printf("Transmit Interrupt pending \n");}

*/

//发送停止条件
UCB1CTL1 || UCTXSTP;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//接收到响应时的接收部分

//将主机设置为接收模式,发送启动条件
UCB1CTL1 &=~UCTR;
UCB1CTL1 || UCTXSTT;

//轮询开始位以完成
While (UCB1CTL1和UCTXSTT)
{
;}


//如果RXIE未启用,则轮询RXIFG0
While (UCB1IFG和UCRXIFG)
{
//从收到的数据中读取一个字节
unsigned char PRxData = UCB1RXBUF;
printf ("接收的数据:%c \n",PRxData);

}

//发送停止条件。
UCB1CTL1 || UCTXSTP;

//等待停止完成
While (UCB1CTL1和UCTXSTP)
{
;}


返回0;}


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Anand:

    乍一看,我看到您正在尝试发送0x0D和0x0C,但实际上是在发送0x02和0x03:

    IF (UCB1IFG和UCTXIFG)
    {
    //发送数据的第一个字节
    UCB1TXBUF = 0x02;
    printf("sent 0x0d \n");
    }
    否则
    {
    printf("Transmit Interrupt pending \n");}
    
    
    //传送中断标志轮询。
    while (!(UCB1IFG和UCTXIFG)) //如果UCTXIFG == 0,则等待
    {
    ; //等待TXBUF为空
    }
    
    IF (UCB1IFG和UCTXIFG)
    {
    //发送数据的第二个字节
    UCB1TXBUF = 0x03;
    printf("sent 0x0c \n");
    }
    否则
    {
    printf("Transmit Interrupt pending \n");}
    

    此致,  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    就像电池的剩余容量一样,增压器组件也支持其他几个命令。 所以我只是在尝试这些,但没有运气。 抱歉混淆了,但我对RemainingCapacity()感兴趣的命令是0c0C和0x0D。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,

    感谢您的澄清。 您是否使用了逻辑分析器来观察I2C总线? 您能否提供您所看到内容的屏幕截图? 我将更深入地了解您的代码,并确保您符合与bq2.7441万-G1连接所需的所有要求。

    此致,
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Caleb,

    请从我的逻辑分析器中查找所附的屏幕截图。 我有两个蓄电池增压器包,两个屏幕截图显示了通过在其中每一个电池上运行代码而接收到的输出。 更令我困惑的是,收到的输出是不同的。 我认为在地址0xAA上发回ACK的一个至少显示了一些进展,而另一个不确认发送的地址。 看看您是否可以从这些问题中获得任何有关问题的信息。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Anand:  

    感谢您提供屏幕截图。 这篇以NAK作为回应的文章对我来说很特别。 您是否确保使用了BQ27.4411万-G1数据表中推荐的10K上拉电阻器?

    查看您的代码后,我发现它有一些问题。 要执行预期命令,您可以发送0x0C或 0x0D,并且需要遵循BQ27.4411万-G1数据表中指定的以下格式:

    上图中的MSP430正在执行的操作:

    1. 正在发送启动条件
    2. 正在发送地址0x55
    3. 正在发送写入位
    4. 正在发送命令0x0C或 0x0D
    5. 正在从BQ设备接收ACK
    6. 正在发送启动条件
    7. 正在发送地址0x55
    8. 正在发送读取位
    9. 正在从BQ设备接收ACK
    10. 正在从BQ设备接收数据
    11. 正在发送ACK
    12. 正在从BQ设备接收数据
    13. 正在发送nack
    14. 发送停止

    这可以通过在应用程序中采用以下代码来实现:

    /**
    @通过i2c总线从bq2.7441万-G1短暂接收数据
    *@param
    *@retval 0:正常操作
    * -1:无法读取数据
    */
    int USI_I2C_READ(Char *buffer,int num, int cmd)
    {
    CHAR *PRxData;
    int i=0;
    
    //发送器,发送启动条件,地址+写入
    UCB1CTL1 || UCTR | UCTXSTT;
    
    /*将命令发送到bq2.7441万 */
    IF (UCB1IFG和UCTXIFG)
    {
    UCB1TXBUF = cmd;
    }
    
    //超时
    用于(i=0;i<1000;i++){
    	IF (UCB1IFG和UCTXIFG)
    		中断;
    }
    
    
    /* I2C无法发送命令
    *因此我们无法从bq2.7441万读取数据
    *所以我们回来了
    */
    如果(i == 1000){
    	返回-1;
    }
    /* RX缓冲区开始*/
    PRxData =缓冲区;
    
    //接收器,发送重新启动条件,地址+读取
    UCB1CTL1 &=~UCTR;
    UCB1CTL1 || UCTXSTT;
    
    而(num > 0){
    	对于(i=0;i<1000;i++){
    			IF (UCB1IFG和UCRXIFG){/*
    				加载TX缓冲区*/
    				*PRxData = UCB1RXBUF;
    
    				/* Decrement TX byte counter */
    				num--;
    				PRxData+; 

    UCB1IFG ==~UCRXIFG; Break; } 如果(i == 1000){ 返回-1; } } //发送停止条件。 UCB1CTL1 || UCTXSTP; /*清除USI_B1 TX int标志*/ UCB1IFG &=~UCTXIFG; 返回0;}

    您能否尝试一下并告诉我结果?

    此致,  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢Caleb发送源代码示例。 我已根据它更新了我的代码,我的新代码如下所示:

    /*
    *此功能获取剩余电池容量。
    *
    **@返回
    *补偿电池剩余容量。 单位为mAh。
    */
    uint8_t ioport_GET_BATTERY_capacity (void)
    {
    //发送器,发送启动条件
    UCB1CTL1 || UCTR | UCTXSTT;
    
    //传送中断标志轮询。
    while (!(UCB1IFG和UCTXIFG))
    {
    ;}
    
    
    /*将命令发送到bq2.7441万 */
    IF (UCB1IFG和UCTXIFG)
    {
    //发送数据的第一个字节
    UCB1TXBUF = 0x0c;
    }
    
    int i;
    //超时
    用于(i=0;i<1000;i++)
    {
    IF (UCB1IFG和UCTXIFG)
    中断;
    }
    
    /* I2C无法发送命令,因此我们无法从bq2.7441万读取数据
    *所以就回来吧
    */
    如果(i = 1000)
    {
    返回-1;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //将主机设置为接收模式,发送启动条件
    UCB1CTL1 &=~UCTR;
    UCB1CTL1 || UCTXSTT;
    
    //从收到的数据中读取一个字节
    CHAR *PRxData;
    char *buffer;
    
    /* RX缓冲区开始*/
    PRxData =缓冲区;
    
    用于(i=0;i<1000;i++)
    {
    IF (UCB1IFG和UCRXIFG)
    {
    /*加载TX缓冲区*/
    *PRxData = UCB1RXBUF;
    
    PRxData++;
    
    UCB1IFG &=~UCRXIFG;
    中断;
    }
    }
    
    如果(i = 1000)
    {
    返回-1;
    }
    
    用于(i=0;i<1000;i++)
    {
    IF (UCB1IFG和UCRXIFG)
    {
    /*加载TX缓冲区*/
    *PRxData = UCB1RXBUF;
    
    PRxData++;
    
    UCB1IFG &=~UCRXIFG;
    中断;
    }
    }
    
    如果(i = 1000)
    {
    返回-1;
    }
    
    
    printf ("已接收数据:%s \n",缓冲区);
    
    //发送停止条件。
    UCB1CTL1 || UCTXSTP;
    
    /*清除USI_B1 TX int标志*/
    UCB1IFG &=~UCTXIFG;
    
    返回0;}
    

    现在,在第一次调用 ioport_GET_BATTERY_capacity()之后,我收到第一个字节的数据0x03。 我不确定传入数据是1字节还是2字节。 但看起来它在做一些事情。 如果你能帮我解释收到的数据,那就太好了。 感谢Caleb的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Anand:

    从BQ2.7441万-G1返回的数据长度为2字节,因此您需要从设备读取两次。 例如,在我提供的代码中,从I2C缓冲区读取的while循环需要执行两次(即num =2首先通过循环)。

    我建议您查看BOOTXL-BATTPACK对应的MSP430G2 Launchpad代码,位于:  

    虽然它不适用于您尝试实施的MSP430或电池电量表,但它们非常相似,有助于提供有关连接这两种器件的见解。  

    此致,  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Caleb,

    我已经加入了您发送给我的代码示例。 这些是我得到的结果,仍然没有意义。 (代码是命令I发送到增压器组件,结果是我返回的内容)。
    代码:0x00,结果:3072 (control_status)
    代码:0x02,结果:4.9152万 (温度:0.1K)
    代码:0x04,结果:4.4811万 (电压:0至6000 mV)
    代码:0x06,结果:9997 (标志)
    代码:0x08,结果:1.5361万 (NominalAvailableCapacity:mAh)
    代码:0x0A,结果:1.5365万 (完全可用容量:mAh)
    代码:0x0C,结果:5 (RemainingCapacity:mAh)
    代码:0x0E,结果:0 (FullChargeCapacity:mAh)
    代码:0x10,结果:2.2272万 (AverageCurrent:Ma)
    代码:0x12,结果:6.5021万 (StandbyCurrent)
    代码:0x14,结果:1.9967万 (MaxLoadCurrent)
    代码:0x18,结果:4.5568万 (AveragePower)
    代码:0x1c,结果:0 (StateOfCharge)
    代码:0x1E,结果:4.9152万 (IntTemperature)
    代码:0x20,结果:11 (StateOfHealth()

    我还有一些小的疑问,就是这些命令是传入的2字节,是首先接收MSB还是LSB。 这可能需要对您发送的示例代码的transBytes2Int()进行一些更改。 谢谢...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Anand,

    该量表使用小尾端作为命令,使用大尾端作为数据存储器。

    您的结果看起来不正确。

    请使用 www.ti.com/.../slua801.pdf上的示例
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您共享该资源。 我面临的另一个问题是,大多数时候,在发送首次写入指令后,增压器包不会确认。 我们是否需要唤醒增压器组件或它始终正常工作? (有关更多信息,请从逻辑分析器中找到所附的屏幕截图。) 所以我无法与它进一步沟通。 导致此问题的原因可能是什么?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Anand:

    您使用的是什么值上拉电阻器? 另外,请查看这份关于调试常见eUSCI和USCI串行通信问题的新应用报告: MSP430 MCU上常见eUSCI和USCI串行通信问题的解决方案

    此致,

    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Anand:

    您是否能够解决您遇到的通信问题?

    此致,
    Caleb Overbay