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.
#include <msp430.h>
#define BQ34Z100_ADDR 0xAA // BQ34Z100 地址
#define SOH_ADDR_MSB 0x02 // SOH MSB 地址
#define SOH_ADDR_LSB 0x03 // SOH LSB 地址
volatile unsigned char RXData;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // 关闭看门狗计时器
// 配置 GPIO
P1OUT &= ~BIT0; // 清除 P1.0 输出保持器
P1DIR |= BIT0; // LED 的方向为输出
P1SEL0 |= BIT6 | BIT7; // I2C 端口
// 关闭启动时默认的高阻抗模式,以激活之前配置的端口设置
PM5CTL0 &= ~LOCKLPM5;
// 配置 USCI_B0 模块为 I2C 模式
UCB0CTLW0 |= UCSWRST; // 软件复位使能
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C 模式、主机模式和同步操作
UCB0BRW = 0x0008; // 波特率设置为 SMCLK / 8
UCB0CTL1 &= ~UCSWRST; // 复位结束
UCB0IE |= UCRXIE | UCNACKIE; // 使能接收中断和 NACK 中断
while (1)
{
__delay_cycles(2000); // 等待 2000 个周期
// 发送 I2C 启动条件
// while (UCB0CTL1 & UCTXSTP); // 确保停止信号已发送
UCB0CTL1 |= UCTR | UCTXSTT; // 写入模式的 I2C 启动条件
// while (UCB0CTL1 & UCTXSTT); // 等待启动条件完成
// 发送 BQ34Z100 地址和寄存器地址
UCB0TXBUF = BQ34Z100_ADDR << 1; // 发送 BQ34Z100 的写地址
// while (!(UCB0IFG & UCTXIFG)); // 等待传输缓冲区为空
UCB0TXBUF = SOH_ADDR_MSB; // 发送 SOH MSB 地址
// while (!(UCB0IFG & UCNACKIFG)); // 等待从设备应答
// 发送重复启动条件并读取 BQ34Z100 中的 SOH 数据
// while (UCB0CTL1 & UCTXSTP); // 确保停止信号已发送
UCB0CTL1 &= ~UCTR; // 切换到读取模式
UCB0CTL1 |= UCTXSTT; // 重复启动条件
// while (UCB0CTL1 & UCTXSTT); // 等待重复启动条件完成
UCB0CTL1 |= UCTXSTP; // 第一次接收数据后停止 I2C 通信
// 退出 ISR 前的延迟
__no_operation();
// 进入 LPM0 模式,并启用全局中断
__bis_SR_register(LPM0_bits|GIE);
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch (__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE:
break;
case USCI_I2C_UCNACKIFG:
UCB0CTL1 |= UCTXSTT; // NACK 接收后重新启动条件
break;
case USCI_I2C_UCRXIFG0:
RXData= UCB0RXBUF; // 读取接收到的数据
__bic_SR_register_on_exit(LPM0_bits); // 退出 LPM0 模式
break;
default:
break;
}
}
> P1SEL0 |= BIT6 | BIT7; // I2C 端口
Per data sheet (SLASE59F) Table 6-17, UCB0SDA/SCL are on P1.2/P1.3. This is probably what you're encountering now. Try instead
> P1SEL0 |= BIT2 | BIT3; // I2C 端口
------------
>#define BQ34Z100_ADDR 0xAA // BQ34Z100 地址
Per BQ34Z100 data sheet (SLUSAU1C) Sec 7.2.14.5, the I2C address is 0x55. Try instead:
>#define BQ34Z100_ADDR 0x55 // BQ34Z100 地址
------------
>UCB0TXBUF = BQ34Z100_ADDR << 1; // 发送 BQ34Z100 的写地址
The target I2C address should be assigned to UCB0I2CSA, and should not be shifted. Remove this line, and add this Before setting UCTXSTT:
>UCB0I2CSA = BQ34Z100_ADDR; // 发送 BQ34Z100 的写地址
**Attention** This is a public forum