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.

[参考译文] MSP430F2132:MSP430FR2311 I2C 总线通信无法正常工作。

Guru**** 2511985 points
Other Parts Discussed in Thread: MSP430F2132, MSP430FR2311

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/671388/msp430f2132-msp430fr2311-i2c-bus-communication-not-working-properly

器件型号:MSP430F2132
主题中讨论的其他器件: MSP430FR2311

大家好、

我在 MSP430FR2311和 MSP430F2132之间实现了 I2C 总线通信。
MSP430FR2311用作主器件
MSP430F2132用作从器件

我要执行的任务是:

从主器件侧 USCI 产生 STAT 条件并将从器件地址(0x48)发送到从器件、从器件在同一启动条件下响应一个字节的数据(从器件向主器件发送一个字节的数据)。
从从器件接收到一个字节的数据后、主器件再次在同一 I2C 总线上传输两个字节的数据 从器件应接收与主器件发送的相同的2字节数据。

下面这个代码中的问题是这样的  
当主器件发送起始条件、从器件接收起始条件、从器件在相同的起始条件下向主器件响应一个字节的数据时、首次发生此情况
2.在主器件向从器件写入两个字节的数据后,从器件成功地接收到该数据。
3、第二次主器件发送启动条件从器件没有响应。

我能帮我解决这个问题吗?

这是 I2C 主设备代码


:#include 
易失性 int Rx_Data、Tx_Data1[]={0x85、0xC8};
int TXByteCtr = 2、RXByteCtr = 0;
int rx_operation_completed = 0;
int main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器

//禁用 GPIO 上电默认高阻抗模式
//激活先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;

//为 I2C 配置引脚
P1SEL0 |= BIT2 | BIT3; // I2C 引脚配置



//将 USCI_B0配置为 I2C 模式
UCB0CTLW0 |= UCSWRST; //将 eUSCI_B 置于复位状态
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;// I2C 主控模式、SMCLK
UCB0CTLW1 |= UCASTP_2; //生成自动停止
UCB0BRW = 0x8; //波特率= SMCLK /8
UCB0I2CSA |= 0x0048; //从机地址
UCB0CTLW0 &=~ UCSWRST; //清除复位寄存器


while (1)
{


while (UCB0CTL1 & UCTXSTP); //确保发送了停止条件
UCB0CTL1 |= UCTXSTT; // I2C 启动条件
UCB0IE = UCRXIE0;
_bis_SR_register (GIE); //全局中断启用

__NO_OPERATION ();

IF (Rx_OPERATY_END_= 1)
{
RX_OPERAING_END_RELASD = 0;
TXByteCtr = 2;
UCB0IE |= UCTXIE0 | UCNACKIE; // Tx 中断使能并发送一个 NACK

while (UCB0CTLW0和 UCTXSTP); //确保发送了停止条件
UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX、启动条件

_bis_SR_register (GIE); //全局中断启用

while (TXByteCtr > 0)
{
__no_operation();
}

__no_operation();

}
}

#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector = USCI_B0_vector
__interrupt void USCIB0_ISR (void)
#elif defined (__GCUN__)
void __attribute__((interrupt (USCI_B0_vector)#interrupt

) USCIB0_ISR (void)(void USCIB0!)编译器错误!
#endif
{
switch (__even_in_range (UCB0IV、USCI_I2C_UCBIT9IFG))
}
USCI_NONE 案例:中断; //向量0:无中断中断;
USCI_I2C_UCALIFG 案例:中断;
USCI_I2C_UCNACKIFG 案例:
UCB0CTL1 |= UCTXSTT; //如果 NACK,则重新发送启动条件
中断; //向量4:NACKIFG 中断;
案例 USCI_I2C_UCSTTIFG:中断; //向量6:STTIFG 中断;
案例 USCI_I2C_UCSTPIFG:中断; //向量8:STPIFG 中断;
USCI_I2C_UCRXIFG3案例:中断; //向量10:RXIFG3中断;
USCI_I2C_UCTXIFG3案例:中断; //向量14:TXIFG3中断;
USCI_I2C_UCRXIFG2案例:中断; //向量16:RXIFG2 break;
USCI_I2C_UCTXIFG2案例:中断; //向量18:TXIFG2中断;
USCI_I2C_UCRXIFG1案例:中断; //向量20:RXIFG1 break;
USCI_I2C_UCTXIFG1案例:中断; //向量22:TXIFG1中断;
USCI_I2C_UCRXIFG0案例:
{
RX_Data = UCB0RXBUF;
RX_OPERAING_Completed = 1;
}
中断; //向量24:RXIFG0中断;
USCI_I2C_UCTXIFG0案例:
{
TXByteCtr --; //减少 Tx 计数器
IF (TXByteCtr) //检查 TX 字节计数器
{
UCB0TXBUF = Tx_Data1[TXByteCTR]; //将数据加载到 TX 缓冲区
_DELAY_CYCLES (100); //传输之间的延迟
}
其他
{
UCB0TXBUF = Tx_Data1[TXByteCTR]; //将数据加载到 TX 缓冲区
UCB0CTLW0 |= UCTXSTP; // I2C 停止条件
UCB0IE &=~UCTXIE0; //清除 USCI_B0 TX int 标志
_DELAY_CYCLES (1000000); //传输之间的延迟
}
}
中断; //向量26:TXIFG0中断;
案例 USCI_I2C_UCBCNTIFG:break; //向量28:BCNTIFG
USCI_I2C_UCCLTOIFG 案例:中断; //向量30:时钟低电平超时
USCI_I2C_UCBIT9IFG 案例:中断; //向量32:第9位
默认值:中断;
}
} 

这是 I2C 从设备代码

:#include 
int TXByteCtr = 0、RXByteCtr = 0;
volatile int Rx_Data[2];
volatile int Tx_Data = 0x44;
int main (void)
{
WDTCTL = WDTPW + WDTHOLD; //停止 WDT 计时器

P3SEL |= 0x06; //将 I2C 引脚分配给 USCI_B0
UCB0CTL1 |= UCSWRST; //启用 SW 复位
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C 从设备,同步模式
UCB0I2COA = 0x48; //自有地址为048h
UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
UCB0I2CIE = UCSTTIE; //启用 STT 中断
IE2 = UCB0TXIE; //启用 RX 中断

while (1)
{
_bis_SR_register (GIE);
__NO_OPERAT();
}
}-->-----------------


// USCI_B0状态 ISR 用于将 CPU 从 LPM0唤醒、以便在
数据传输后在主程序中进行//处理。 当

实际数据被发送时、LPM0只在(重新) START 或 STOP 条件下//退出。
///----------------------------------
#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector = USCIAB0RX_Vector
__interrupt void USCIAB0RX_ISR (void)
#Elif defined (__GNU__)
void __attribute__((interrupt (USCIAB0RX_ISR)#vector

(void) USCIA0RX_ICUICUICURX_ICURX_ICURX_ISR (void))#defineer_ICUICRx_ICUAR
#endif
{
UCB0STAT &=~UCSTTIFG; //清除中断标志
}


// USCI_B0数据 ISR
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = USCIAB0TX_Vector
__interrupt void USCIAB0TX_ISR (void)
#Elif defined (__GCU_systems_ICC_)#pragma vector = USCIAB0TX_Vector
(void

)(void USCIA0TX_B0TX_ISR)(void)(void)(void)#interrupt COMPUSCIA0TX_ISR (void)(void)(void)
#endif
{
if (IFG2 & UCB0RXIFG)
}
RX_Data[RXByteCTR]= UCB0RXBUF; //获取 RX 数据
RXByteCtr +; //递增 Rx 计数器
if (RXByteCtr > 1)
{
RXByteCtr = 0;
IE2 = UCB0TXIE; //启用 RX 中断
}
}
否则
{
IF (IFG2 & UCB0TXIFG)
{

UCB0TXBUF = Tx_Data;
IE2 = UCB0RXIE;

}
}


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在主器件代码中、在启动主器件发送模式之前设置 UCTR 位、但在再次启动主循环时不会将其复位、因此主器件继续在主器件发送模式下运行。 在开始任何事务之前、您应该始终显式设置或清除此位。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Andrei、

    感谢您的建议。
    它在工作


    此致、
    开尔文