c - 使用 STM32 HAL 的 I2C 通信问题
问题描述
我正在尝试通过 I2C 将 STM32 板与 Arduino 连接。
首先,我检查了我的 I2C 连接是否正在使用以下示例: https ://www.digikey.be/en/maker/projects/getting-started-with-stm32-i2c-example/ba8c2bfef2024654b5dd10012425fa23
这有效,终端打印传感器的温度。
其次,我为显示收到的 I2C 消息并闪烁 LED 的 Arduino 写了一个小草图:
#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方面认为它是正确的。
解决方案
虽然我还没有详细研究您描述的问题,但我在最后一个代码块中发现了一个指针错误。您正在将类型转换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) {
/* ... */
}
推荐阅读
- ansible - Ansible:如何替换嵌套字典中的值?
- java - 调用放置在另一个类中的另一个函数中的函数
- centos - 具有多个 AD 树的 Freeradius 2.x 到 3.x LDAP 配置
- sql-server - 动态将多行转换为具有多列的一行,pivot 似乎不起作用
- laravel - Laravel 集合组按类似类别名称
- sql - 从表中拉出一个子群体
- javascript - 在从异步函数内部调用它们时,是否有任何理由更喜欢 node.js 中函数的异步版本?
- ember.js - 未捕获的 TypeError:scope.observeChanges 不是函数
- sql - 如何在 Postgres 函数中存储日期变量?
- javascript - 在 forEach 循环中修改对象属性