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.

[参考译文] MSP430F5249:通过I2C读取时出现问题

Guru**** 2614265 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/664823/msp430f5249-problem-with-reading-over-i2c

部件号:MSP430F5249

您好,

我在试图通过I2C读取时遇到了一个非常奇怪的问题。 第一次写入和读取操作正常。 但是,第二次写入失败。

我正在一次写入一个字节的两字节寄存器地址,然后更改为读取模式以执行读取。 我的代码如下所示。

静态void StoreRegisterAddress(const I2CAddressSize register_size, const uint16_t register_address)
{
UINT8_t索引= 0;
regAddressSize =寄存器大小;

//注册地址的MSB优先
开关(寄存器大小)
{
Case I2CAddressSizeTwoBytes:
regAddress[index++]= MSB16 (register_address);
//不中断-有意
案例I2CAddressSizeOneByte:
regAddress[index++]= LSB16 (register_address);
中断;
默认:
//不写入任何内容
break;
}
}

void WriteToI2CSlave (const uint8_t slaver_address,const I2CAddressSize register_size,const uint16_t register_address,const uint8_t *data,const uint8_t size)
{
txMasterSize =(大小<= MaxI2cBufferLength)? 大小:MaxI2cBufferLength;
txMasterCount =0;
memcpy(txMasterData, data, txMasterSize);
UCB0I2CSA = slaver_address;//设置从属地址
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
StoreRegisterAddress(register_size, register_address);
UCB0CTL1 || UCTR + UCTXSTT;// I2C TX,启动条件
__no_operation();
}

void ReadFromI2CSlave(const uint8_t slaver_address, const I2CAddressSize register_size, const uint16_t register_address, const uint8_t size)
{
rxMasterSize =(大小<= MaxI2cBufferLength)? 大小:MaxI2cBufferLength;
rxMasterCount = rxMasterSize;
pRxMasterData = rxMasterData;
UCB0I2CSA = slaver_address;//设置从属地址
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
StoreRegisterAddress(register_size, register_address);
UCB0CTL1 || UCTR + UCTXSTT;//进入写入模式并开始发送
__no_operation();
}//

USI_B0数据ISR -这是PMU <-->从属设备
#if defined(__TI_Compiler_version__)的中断服务例程|| defined(__IAR_systems_icc__)
#pragma vector = USI_B0_vector
__interrupt void USI_B0_ISR(void)
#Elif defined(__GNUC__)
void __attribute__((interrupt (USCI_B0_vector)) USI_B0_ISR (void)
#else
#error编译器不受支持!
#endif
{
SWITCH(__EIV_IN_RANGE(UCB0IV,12))
{
案例0:中断; //矢量0:无中断
案例2:中断; //矢量2:ALIFG
案例4: //矢量4:NACKIFG
{
UCB0CTL1 || UCTXSTP; //当缺少确认时,从属设备获得停止条件
UCB0IFG &=~UCTXIFG;
中断;
}
案例6:中断; //向量6:STTIFG
案例8:中断; //矢量8:STPIFG
案例10: //矢量10:RXIFG
{
IF (rxMasterSize == 1)
{
IF (rxMasterCount > 0)
{
UCB0CTL1 || UCTXSTP; //生成I2C停止条件
*pRxMasterData = UCB0RXBUF; //将最终RX数据移至rxMasterData
--rxMasterCount;
}
否则
{
UCB0IFG &=~UCRXIFG; //清除USI_B0 RX int标志
readMasterData =真;
__BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出低功耗模式
}
}
否则
{
--rxMasterCount;

IF (rxMasterCount)
{
*pRxMasterData++= UCB0RXBUF; //将RX数据移动到rxMasterData地址
IF (rxMasterCount == 1) //只剩下一个字节?
{
UCB0CTL1 || UCTXSTP; //生成I2C停止条件
}
}
否则
{
*pRxMasterData = UCB0RXBUF; //将最终RX数据移至PRxData
UCB0IFG &=~UCRXIFG; //清除USI_B0 RX int标志
readMasterData =真;
__BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出低功耗模式
}
}

中断;
}
案例12: //矢量12:TXIFG
{
IF (regAddressSize >0)
{
//发送注册地址
UCB0TXBUF = regAddress[I2cMaxRegisterSize - regAddressSize];
--regAddressSize;
}
否则
{
IF (rxMasterCount > 0)
{
UCB0IFG &=~UCTXIFG;
UCB0CTL1 &=~UCTR; //进入阅读模式
UCB0CTL1 || UCTXSTT; // I2C启动条件
}
否则
{
IF (txMasterCount < txMasterSize) //检查TX字节计数器
{
UCB0TXBUF = txMasterData[txMasterCount+];//加载TX缓冲区和增量TX字节计数
器}
否则
{
UCB0CTL1 || UCTXSTP; // I2C停止条件
UCB0IFG &=~UCTXIFG; //清除USI_B0 TX int标志
sentMasterData =真;
__BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出低功耗模式
}
}
}
中断;
}
默认值:break;
}
}

 在TXIFG案例栏中出现以下行后,程序似乎总是失败:

如果(rxMasterCount > 0)
{
UCB0IFG &=~UCTXIFG;
UCB0CTL1 &=~UCTR; //进入阅读模式
UCB0CTL1 || UCTXSTT; // I2C启动条件
... 

我不明白为什么这是第一次,而不是第二次!

有人能告诉我什么错了吗?

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

    您好,Jacob,

    我建议您查看 MSP430 MCU上常见eUSCI和USCI串行通信问题的解决方案 ,以了解这是否有助于解决您的问题。

    此致,

    Britta.

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

    我想您可以继续处理您的应用程序,因为您不再回复,所以我将关闭此帖子。
    如果您需要进一步的帮助,请再次发表意见,它将重新打开线程。

    此致,
    Britta.