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.

[参考译文] CCS/MSP430FR5969:使用I2C USI_B读取TMP102中的温度时出现问题

Guru**** 2535750 points
Other Parts Discussed in Thread: TMP102

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/581257/ccs-msp430fr5969-problem-to-read-temperature-in-tmp102-using-i2c-usci_b

部件号:MSP430FR5969
主题:TMP102中讨论的其他部件

工具/软件:Code Composer Studio

大家好!

我`m使用Drivelib读取 和配置TMP102来完成I2C的实现,但在读取模式下没有成功。  

设置寄存器0x00 (温度寄存器)后,如下所示: I2C TMP102地址(0x48)在传输数据中(0x90写模式/0x91读取模式)  

要进行设置,我使用了以下代码:  

EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE,TMP102_I2C_ADDRESS);//设置TMP102地址
EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置
EUSCI_B_I2C_masterSendMultiByteStartWithTimeout(EUSSCI_B0_Base,0x00,Timeout_I2C);//使用初始化传输
EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout (EUSCI_B0_BASE,0x00,Timeout_I2C);

while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);

设置寄存器后,我需要开始接收数据。 TMP102发送2字节(MSB和LSB)  

根据示例I编码:  

(I2C,带输出中断模式)  

EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE,TMP102_I2C_ADDRESS);//设置TMP102地址
EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);

//开始发送
EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
While (EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ));

//接收第一个字节
temp_Word[2]= EUSCI_B_I2C_masterReceiveMultiByteNext(EUSI_B0_BUSB);
While (EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ));

//接收第二个字节
temp_Word[1]= EUSI_B_I2C_masterReceiveMultiByteFinish (EUSI_B0_BASE);
While (EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ));

//禁用I2C模块
EUSCI_B_I2C_DISABLE (EUSCI_B0_BASE);

temp_Word_out = Temp_Word[0]<8;
temp_Word_out = Temp_Word_out + Temp_Word[1];
返回Temp_Word_Out;

I2C接收与当前温度兼容的第一个字节(0x16),但在后面停止,如下图所示

有人可以帮助我了解问题出在哪里,我应该怎么做才能解决问题?

1-为什么传输在收到第一个字节后停止?  

2当我发送配置TMP寄存器的命令时,我需要发送两次命令(EUSSCI_B_I2C_masterSendMultiByteFinishWithTime(EUSSCI_B0_Bbase, 0x00, Timeout_I2C);)如果我只输入一个命令,I2C只发送从属地址。 为什么会发生这种情况?

谢谢,顺祝商祺  

 

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

    UCBBUSY在启动后设置,并在停止后清除,因此您将永远被困在While循环内。 您应该轮询UCRXIFG0以查看数据是否就绪,或者使用EUSCI_B_I2CmasterReceiveSingle函数(自动执行此操作),而不是检查UCBBUSY。

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

    你好,Ryan,感谢你的时间和关注。  

    我对代码做了一些修改,发现了一些奇怪的失败。  

     我的第一个例程是设置TMP102,我用0x60A0配置了此温度传感器

    unsigned char TMP102_config(void)

    unsigned char HighByte;
    无符号字符LowByte;
    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;

    HighByte = config_sensor>>8;
    LowByte = CONFIG_SENSOR&0x00FF;

    EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE,TMP102_I2C_ADDRESS);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置
    EUSCI_B_I2C_masterSendMultiByteStartWithTimeout(EUSSCI_B0_BBASE,Conf_Reg,Timeout_I2C);//使用初始化传输
    EUSCI_B_I2C_masterSendMultiByteNextWithTimeout (EUSCI_B0_BASE,HighByte,Timeout_I2C);
    EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout (EUSCI_B0_BASE,LowByte,Timeout_I2C);

    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);


    }

    //检查传输是否超时
    IF (超时计数器== 0)

    STATUS_transmition = 0;
    }
    返回状态_传输;
    }

    完成此例程后,我发送命令读取TMP102,并修改了此波形  

     通过I2C读取变量中的正确数据。  

    使用的代码为  

    无符号int TMP102_READ_Temp (void)

    unsigned char HighByte;
    无符号字符LowByte;
    unsigned char Temp_Word[2];
    无符号int Temp_Word_out;
    unsigned long Timeoutcounter=Timeout_I2C;

    EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE,TMP102_I2C_ADDRESS);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置
    EUSCI_B_I2C_masterSendMultiByteStartWithTimeout(EUSSCI_B0_Base,0x00,Timeout_I2C);//使用初始化传输
    EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout (EUSCI_B0_BASE,0x00,Timeout_I2C);

    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);


    }

    EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE,TMP102_I2C_ADDRESS);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);


    //开始发送
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    While (EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ));
    temp_Word[1]= EUSCI_B_I2C_masterReceiveSingle (EUSCI_B0_BASE);
    temp_Word[0]= EUSCI_B_I2C_masterReceiveSingle (EUSI_B0_BAC_base);
    //禁用I2C模块
    EUSCI_B_I2C_DISABLE (EUSCI_B0_BASE);

    temp_Word_out = Temp_Word[1]<8;
    temp_Word_out = Temp_Word_out + Temp_Word[0];
    返回Temp_Word_Out >>4;
    }

    但在第一个循环之后,代码在 调用函数uint8_t EUSCI_B_I2C_masterReceiveSingle(uint16_t baseAddress)后停止工作。 此函数为DriverLib  


     

    您能帮您了解发生了什么吗?  谢谢,顺祝商祺  

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可能需要在读取最后一个字节并重新开始读取序列后发送停止命令,在禁用通信之前使用ESCI_B_I2C_masterReceiveMultiByteStop,或者在最后一个字节上使用EUSI_B_I2C_masterReceiveMultiByteFinish,而不是ESCI_B_I2C_masterReceiveSingle。

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

    你好Ryan!

    您的回答对我有帮助,但我有一些问题。 事实上,这种I2C驱动程序库解释非常糟糕。

    但好的,去尝试解决我的问题。

    我修复了I2C数据传输的问题,但仅在发送一个字节时才工作。

    我创建了此功能:

    unsigned char I2C_ADDR_DATA_TX (unsigned char addr,unsigned char data)

    unsigned long Timeoutcounter=Timeout_I2C;

    unsigned char status_transmition = 1; //将传输状态设置为1=传输正常

    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE); //启用I2C接口

    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址

    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置

    EUSCI_B_I2C_masterSendSingleByteWithTimeout(EUSSCI_B0_BBASE,DATA,Timeout_I2C);//传输数据

    EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE);

      while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);

      //检查传输是否超时

      IF (超时计数器== 0)

      {

      STATUS_transmition = 0;

      }

      返回状态_传输;

    }

     

    当我在主循环中运行此功能时 ,结果是  

    同时(1)

    __DELAY周期(1.5万次);
    LED_Pilot心脏_位_切换();
    I2C_ADDR_DATA_TX (0x48,0x55)

    }

     


    I2C发送单字节-正常。  

     

    在我的情况下,我需要发送1或2个字节。  

    按照driverlib 手册的想法和简短说明,我更改了函数  

    EUSCI_B_I2C_masterSendSingleByteWithTimeout(EUSSCI_B0_BBASE,DATA,Timeout_I2C);//传输数据单字节  

    用于能够发送多个字节的函数。 我需要开始通信发送多个字节并完成通信。  

    unsigned char I2C_ADDR_DATA_WORD_TXX (unsigned char addr,unsigned char data_a,unsigned char data_b)


    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;//将传输状态设置为1=传输正常
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);//启用I2C接口
    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置
    EUSCI_B_I2C_masterSendMultiByteStartWithTimeout(EUSSCI_B0_BBASE,DATA_A,Timeout_I2C);   <<<发送第一个字节  
    EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout(EUSSCI_B0_BBASE,DATA_b,Timeout_I2C);  <<<发送第二个字节
    //EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE);
    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);
    //检查传输是否超时
    IF (超时计数器== 0)

    STATUS_transmition = 0;
    }
    返回状态_传输;

    }

    //主环路

    同时(1)

    __DELAY周期(150);
    LED_Pilot心脏_位_切换();
    I2C_ADDR_DATA_WORD_TXX (0x48,0x55,0xAA);


    }

    第一个I2C传输 工作正常 (0x48 = 0x90 (I2C ADDR) 0x55和0xAA),但在第一次传输后MCU停止发送第一个字节0x55。  

    我的代码中有什么问题?  

     

    当我去接收TMP102的数据时

    unsigned int I2C_ADDR_RX (unsigned char addr)


    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;//将传输状态设置为1=传输正常
    unsigned char Temp_Word[2];
    无符号int Temp_Word_out;


    I2C_ADDR_DATA_TX (0x48,0x00); //<<此处我配置要读取的寄存器  
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);//启用I2C接口
    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    temp_Word[1]= EUSCI_B_I2C_masterReceiveSingleByte (EUSCI_B0_BASE); //<我在这里收到  
    EUSCI_B_I2C_masterIsStopSent (EUSCI_B0_BASE);
    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);
    temp_Word_out = Temp_Word[1]<8;
    temp_Word_out = Temp_Word_out + Temp_Word[0];
    返回Temp_Word_Out >>4;

    }

     

     


     

    当我在代码中包含第二个字节的读数时:  

     

    unsigned int I2C_ADDR_RX_WORD (unsigned char addr)

    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;//将传输状态设置为1=传输正常
    unsigned char Temp_Word[2];
    无符号int Temp_Word_out;
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);//启用I2C接口
    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    temp_Word[1]= EUSI_B_I2C_masterReceiveMultiByteNext(EUSI_B0_BACB);
    temp_Word[0]= EUSI_B_I2C_masterReceiveMultiByteFinish (EUSI_B0_BASE);
    EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);
    temp_Word_out = Temp_Word[1]<8;
    temp_Word_out = Temp_Word_out + Temp_Word[0];
    返回Temp_Word_Out >>4;

    }

     


     

    只有第一个字节到达。 问题是什么?  

     

    感谢您的关注和诚挚的问候。  

     

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

    对于传输问题,您是否尝试在传输之间使用较长的延迟(1毫秒),或者使用EUSCI_B_I2C_masterSendMultiByteNext和EUSCI_B_I2C_masterSendMultiByteStop?

    对于接收问题,您是否两次尝试使用EUSCI_B_I2C_masterReceiveSingle,然后使用EUSCI_B_I2C_masterReceiveMultiByteStop,并且两次序列之间的延迟较长(2毫秒)? 或者,EUSCI_B_I2C_masterReceiveSingle和EUSCI_B_I2C_masterReceiveMultiByteFinish是否伴有延迟?

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

    现在I2C工作了。 关于数据接收的提示是正确的,我将TX和RX I2C的代码放在下面。  传输提示 不起作用我再次更改了代码,并且函数EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout和 EUSCI_B_I2C_masterSendMultiByteStartWithTimeout 不能正常工作。

    谢谢,现在 与SPI合作。  

     

    unsigned char I2C_ADDR_DATA_WORD_TXX (unsigned char addr,unsigned char data_a,unsigned char data_b)


    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;//将传输状态设置为1=传输正常
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);//启用I2C接口
    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_mode);//在传输模式下设置
    EUSCI_B_I2C_masterSendStart (EUSCI_B0_BASE);
    EUSCI_B_I2C_masterSendMultiByteNextWithTimeout (EUSCI_B0_BBASE,DATA_A,Timeout_I2C);
    EUSCI_B_I2C_masterSendMultiByteNextWithTimeout (EUSCI_B0_BBASE,DATA_b,Timeout_I2C);
    EUSCI_B_I2C_masterSendMultiByteStop(EUSI_B0_base);
    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);
    //检查传输是否超时
    IF (超时计数器== 0)
       {
             STATUS_transmition = 0;
       }
    返回状态_传输;

    }

    unsigned int I2C_ADDR_RX_WORD (unsigned char addr)


    unsigned long Timeoutcounter=Timeout_I2C;
    unsigned char status_transmition = 1;//将传输状态设置为1=传输正常
    unsigned char Temp_Word[2];
    无符号int Temp_Word_out;
    EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);//启用I2C接口
    EUSCI_B_I2C_setSlaveAddress(EUSI_B0_BBASE,addr);//设置TMP102地址
    EUSCI_B_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);
    EUSCI_B_I2C_masterReceiveStart (EUSCI_B0_BASE);
    temp_Word[1]= EUSCI_B_I2C_masterReceiveSingle (EUSCI_B0_BASE);
    temp_Word[0]= EUSCI_B_I2C_masterReceiveSingle (EUSI_B0_BAC_base);
    EUSCI_B_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE);
    while ((EUSSCI_B_I2C_isBusy (EUSSCI_B0_BBASE ))&--Timeoutcounter);
    temp_Word_out = Temp_Word[1]<8;
    temp_Word_out = Temp_Word_out + Temp_Word[0];
    返回Temp_Word_Out >>4;

    }