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.

[参考译文] MSP430G2533:I2C主控-->从属:地址被传输,但从属设备在第一个字节后没有响应,ACK也取决于上拉电阻

Guru**** 2539570 points
Other Parts Discussed in Thread: MSP430G2533, MSP430G2553, RF430FRL152H

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/577378/msp430g2533-i2c-master----slave-address-is-transmitted-but-the-slave-does-not-respond-after-first-byte-also-ack-depends-on-the-pull-up-resistor

部件号:MSP430G2533
主题中讨论的其他部件:MSP-EXP430G2MSP430G2553RF430FRL152H

我正在尝试使用I2C协议在MSP-EXP430G2评估板(具有 MSP430G2533微控制器)和照片探测器(从属)之间进行通信。  

我已将2.2 K欧姆从SDA和SCL线路上拉拔的外部电阻器连接到VDD (3.4 电压)。  

从属地址为0x2A。  

与从属设备通信的协议要求我存储了TX_DATA[8]阵列的以下序列(如下图所示)。  

我正在使用的代码粘贴在此处。 问题在于: 我要么没有从从机收到ACK信号(这发生在90 % of the Times,并带有一些随机的上拉值),要么有时当我得到除地址之外的ACK信号时,没有其他数据被传输(这只发生在10 % of the time)。

当我在CCS Studio中单步执行代码时,代码卡在I2C传输中断中: __bis_sr_register(CPUOFF + GIE);     并且不会出现。  

是否有人知道为什么会这样? 或者以前有人遇到过类似的问题吗? 我们非常感谢您的任何帮助。  

//与I2C从属设备通信,以便从光检测器传输数据
//此处使用TI开发入门套件板
#include <MSP4S.h>
/*
主要c
*/
void I2C_Initialize (void);
void I2C_Transmit (void);
void I2C_receive (void);

Int TransmitByteCtr = 8;
unsigned char PointerRxData;//指向RX数据的指针
Int Rx = 0;
unsigned char TX_data[8]={0x2A, 0x00, 0x89, 0x2A, 0x00, 0x09,0x2A,0x03};

INT MAIN ( void )

WDTCTL = WDTPW + WDTHOLD;//停止WDT
//disable_INT;//禁用所有中断
//ClockInitialize();
//两者都是端口1:端口1.6 端口1.7 位是使用端口寄存器为I2C设置的,SDA = 1.7 WFP SCL = 1.6 //
P1DIR |= 0xC0;
P1SEL || BIT6 + BIT7;//将I2C引脚分配给USI_B0 //
P1SEL2|= BIT6 + BIT7;//将I2C引脚分配给USI_B0
I2C_Initialize();
同时(1)

//传输过程
Rx = 0;
I2C_Transmit();
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件

//接收过程
Rx = 1;
I2C_receive();
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
}
}

//------------------
// USI_B0数据ISR用于移动从I2C从属设备接收的数据
//至MSP430内存。 它的结构可以用于接收
//------------------
#pragma vector = USCIAB0TX_vector
__interrupt void USCIAB0TX_ISR(void)

如果(Rx == 1)
{//主中继器接收?
PointerRxData = UCB0RXBUF;//获取RX数据
__BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出LPM0
}

否则
{//主传输
IF (TransmitByteCtr <8)//检查TX字节计数器

UCB0TXBUF = TX_DATA[TransmitByteCtr ];//加载TX缓冲区
TransmitByteCtr ++;// Decrement TX字节计数器
}
否则

UCB0CTL1 || UCTXSTP;// I2C停止条件
IFG2 &=~UCB0TXIFG;//清除USI_B0 TX int标志
__BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出LPM0
}
}
}

Void I2C_Initialize (void)(Void I

IE2 |= UCB0RXIE;//启用RX中断
IE2 |= UCB0TXIE;//启用TX中断
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
UCB0CTL1 || UCSWRST;//启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCSNC;// I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用SMCLK,保持SW重置
UCB0BR0 = 12;// fSCL = SMCLK/12 =~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x2A;//从属地址为02Ah
UCB0CTL1 &=~UCSWRST;//清除软件重置,恢复操作
}

void I2C_Transmit (void)

// while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
UCB0CTL1 || UCTR + UCTXSTT;// I2C TX,启动条件
__bis_sr_register(CPUOFF + GIE);//输入带中断的LPM0
}

void I2C_receive (void)

UCB0CTL1 &=~UCTR;//清除UCTR
while (UCB0CTL1和UCTXSTP);//确保已发送停止条件
UCB0CTL1 || UCTXSTT;// I2C启动条件
While (UCB0CTL1和UCTXSTT);//启动条件已发送?
UCB0CTL1 || UCTXSTP;// I2C停止条件
__bis_sr_register(CPUOFF + GIE);//输入带中断的LPM0
}

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

    您好,

    您是否正在使用逻辑分析器查看设备之间的通信? 您能否提供您所看到的失败和"成功"的屏幕截图? 另外,从属设备建议用于上拉电阻器的值是多少?

    代码__bis_sr_register(CPUOFF + GIE)的一部分将设备置于低功耗模式(LPM),然后在中断服务例程(ISR)中完成其余处理。 如果在ISR内设置了断点,则应看到该代码正在执行。

    我将仔细查看您的代码,如果发现异常情况,请告诉您。 我还建议您查看应用报告: MSP430 MCU上常见eUSCI和USCI串行通信问题的解决方案

    此致,
    Caleb Overbay

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

    您在这方面是否取得了进展? 我对代码的一个评论是,您将TransmitByteCtr初始化为8,然后在ISR中有一个IF语句“IF (TransmitByteCtr <8)",该语句的计算结果始终为false。

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

    您好,Caleb,

    是的,我确实取得了进展,能够成功地从主中继器传输数据。

    我现在需要一些有关代码Rx部分的帮助。

    此序列之后,主中继器请求从属设备在SDA线路上读取数据,但是主中继器必须生成数据时钟,您是否有任何线索可以说明如何生成8字节数据的读取ISR`?

    读取这些数据后,下一步是将它们存储在内存中。 有什么提示?

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

    您好,

    使用I2C读取数据肯定比写入更困难。 它取决于从设备数据表中指定的读取协议,因此请务必熟悉它。 通常情况下,顺序如下:

    1. 发送启动序列
    2. 发送R/W位低的从属地址
    3. 发送注册号
    4. 再次发送启动序列(重复启动)
    5. 发送R/W位高的从属地址
    6. 读取数据字节
    7. 发送停止序列

    另外,请注意何时发送停止序列。 在MSP430G2553上,停止序列必须在收到的第N个字节上发送。  MSP430 MCU上常见eUSCI和USCI串行通信问题解决方案的5.2 和5.3 章节 将更详细地介绍此内容以及器件用户指南。

    最后,我附上了一些执行I2C读写的示例代码,MSP430G2553作为主机。 此代码遵循我以前链接到的应用程序报告中指定的顺序。 请将此作为如何从I2C从属设备读取多个或单个字节的指南。

    e2e.ti.com/.../8358.main.c

    此致,
    Caleb Overbay  

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

    您好,

    感谢您的回答。 如果我要将相同的代码移植到TI RF430FRL152H芯片上,它是否工作? 我的意思是,MSP430的架构和寄存器集是否兼容? 如果不是,我需要做出哪些改变?

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

    您好,

    否此代码不适用于RF430FRL152H,因为MSP430G2553使用USCI模块进行通信,而RF430FRL152H 使用eUSCI模块。 您可以在此处找到有关在两个模块之间切换的信息: Migrating from the USCI Module to the eUSCI Module

    此致,  
    Caleb Overbay