Arduino向STM32通过I2C传输数组或整数时遇到问题
Arduino(从机)与STM32(主机HAL库)I2C通信异常问题
现状与问题
- STM32作为I2C主机,向Arduino从机发送整数、整数数组、uint8_t字符串数组均正常,可通过UART终端验证接收结果。
- STM32接收Arduino发送的String类型数据正常(Arduino端需用
Wire.write(Message.c_string()))。 - 异常情况:
- 接收Arduino发送的单个整数时,STM32的UART终端无任何输出。
- 接收Arduino发送的整数数组时,终端显示与数组长度一致的不可见字符,确认有数据接收,但无法判断是数据错误还是显示方式问题。
STM32端main函数代码(UART、I2C配置已确认正确)
/* On STM32. I'm just sharing the main function to avoid to flood the topic. Please be assured that all the other stuff, as UART or I2C configuration, is done properly*/ int main(void) { HAL_StatusTypeDef retour_i2c; uint8_t message_envoye[] = "Hello World !!"; uint8_t entier_envoye = 32; uint8_t tableau_envoye[] = {1, 2, 3, 4}; uint8_t message_recu[10]; uint8_t entier_recu; uint8_t tableau_recu[4]; // My Arduino is sending an array of 4 integers HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); MX_I2C1_Init(); I2C_Verif_Addresses(); while (1) { // Transmition part is OK retour_i2c = HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(I2C_SLAVE_ADDR << 1), tableau_envoye, sizeof(tableau_envoye), 1000); if(retour_i2c != HAL_OK){ I2C_Error_Handler(&hi2c1); } else{ HAL_Delay(1000); HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); } // Reception part is not OK // retour_i2c = HAL_I2C_Master_Receive(&hi2c1, (uint16_t)(I2C_SLAVE_ADDR << 1), message_recu, sizeof(message_recu), 1000); // "strings" are working retour_i2c = HAL_I2C_Master_Receive(&hi2c1, (uint16_t)(I2C_SLAVE_ADDR << 1), tableau_recu, sizeof(tableau_recu), 1000); // Receiving an array cause invisible characters to be printed // retour_i2c = HAL_I2C_Master_Receive(&hi2c1, (uint16_t)(I2C_SLAVE_ADDR << 1), entier_recu, sizeof(entier_recu), 1000); if(retour_i2c != HAL_OK){ I2C_Error_Handler(&hi2c1); } else{ HAL_Delay(1000); HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); HAL_UART_Transmit(&huart2, tableau_recu, sizeof(tableau_recu), 10); } } }
问题原因及解决办法
核心原因:参数传递错误 + 终端显示逻辑偏差
整数/数组显示为不可见字符的原因
你用HAL_UART_Transmit直接发送uint8_t类型的整数/数组,终端会把这些数值当作ASCII码解析。比如数值1对应ASCII控制字符SOH,数值2对应STX,这类字符本身不可见,所以终端显示空白或乱码。而字符串能正常显示,是因为字符串元素都是可见字符的ASCII码。接收单个整数无反应的原因
看注释掉的接收代码:retour_i2c = HAL_I2C_Master_Receive(&hi2c1, ..., entier_recu, sizeof(entier_recu), 1000);
这里犯了参数传递错误:HAL_I2C_Master_Receive的第三个参数需要指针类型(内存地址),你直接传了entier_recu(变量值),而非&entier_recu(变量地址)。这会导致I2C接收时写入错误内存区域,要么程序异常,要么没接收到正确数据,所以终端无输出。
解决步骤
修复单个整数接收的参数错误
修改接收代码为:retour_i2c = HAL_I2C_Master_Receive(&hi2c1, (uint16_t)(I2C_SLAVE_ADDR << 1), &entier_recu, sizeof(entier_recu), 1000);正确显示整数/数组数据
不能直接把数值通过UART发送给终端,需先将数值转换为ASCII字符串再发送。可以用标准库sprintf实现:
数组显示示例:else{ HAL_Delay(1000); HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); // 转换数组为字符串后发送 char uart_buf[50] = {0}; int len = sprintf(uart_buf, "Received array: %d, %d, %d, %d\r\n", tableau_recu[0], tableau_recu[1], tableau_recu[2], tableau_recu[3]); HAL_UART_Transmit(&huart2, (uint8_t*)uart_buf, len, 10); }单个整数显示示例:
char uart_buf[20] = {0}; int len = sprintf(uart_buf, "Received integer: %d\r\n", entier_recu); HAL_UART_Transmit(&huart2, (uint8_t*)uart_buf, len, 10);确认Arduino端发送逻辑
确保Arduino端按字节发送数值本身,而非转换为字符串。比如发送数组的代码:int data[] = {1,2,3,4}; Wire.write((uint8_t*)data, sizeof(data));发送单个整数的代码:
int num = 100; Wire.write((uint8_t*)&num, sizeof(num));注意:若Arduino发送的是16位
int类型,STM32端需用对应长度的变量(如uint16_t)接收,避免数据截断。
内容的提问来源于stack exchange,提问作者Tsu'Na
相关产品推荐
相关产品推荐

