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.

[参考译文] MSP430F2619:I2C 重复启动示例代码要求

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1377680/msp430f2619-i2c-repeated-start-sample-code-requirement

器件型号:MSP430F2619

工具与软件:

我正在尝试实现与从 IC 的 I2C 通信。 从器件为 ACS37800电源监控 IC。 目标
使用上述格式执行 I2C 读取操作。


该用例需要重复启动条件、我只能找到传统 I2C 从器件读取的示例代码(即没有重复启动)。
能否为 MSP430F2619提供用于实现重复启动的示例代码。

这是我尝试实现的[ SCL @ 143KHz]

#include

//定义全局变量
unsigned char RXData、Master_RX、TXByteCtr = 0、RXByteCtr = 4;// RXByteCtr 设置为要读取的字节数
int i、c=0;
unsigned char RXDataarr[15]={1、2、3、4、5、6、7、8、9、10、11、12、13、14、15};

//函数原型
void Master_TX_TO_RX_Slave (void);
空 MasterUSCIB0TX (空);

int main (void)

WDTCTL = WDTPW + WDTHOLD;//停止 WDT

P3SEL |= 0x06;//将 I2C 引脚分配至 USCI_B0

while (1)


Master_TX_to_RX_Slave ();//执行主器件 TX 到 RX 从器件通信
___ BIC_SR_register (GIE);
//清除通用中断使能
}
}

// USCI_B0 Data ISR1
#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR (void)
#elif defined (_GNUC__)
void __attribute__(((interrupt (USCIAB0TX_vector))) USCIAB0TX_ISR (void)
#else
错误编译器不受支持!
#endif

如果(Master_RX = 0)

if (TXByteCtr =1)
{__delay_cycles (50);
UCB0TXBUF = 0x20;//发送寄存器地址
TXByteCtr --;
}
设计

MASTER_RX = 1;
//c=1;
UCB0CTL1 &=~μ s UCTR;//切换到 RX 模式
UCB0CTL1 |= UCTXSTT;//发送重复启动条件

}//do
//{
}

如果(Master_RX =1)

if (UCB0CTL1 & UCTXSTT)//确保发送启动条件
返回;
RXDataarr[c]= UCB0RXBUF;
C++;

if (c==8)

UCB0CTL1 |= UCTXSTP;//发送停止条件
IE2 &=~UCB0TXIE;
IE2&=~UCB0RXIE;
C=0;
}
}

}//ISR


//此函数用于启动主器件 TX 到 RX 从器件的通信
void Master_TX_TO_RX_Slave (void)

MasterUSCIB0TX ();

__bis_SR_register (GIE);//启用常规中断
TXByteCtr = 1;//加载 TX 字节计数器

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

//添加超时机制以防止无限循环

while (UCB0CTL1和 UCTXSTT);

__bis_SR_register (GIE);//启用中断
while (UCB0CTL1 & UCTXSTP);//确保发送了停止条件
}

//配置 USCI_B0以进行主传输的函数
空 MasterUSCIB0TX (空)

UCB0CTL1 |= UCSWRST;//启用软件复位
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
UCB0BR0 = 7;//设置 SCL 频率1MHz/7 ~~ 143Khz
UCB0BR1=0;
UCB0I2CSA = 0x7F;//设置从器件地址(根据需要进行调整)
UCB0CTL1 &=~μ s UCSWRST;//清除软件复位、恢复操作
MASTER_RX = 0;//初始化 Master_RX 标志
IE2 |= UCB0TXIE + UCB0RXIE;//启用 TX 和 RX 中断
}


上述代码通过 ISR 迭代9次、以接收4个字节的从器件数据。 传输部分更易于理解、但我不明白接收部分的原因
需要迭代9次才能接收4个字节的从器件数据。 当它应该理论上只迭代4次。 我通过反复试验得到该值9、仅进行了4次迭代
产生少于4个字节的结果、并以 I2C 通信的过早终止结束。

即使接收到4个字节、RXIFG 标志仍然保持置位、这也是需要关注的领域、因为我预计会在4个字节后终止通信。

对于此问题发生的原因、任何类型的解决方案或建议都将非常有帮助。

此致、

Anand 与

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

    TI 示例 MSP430x261x_USCI_i2c_standard_master.c 使用重复启动来实现 I2C_Mode Master_Read ()。 (查找 SWITCH_TO_RX_MODE。)

    [编辑:对不起,我忘记了这个链接:

    https://dev.ti.com/tirex/explore/node?node=A__AEJIFApgaCbL04wfEfe6XQ__msp430ware__IOGqZri__LATEST

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

    感谢 Bruce、感谢您在提供信息链接方面提供的及时帮助。 我使用了代码逻辑本身、并刷写了它。 我没有得到任何数据作为回报。  

    我已验证硬件端是否完好无损。 执行新代码后、满足返回启动条件、但不返回数据。 对此有什么解决方案吗?

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

    您如何判断未返回任何数据? NACK? 总线挂起? 无 RXIFG 中断?

    在 main()中、它从寄存器0读取1个字节、从寄存器1开始读取2个字节、从寄存器2开始读取6个字节。 (它也会写入寄存器3、4和5、这可能合适、也可能不合适。) 结果 进入数组 SlaveType[0/1/2];您在那里看到了什么吗?

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

    q1) 如何判断不返回数据?

    我使用示波器来监控 SDA 和 SCL 线路、并且没有发送任何数据或时钟、一旦我单步执行代码、我就会看到 TXIFG 标志未设置、ISR 也未被遍历。 有时数据会与源代码一起正确遍历传输、但示波器随后仅显示发送部分。 我希望通过示波器捕获 RX 位。 我在 Master_Read while (1)持续运行的循环中包含了函数调用语句、即 I2C_INCLA (SLAVE_ADDR、CMD_TYPE_0_SLAVE、TYPE_0_LENGTH);。

    Q2)查看 main()、它从寄存器0读取1个字节、从寄存器1开始读取2个字节、从寄存器2开始读取6个字节。 (它也会写入寄存器3、4和5、这可能合适、也可能不合适。) 结果 进入数组 SlaveType[0/1/2];您在那里看到了什么吗?

    在我的代码中、我已更改代码行 "#define TYPE_0_LENGTH 4"、以便从从从设备读取4个字节。

    在 main()中、我根据我的用例注释了3个编写函数调用和其余的两个读取函数调用、因此 main 函数仅包括:


    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

    initClock4.12.4C() 16MHz;
    initGPIO();
    initI2C();

    while (1)

    I2C_4.54 Master_Read (SLAVE_ADDR、CMD_TYPE_0_SLAVE、TYPE_0_LENGTH);

    }

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

    您的 ACS37800是如何安装的? 这是商用分线板吗? 我不知道如何配置 DIO_0/_1。

    我不确定如何处理数据表表2、因为(1) DIO_0/_1是单值的(2) DIO_2不存在(3)"配置 DIO 引脚"部分(第21页)讨论了 LOW=1。 我不知道我相信任何一个。 因此、我来回顾 SparkFun 对该器件的看法、即默认 I2C 地址(DIO_0/_1拉至 GND)为0x60。

    https://cdn.sparkfun.com/assets/1/9/f/6/9/Qwiic_Power_Meter-ACS37800_Schematic.pdf

     但是、这似乎确实是确认0x7F;让我感到困惑的是、这是一个保留的 I2C 地址、尽管(据我所知)它当前没有使用。

    没错、在任何情况下、示波器引线都看起来为奇数。 引入人工延迟(__delay_cycles (500)或类似延迟)来查看 I2C 单元认为事务开始/结束的位置可能会很有用