请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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; } }