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.

[参考译文] 编译器/MSP430FR5989:在I2C中重复启动,仅接收一个字节

Guru**** 2587365 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/620119/compiler-msp430fr5989-repeated-start-in-i2c-and-receive-only-one-byte

部件号:MSP430FR5989

工具/软件:TI C/C++编译器

您好,

我遇到了一个问题,在重复的启动序列之后只接收一个字节。  最简单的解释方法是举例说明:

工作箱,带停止/启动序列

  1. Send start / W -在 UCBxCTLW0中设置UCTXSTT和UCTR
  2. 发送字节1
  3. 发送字节2
  4. send stop UCBxCTLW0|=  UCTXSTP
  5. 将模式更改为读取-清除 UCBxCTLW0中的UCTR
  6. Send start / R -在UCBxCTLW0中设置UCTXSTT和UCTXSTP
  7. 仅接收一个字节,之后MCU发送nack和stop。

重复启动序列的非工作案例:

  1. Send start / W - 在  UCBxCTLW0中设置UCTXSTT和UCTR
  2. 发送字节1
  3. 发送字节2
  4. 将模式更改为读取-清除 UCBxCTLW0中的UCTR
  5. 发送START / R - UCTXSTT和UCTXSTP (UCBxCTLW0)
  6. 接收两个字节:第一个字节是ACKed,第二个字节正在等待我的移动

我找到了解决此问题的方法,我正在使用 UCASTPx模式10b,它允许在发送/接收n字节后自动生成停止。 如下所示:

  1. UCBxTBCNT = 0 (将计数器设置为零,什么阻止自动停止生成)
  2. Send start / W - 在  UCBxCTLW0中设置UCTXSTT和UCTR
  3. 发送字节1
  4. 发送字节2
  5. 将模式更改为读取-清除 UCBxCTLW0中的UCTR
  6. UCBxTBCNT = 0x01 (将计数器设置为1 字节)
  7. 发送start / R - UCBxCTLW0中的UCTXSTT
  8. 仅接收一个字节,之后MCU发送nack和stop。

我的问题:

1.为什么在 重复启动模式下设置UCTXSTT和UCTXSTP时I2C工作不正常?

2. 文档中包含一条规定, 只有 在UCSWRST等于1时,才可以修改UCTBCNTx。  我不能满足这一条件,因为它将禁用I2C并释放SCL线路,并且重复启动变得不可能。  我是否要担心这项规定呢?

此致,

Mateusz

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

    《用户指南》的26.3 .5.2 2节说明:

    停止条件由自动停止生成或通过设置UCTXSTP位生成。 从从属设备收到的下一个字节后面是nack和stop条件。 如果eUSI_B模块当前正在等待读取UCBxRXBUF,则会立即出现此错误。

    因此,同时设置TXSTT和TXSTP是正确的。

    代码的描述听起来不错。 显然,代码实际上并不是执行您所描述的操作。

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

    我花了一些时间准备代码,以显示我所写的案例。 有三种情况:

    案例1.

    发送命令后,我发送了停止命令。  然后我设置标记UCTXSTT和UCTXSTP,这使得只接收一个字节。 但由于停止从属设备"忘记"命令并发送错误的答案。

    案例2.

    发送命令后,我发送了重复启动。 我从从属设备收到了正确的答案,但MSP收到了两个字节。

    案例3.

    发送命令后,我会重复发送启动和停止。 我预计MSP会发送重复的启动,并在收到一个字节后发送nack和stop。 但MSP会先发送停止,然后再发送启动(不会重复启动)。  


    以下是代码:

    void i2ctest (void){ volatile uint16_t tmp; prepareDevice(); /*禁用USCI模块并清除控制寄存器的其他位*/ HWREG16(EUHW_B1_BASE + OFS_UCBxCTLW0)= UCSWRST; /*时钟预分频器-频率:100kHz */REFS_REG16 = UHWFS_USB1= UGSI_X64; IB_USB1= UGS10_US_U16 = UFS_USB1= UX64; IB_USB1= UGS_USB1= UGS_X64; IB_US_USB1= UGS10=UGS_XST /* UCCLTO_0 -禁用时钟低超时计数 器* UCAST_1 - UCBCNTIFG设置时字节计数器达到阈值。 * UCGLIT_0 - 50ns无故障时间 */ HWREG16 (EUSCI_B1_BASE + OFS_UCBxCTLW1)= UCCLTO_0 | UCAST_1 | UCGLIT_0; /* 7位地址 * UCMST =主模式 * UCMODE_3 = I2C模式 * UCSSYNC =同步模式 * UEL0,源码:UEL0 SMCLK * UCTR Transmitter */ HWREG16 (EUSSCI_B1_BASE + OFS_UCBxCTLW0)|| UMST + UCMODE_3 + UCSYNC | UCSSEL_3 | UCTR; /*重置UCWRST位以启用I2C模块*/ HWREG16 (EULW_B1_BASE + OFS_USS_3 | UCTXSCI_ST0 ~ =发送状态/USCI0和USCISCI0 ST0 WHREG16 (EUSCI_B1_BASE + OFS_UCBxCTLW0)& UCTXSTT); /*发送命令至SPI从属设备* / WHILE (!(HWREG16 (EUSCI_B1_BASE + OFS_UCBxIFG)& UCTXIFG0); CBREG16 (EUSCI_B1_BASE = UXF+ U21) U21 (USCI_HFS_UXF= U21 ) /*发送停止并等待发送*/ HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)=(HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)和(~UCT))| UCTXSTP; 而(HWREG16(EULWSTP_B1_BASE + OFS_UCTXF)= ~UCTXSCI_US_UCT0)+ UCTXSCIF_USC1= UCTXSCIF_USC1= UCTXSCIF_UCTXSCIF_USC1= UCTXSCIF_USC1= UCTXSCI0 /*发送重复启动*/ HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)=(HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)&(~UCT))| UCTXSTT; 中断; 案例3: /*发送重复启动和停止*/ REG16(EUSCI_UCTFS_USCI_21 = USCI_21 = USCI_SCI_SC1;~USC1= UGFS_XSC1= USC1; USC1= USC1; USC1= USC1= USC1= USC1; USCF_XSCF; USC1= USCF_XSCF; USCF; USCF_XSC1= USCF; USCF; USC1= USCF; USC1= UXSCF_XSCF; U HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)|= UCTXSTP; tmp = HWREG16(EUSI_B1_BASE + OFS_UCBxRXBUF); while (1); }

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

    您的代码与driverlib的EUSCI_B_I2C_masterReceiveSingleByte()之间的唯一区别是后者使用两个单独的指令来清除UCTR并设置UCTXSTT+UCTXSTP。 我本来以为只能使用“&=”和“|=”,但您的波形显示硬件将TXSTP应用于传输事务。

    因此,当使用重复启动时,您实际上必须在TXSTP之前更改UCTR:

    	案例3:
    		/*发送重复启动和停止*/
    		HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)&=~UCTR;
    		HWREG16(EUSSCI_B1_BASE + OFS_UCBxCTLW0)|| UCTXSTT | UCTXSTP;