【问题标题】:I2C Communication Problem using STM32 HAL使用 STM32 HAL 的 I2C 通信问题
【发布时间】:2020-12-19 14:55:06
【问题描述】:

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

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

这行得通,终端打印传感器的温度。

其次,我为 Arduino 写了一个小 Sketch,它显示收到的 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, TMP102_ADDR, buf, 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, buf, strlen((char*) buf), HAL_MAX_DELAY);
        HAL_Delay(200);
        //Test an Ardu

        if (HAL_I2C_Master_Transmit(&hi2c1, (9 << 1), (uint8_t*) 0x02, 1,
        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, buf, strlen((char*) buf), HAL_MAX_DELAY);

        // Wait
        HAL_Delay(500);

相关部分是代码:

if (HAL_I2C_Master_Transmit(&hi2c1, (9 << 1), (uint8_t*) 0x02, 1,
        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, buf, strlen((char*) buf), HAL_MAX_DELAY);

如果 Arduino 未连接到 I2C,则终端会打印“Error Ardu Tx”,因此看起来 STM 找到了从地址 0x09。

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

不知道那里出了什么问题。

也许你们中的一些人会看到错误。在 STM 方面认为它是正确的。

【问题讨论】:

    标签: c arduino embedded stm32 i2c


    【解决方案1】:

    虽然我还没有详细研究您描述的问题,但我在最后一个代码块中发现了一个指针错误。您正在将 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) {
            /* ... */
        }
    

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 2018-08-26
      • 2022-01-20
      • 2022-01-13
      • 2021-08-27
      • 2020-01-12
      • 2017-04-17
      • 2020-07-06
      • 2021-03-04
      相关资源
      最近更新 更多