使用STM32 HAL的I2C通信问题

问题描述

我正在尝试通过I2C将STM32开发板与Arduino连接。

首先,我检查了I2C连接是否与以下示例一起使用: https://www.digikey.be/en/maker/projects/getting-started-with-stm32-i2c-example/ba8c2bfef2024654b5dd10012425fa23

可以,终端打印传感器的温度。

第二,我为Arduino写了一个小草图,显示接收到的I2C消息并使LED闪烁:

#include <Wire.h>
int LED = 13;
int x = 0;
void setup() {
  // Define the LED pin as Output
  pinMode (LED,OUTPUT);
  // Start the I2C Bus as Slave on address 9
  Wire.begin(9); 
  // Attach a function to trigger when something is received.
  Wire.onReceive(receiveEvent);
  Serial.begin(115200);
}
void receiveEvent(int bytes) {
  Serial.println("Data");
  x = Wire.read();    // read one character from the I2C
}
void loop() {
  Serial.println(x);
  //If value received is 0 blink LED for 200 ms
  if (x == 1) {
    digitalWrite(LED,HIGH);
    delay(200);
    digitalWrite(LED,LOW);
    delay(200);
  }
  //If value received is 3 blink LED for 400 ms
  if (x == 4) {
    digitalWrite(LED,HIGH);
    delay(400);
    digitalWrite(LED,LOW);
    delay(400);
  }

这是我针对STM修改代码

buf[0] = REG_TEMP;
        ret = HAL_I2C_Master_Transmit(&hi2c1,TMP102_ADDR,buf,1,HAL_MAX_DELAY);
        if (ret != HAL_OK) {
            strcpy((char*) buf,"Error Tx\r\n");
        } else {

            // Read 2 bytes from the temperature register
            ret = HAL_I2C_Master_Receive(&hi2c1,2,HAL_MAX_DELAY);
            if (ret != HAL_OK) {
                strcpy((char*) buf,"Error Rx\r\n");
            } else {

                //Combine the bytes
                val = ((int16_t) buf[0] << 4) | (buf[1] >> 4);

                // Convert to 2's complement,since temperature can be negative
                if (val > 0x7FF) {
                    val |= 0xF000;
                }

                // Convert to float temperature value (Celsius)
                temp_c = val * 0.0625;

                // Convert temperature to decimal format
                temp_c *= 100;
                sprintf((char*) buf,"%u.%u C\r\n",((unsigned int) temp_c / 100),((unsigned int) temp_c % 100));
            }
        }

        // Send out buffer (temperature or error message)
        HAL_UART_Transmit(&huart1,strlen((char*) buf),HAL_MAX_DELAY);
        HAL_Delay(200);
        //Test an Ardu

        if (HAL_I2C_Master_Transmit(&hi2c1,(9 << 1),(uint8_t*) 0x02,HAL_MAX_DELAY) != HAL_OK) {
            strcpy((char*) buf,"Error Ardu Tx\r\n");
        } else {

            //strcpy((char*) buf,"Error Ardu Tx\r\n");
        }
        HAL_UART_Transmit(&huart1,HAL_MAX_DELAY);

        // Wait
        HAL_Delay(500);

相关部分是该代码

if (HAL_I2C_Master_Transmit(&hi2c1,HAL_MAX_DELAY);

如果Arduino未连接到I2C,终端将显示“ Error Ardu Tx”,因此STM似乎找到了Slave Adress 0x09。

奇怪的是,无论如何,我发送的内容(当前为0x02)是Ardu Terminal打印出奇怪的内容。几乎是“ 84”,但绝不是“数据”。

不确定那里出什么问题了。

也许有些人可以看到错误。在STM方面认为它是正确的。

解决方法

尽管我还没有详细研究您所描述的问题,但是在最后一个代码块中发现了一个指针错误。您正在将类型0x02强制转换为uint8_t *类型(指向uint8_t的指针)。因此,在STM32上,它将有效地用作32位地址(即0x00000002)。这可能是您在Arduino端收到错误数据字节的原因。可以将代码修改为如下形式:

    uint16_t addr = 0x09;
    uint8_t data[] = { 0x02 };
    if (HAL_I2C_Master_Transmit(&hi2c1,(addr << 1),data,sizeof(data),HAL_MAX_DELAY) != HAL_OK) {
        /* ... */
    }