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.

msp430G2553单片机用HDQ读取bq27541不通讯问题

Other Parts Discussed in Thread: MSP430G2553, EV2400, MSP430F149

TI官网用的是单片机MSP430F2xx,读取端口用的是P1.1,用定时器TA0,来读取BQ27541,我们改用的单片机是MSP430G2553,用P2.0端口,定时器用TA1,我把官网提供的单片机程序该位以下,但是读不出数据,,请大神帮我看看是什么问题,谢谢!

#include <io430g2553.h>
#include "HDQ.h"
#include "in430.h"

enum
{
  imWrite,
  imWriteE,
  imRead,
  imReadE,
  imDelay
};

// Local variables
//中断服务程序的模式
static unsigned char ISRMode;
//接收到的数据
static unsigned char Xfer;
//发送数据的位数
static unsigned char BitCnt;
//记录时间戳
static unsigned int Ticks;

void HDQdelay(void)
{
  __delay_cycles(500000);                       // Delay before next operation
}

static void HDQBreak(void)
{
  TA1CCR0 = TA1R + tBreak;                        // Break time
  TA1CCTL0 = OUTMOD_0 + CCIE;                    // Reset OUT0, enable int
  ISRMode = imDelay;                            // Set ISR mode
  LPM0;                                         // Wait for ISR completion
  TA1CCR0 += tBR;                                // Break recovery time
  TA1CCTL0 = OUTMOD_0 + OUT + CCIE;              // Set OUT0, enable int
  LPM0;                                         // Wait for ISR completion
}

static void HDQBasicWrite(unsigned char Data)
{
  Xfer = Data;
  TA1CCTL0 = OUTMOD_0;                           // Reset OUT0

  TA1CCR0 = TA1R;
  Ticks = TA1CCR0;                               // Bit start time stamp

  if (Xfer & BIT0)                              // LSB == 1?
    TA1CCR0 += tHW1;                             // Output '1'
  else
    TA1CCR0 += tHW0;                             // Output '0'
 
  TA1CCTL0 = OUTMOD_4 + CCIE;                    // Toggle OUT0 on EQU0, en. int
  BitCnt = 8;                                   // 8 bits to transfer
  ISRMode = imWrite;                            // Set ISR mode
  LPM0;                                         // Wait for ISR completion
}

void HDQSetup(void)
{
  P2DIR &= ~BIT0;                             // P2.x as input
  P2SEL |= BIT0;                              // Select TA1 function
  DCOCTL = CALDCO_8MHZ;                         // Set DCO for 8MHz using
  BCSCTL1 = CALBC1_8MHZ;                        // calibration data in Info Flash
  BCSCTL2 = DIVS_2;                             // SMCLK = (DCO / 4)
  _EINT();
}

void HDQWrite(unsigned char Addr, unsigned char Data)
{
  TA1CTL = TASSEL_2 + MC_2;                      // SMCLK, continuous mode
  P2DIR |= BIT0;                              // P2.x as in output
  HDQBreak();                                   // Send HDQ break
  HDQBasicWrite(Addr | 0x80);                   // Write to Addr
 
  TA1CCR0 += tCYCH;                              // Insert delay
  TA1CCTL0 = OUTMOD_0 + OUT + CCIE;              // Set OUT0, enable int
  ISRMode = imDelay;                            // Set ISR mode
  LPM0;                                         // Wait for ISR completion  
 
  HDQBasicWrite(Data);                          // Write Data
  P2DIR &= ~BIT0;                             // P2.x as in input
  TA1CTL = 0;                                    // Stop Timer_A
  HDQdelay();                                   // Allow some recovery time
}

unsigned int HDQRead(unsigned char Addr)
{
  TA1CTL = TASSEL_2 + MC_2;                      // SMCLK, continuous mode
  P2DIR |= BIT0;                              // P2.x as in output
  HDQBreak();
  HDQBasicWrite(Addr);
  P2DIR &= ~BIT0;                             // P2.x as in input

  BitCnt = 8;                                   // 8 bits to transfer
  ISRMode = imRead;                             // Set ISR mode

  TA1CCTL0 = CM_2 + CCIS_0 + SCCI + CAP + CCIE;  // Capt. falling edge of P2.0
  TA1CCR1 = TAR + tTO;                           // Time-Out
  TA1CCTL1 = CCIE;                               // Enable Time-Out
  LPM0;                                         // Wait for ISR completion
  TA1CTL = 0;                                    // Stop Timer_A

  if (BitCnt)                                   // All bits received?
    return HDQ_ERROR;                           // Error condition (Time-Out)
  else
    return Xfer;                                // OK
}

#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer_A0_ISR(void)
{

  switch (ISRMode)
  {
    case imWrite :
      if (--BitCnt)                             // Decr and check
      {
        TA1CCR0 = Ticks + tCYCH;                 // Time to cycle completion
        ISRMode = imWriteE;                     // Switch ISR mode
      }
      else
      {
        TA1CCTL0 = OUTMOD_0 + OUT;               // Set OUT0, disable int
        __bic_SR_register_on_exit(LPM0_bits);   // Return active
      }
      break;
    case imWriteE :
      Ticks = TA1CCR0;                           // Bit start time stamp
        
      if ((Xfer >>= 1) & BIT0)                  // Process next bit
        TA1CCR0 += tHW1;                         // Output '1'
      else
        TA1CCR0 += tHW0;                         // Output '0'
        
      ISRMode = imWrite;                        // Switch ISR mode
      break;
    case imRead :
      TA1CCTL1 = 0;                              // Disable Time-Out
      TA1CCR0 += (tDW0 + tDW1) / 2;              // Time to middle of bit
      TA1CCTL0 &= ~CAP;                          // Compare mode
      ISRMode = imReadE;                        // Switch ISR mode
      break;
    case imReadE :
      Xfer >>= 1;                               // Process next bit
      if (TA1CCTL0 & SCCI)                       // Check Timer_A latch
        Xfer |= 0x80;
      if (--BitCnt)                             // Decr and check
      {
        TA1CCTL0 |= CAP;                         // Capture mode
        TA1CCR1 = TA1R + tTO;                     // Time-Out
        TA1CCTL1 = CCIE;                         // Enable Time-Out
        ISRMode = imRead;                       // Switch ISR mode     
      }
      else
      {
        TA1CCTL0 = OUTMOD_0 + OUT;               // Set OUT0, disable int
        __bic_SR_register_on_exit(LPM0_bits);   // Return active
      }
      break;
    case imDelay :
      TA1CCTL0 &= ~CCIFG;                        // Disable int
      __bic_SR_register_on_exit(LPM0_bits);     // Return active
      break;
  }
}

#pragma vector = TIMER1_A1_VECTOR
__interrupt void Timer_A1_ISR(void)
{
  if (TA1IV == 0x02)                             // Timer_A.CCR1
  {
    TA1CCTL0 = 0;                                // Disable receiption
    TA1CCTL1 = 0;                                // Disable Time-Out
    __bic_SR_register_on_exit(LPM0_bits);       // Return active
  }
}

  • 有没有用EV2400和上位机软件EVSW同HDQ端口进行通讯,确认电池包可以在HDQ下正常通讯?

  • 用EV2003试过了,可以,而且我用I2C写是可以通讯的,换成HDQ就不可以了,我认为可能是我的程序哪里有问题,但是我找了好久,没有找到,请帮我看下,谢谢。电路图见附件,谢谢

  • BQ27541的I2C端口和HDQ端口是二选一的关系,不是两个端口同时都能工作的。BQ27541默认是工作在I2C端口下。要在HDQ下工作,需要专门的命令把I2C通讯转换成HDQ通讯。

  • 代码是什么,能告诉下吗?然后,我听说转换过去了是不可逆的,是吗?非常感谢!

  • 而且,我门这里有一个工程师说,他用ev2300读bq27541,用I2C和HDQ都可以,没有转换也可以读写

  • 可以参考这个文档:http://www.ti.com/lit/pdf/slua504。相关部分如下:

    STEP 4: Writing the DFI at Production
    Pack PCB designers must ensure that the I2C lines of bq2754x are accessible at time of writing DFI in
    production, if the device is intended to be used as a single-wire, communication-enabled device. It is
    expected that the pack manufacturers add the Write DFI step within their final complete system test that
    verifies the product to be functional for release to market. The flowcharts in Figure 8, Figure 9, and
    Figure 10 show the steps that must be followed to write the DFI created with the bqEASY™ software
    using their own test setup. Test developers can use the flowchart to call I2C commands with their test
    setup and program all the flash of the bq2754x.
    If customers develop their own tools to program the DFI and need to set the device to HDQ mode, the
    following steps are required.
    After writing the DFI but before sending the commands to exit ROM mode, send the following commands:
    (a) I2C Command 0x00: Byte 0x16
    (b) I2C Command 0x04: Byte 0x05
    (c) I2C Command 0x64: Byte 0x1B
    (d) I2C Command 0x65: Byte 0x00
    Finish the programming process by exiting ROM mode and sending the following commands:
    (a) I2C Command 0x00: Byte 0x0F
    (b) I2C Command 0x64: Byte 0x0F
    (c) I2C Command 0x65: Byte 0x00

  • 解决了,是通讯方式的问题,我把一个bq27741的转成HDQ模式就可以了,非常感谢!^V^

  • 张工:

             您好!

             请问一下,HDQ读出来的数据不稳定是什么原因?有的时候读的是对的,有的时候是错了,有的时候,一部分数据是对的,另外一部分又是错的,是什么原因?

  • 用msp430F149可以读吗

  • 没有这款单片机,只有g2553

  • 准备放弃了EV2300

    读CHEM_ID 等读不到

    这个表无法读到数据

    Table 2. Control( ) Subcommands

    电压电流其他的都可以读

    Table 1. Standard Commands

  • 张工:

       您好!

       HDQ可以通讯了,但是读出来的数据不准确,请问是什么原因?程序是官网提供的,时序没有改,请问是什么原因,谢谢!

        #define ClkFreq     2000000u                    // Timer clock frequency (Hz)
    //------------------------------------------------------------------------------
    // Define HDQ Protocol Related Timing Constants
    //------------------------------------------------------------------------------
    #define tBreak      (190 * ClkFreq / 1000000)   // HDQ Break Time (190us)
    #define tBR         (40 * ClkFreq / 1000000)    // HDQ Break Recovery Time (40us)
    #define tHW1        (40 * ClkFreq / 1000000)    // Host sends 1 time (40us)
    #define tHW0        (123 * ClkFreq / 1000000)   // Host sends 0 time (123us)
    #define tCYCH       (230 * ClkFreq / 1000000)   // Host bit window timing (230us)
    #define tDW1        (41 * ClkFreq / 1000000)    // Slave sends 1 time (41us)
    #define tDW0        (113 * ClkFreq / 1000000)   // Slave sends 0 time (113us)
    #define tTO         (500 * ClkFreq / 1000000)   // Time-Out Bit Receiption (500us)

    #define HDQ_ERROR 0x0000                        // Time-Out Error Condition

  • 你好,我也遇到和你一样的问题,请问你这个问题解决了吗,是什么原因呢

  • 你好,我也遇到和你一样的问题,请问你这个问题解决了吗,是什么原因呢