msp430G2553单片机用HDQ读取bq27541不通讯问题
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
你好,我也遇到和你一样的问题,请问你这个问题解决了吗,是什么原因呢
你好,我也遇到和你一样的问题,请问你这个问题解决了吗,是什么原因呢