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.

[参考译文] MSP430FR5043:使用 MSP430 API 与 HDC2022进行 I2C 连接

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1065506/msp430fr5043-i2c-interfacing-with-hdc2022-using-msp430-api

器件型号:MSP430FR5043
主题中讨论的其他器件: HDC2022

你(们)好

我正在尝试使用提供的 API 将 HDC2022与 MSP430FR5043连接。 我能够通过单独的代码读取温度、器件 ID、寄存器、但当尝试一个接一个地读取时、读取的值会损坏。 当按下 RESET 并再次引导 MSP430时、它能够正确读取第一个寄存器。 在需要的任何地方添加延迟函数。

请在此处告诉我可能出现的问题。

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

    您好!

    这似乎很奇怪。 您使用哪个 API 来连接 HDC2022?

    此致、

    现金 Hao

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

    您好!

    请找到以下代码。

    uint8_t i2c_read_temp(uint8_t reg_address)
    {
        uint8_t temp = 0;
    
        while (EUSCI_B_I2C_SENDING_STOP
                == EUSCI_B_I2C_masterIsStopSent(EUSCI_B1_BASE))
            ;
    
        Serial_String("\r\n");
        Serial_String("out of first while loop in i2c read");
    
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B1_BASE, reg_address);
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, reg_address);
    
        Serial_String("\r\n");
        Serial_String("Reading from register");
    
        //  printf(test, "%d ", reg_address);
    
        //Serial_String("\r\n");
    
        //Serial_String("out of mastersend func in i2c read");
        __delay_cycles(1000);
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
        //Serial_String("\r\n");
        // Serial_String("out of second while loop in i2c read");
    
        EUSCI_B_I2C_masterReceiveStart(EUSCI_B1_BASE);
    
        temp = EUSCI_B_I2C_masterReceiveSingle(EUSCI_B1_BASE);
    
        EUSCI_B_I2C_masterReceiveMultiByteStop(EUSCI_B1_BASE);
    
        return temp;
    }
    
        LSB = i2c_read_temp(0xFE);
    
        MSB = i2c_read_temp(0xFF);

    这里 LSB = i2c_read_temp (0xFE);给出 D0、但   MSB = i2c_read_temp (0xFF);给出72。

    当延迟后在循环中逐个调用函数时、会观察到这种情况。

    但是、当只调用函数时、我会观察到 LSB 为 D0、MSB 为7、这是数据表中正确的。

    请检查。

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

    您好

    等待回复。

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

    你(们)好

    请回复。

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

    您好、Vivin、

    现在我不知道为什么每次调用一次读取函数时、读取函数可以正常工作。

    您可以使用示波器或逻辑分析仪来捕获 I2C 信号吗? 和比较 连续和单独调用读取函数之间的信号。

    这可以为我们提供一些解决此问题的线索。

    此致、

    现金 Hao  

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

    您好

    请参阅随附的 I2C 屏幕截图。

    我们观察到 HDC IC 在每次读取时都提供了适当的寄存器值、因此做出了正确响应、但 我们发现以下问题。

    考虑我们正在按以下顺序读取寄存器。

    LSB1 = i2c_read_temp (0xFE)-- D0

    MSB1 = i2c_read_temp (0xFE)-- 07

    LSB2 = i2c_read_temp (0xFC)-- 49

    MSb2 = i2c_read_temp (0xFD)-- 54

    这里我们正确地获得了 LSB1和 MSB 1、但对于 LSB2、我们得到0x07 (对应于上一步中读取的 I2C 数据)和 MSB 2为0x49 (对应于上一步中读取的 I2C 数据)。

    在数据被清除之前、MSP 缓冲区中的数据似乎没有被清除或中断被清除。

    请告诉我如何解决此问题。 使用的代码与上面显示的代码相同。

    此致、

    Bivin

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

    你(们)好

    请更新

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

    您能否发布 I2C 初始化代码?  EUSCI_B_I2C_masterReceiveSingle()关心 UCRXIE0是否被置位。

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

    大家好

    请参阅以下代码。

    void i2c_reinit(void)
    {
        GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN5);
        GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN6);
    
        GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN5 + GPIO_PIN6);
    
        __delay_cycles(1000000);
    
        GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN5 + GPIO_PIN6);
    
        GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_P5,
                                                   GPIO_PIN5 + GPIO_PIN6,
                                                   GPIO_SECONDARY_MODULE_FUNCTION);
    
        Serial_String("\r\n");
        Serial_String("I2C re-initialization is started");
    
        EUSCI_B_I2C_initMasterParam param = { 0 };
    
        param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
        param.i2cClk = CS_getSMCLK();
        param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
        param.byteCounterThreshold = 0;
        param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        EUSCI_B_I2C_initMaster(EUSCI_B1_BASE, &param);
    
        //Specify slave address
        EUSCI_B_I2C_setSlaveAddress(EUSCI_B1_BASE, SLAVE_ADDRESS);
    
        //Set Master in receive mode
        EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    
        //Enable I2C Module to start operations
        EUSCI_B_I2C_enable(EUSCI_B0_BASE);
    
        EUSCI_B_I2C_clearInterrupt(
                EUSCI_B1_BASE,
                EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    
    }
    
    
    void i2c_write(uint8_t reg_address, uint8_t data)
    {
    
        while (EUSCI_B_I2C_SENDING_STOP
                == EUSCI_B_I2C_masterIsStopSent(EUSCI_B1_BASE))
            ;
        Serial_String("\r\n");
        Serial_String("Starting write operation");
    
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B1_BASE, reg_address);
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, reg_address);
        Serial_String("\r\n");
        Serial_String("reg address sent");
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
    
        Serial_String("\r\n");
        Serial_String("ack received");
    
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, data);
        EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B1_BASE, data);
        Serial_String("\r\n");
        Serial_String("data sent");
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
    
        Serial_String("\r\n");
        Serial_String("data ack received");
    
        EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
    
    }
    

    我们首先调用 i2c_reinit(),然后调用 i2c_write(),再调用 i2c_read_temp()。

    请发表评论。

    此致、

    Bivin

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

    我在这里看不到任何明显的错误。 驱动 i2c 引脚(即使是1秒)也是非常不寻常的,尽管如果您只执行一次(曾经),我不能想到会给您带来麻烦的原因。 话虽如此,是否有理由这样做?

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

    大家好

    仅出于测试目的添加了1秒延迟。 没有具体原因。

    您提到"EUSCI_B_I2C_masterReceiveSingle()关心 UCRXIE0是否被置位。"、这是上述代码中的一个问题。

    我们观察到的是,如前所述,从寄存器读取的数据将在下一次 I2C 读取时出现。 是否有方法在读取操作之前清除 I2C 读取缓冲器或 FIFO。

    请发表评论。

    此致、

    Bivin

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

    您的症状表明,有些东西没有等待 UCRXIFG 升高。 ReceiveSingle 仅在 UCRXIE=0时等待、因此我正在寻找对 EUSCI_B_EnableInterrupt 的调用、我在这些片段中看不到该调用。

    是否可以在"Registers"视图中对 ReceiveSingle 的调用和 EUSCI_B1配置的屏幕截图处断点? 这肯定会告诉我们。

    未经请求:对 I2C_ENABLE 的调用引用了 EUSCI_B0、而不是 B1。 我想知道是否有另一个对 I2C_ENABLE 的调用。