You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现树莓派3通过I2C向STM32F205发送浮点数据

树莓派3 I2C主设备发送浮点数据实现

1. 依赖安装

先安装树莓派I2C操作的Python库:

sudo apt-get install python3-smbus2

2. Python发送代码

模拟原Arduino的浮点数据字节化逻辑(默认小端字节序,与Arduino/STM32的浮点存储格式一致):

from smbus2 import SMBus
import struct

# 配置参数
I2C_BUS = 1  # 树莓派3默认I2C总线(SDA=GPIO2, SCL=GPIO3)
SLAVE_ADDR = 0x08  # STM32从设备地址,需与原Arduino代码一致

# 待发送的测量数据
meas_data = {
    "id": 1,
    "voltage": 220.5,
    "current": 1.23,
    "voltage_phase": 30.0,
    "current_phase": -15.5,
    "frequency": 50.0
}

def float_to_le_bytes(f):
    # 将float转为4字节小端字节数组
    return struct.pack('<f', f)

def uint16_to_le_bytes(i):
    # 将16位ID转为2字节小端字节数组(若原Arduino用32位ID则改用'<I')
    return struct.pack('<H', i)

# 打包并发送数据
with SMBus(I2C_BUS) as bus:
    send_buf = bytearray()
    send_buf.extend(uint16_to_le_bytes(meas_data["id"]))
    send_buf.extend(float_to_le_bytes(meas_data["voltage"]))
    send_buf.extend(float_to_le_bytes(meas_data["current"]))
    send_buf.extend(float_to_le_bytes(meas_data["voltage_phase"]))
    send_buf.extend(float_to_le_bytes(meas_data["current_phase"]))
    send_buf.extend(float_to_le_bytes(meas_data["frequency"]))
    
    # 发送数据(0x00为起始寄存器地址,若原Arduino有指定则替换)
    bus.write_i2c_block_data(SLAVE_ADDR, 0x00, send_buf)

STM32端接收字节转浮点型处理

1. 定义接收缓冲区与数据结构

#include <string.h>
#include "stm32f1xx_hal.h"

// 接收缓冲区:ID(2字节) + 5个float(各4字节),总长度22字节
uint8_t i2c_rx_buf[2 + 4*5] = {0};
uint8_t rx_idx = 0;

// 存储解析后的数据结构
typedef struct {
    uint16_t id;
    float voltage;
    float current;
    float voltage_phase;
    float current_phase;
    float frequency;
} MeasData;

MeasData received_data;

2. I2C中断回调接收字节

在I2C从设备中断回调中填充缓冲区:

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    if(hi2c->Instance == I2C1)
    {
        // 读取DR寄存器值存入缓冲区
        i2c_rx_buf[rx_idx++] = hi2c->Instance->DR;
        
        // 继续接收下一字节,直到缓冲区填满
        if(rx_idx < sizeof(i2c_rx_buf))
        {
            HAL_I2C_Slave_Receive_IT(hi2c, &i2c_rx_buf[rx_idx], 1);
        }
        else
        {
            // 解析数据
            parse_i2c_data();
            rx_idx = 0; // 重置索引准备下次接收
        }
    }
}

3. 字节数组转浮点型

利用memcpy直接将字节块转换为float(小端字节序与发送端一致):

void parse_i2c_data(void)
{
    // 转换ID(小端字节序)
    received_data.id = (uint16_t)(i2c_rx_buf[1] << 8) | i2c_rx_buf[0];
    
    // 转换各浮点变量
    memcpy(&received_data.voltage, &i2c_rx_buf[2], sizeof(float));
    memcpy(&received_data.current, &i2c_rx_buf[6], sizeof(float));
    memcpy(&received_data.voltage_phase, &i2c_rx_buf[10], sizeof(float));
    memcpy(&received_data.current_phase, &i2c_rx_buf[14], sizeof(float));
    memcpy(&received_data.frequency, &i2c_rx_buf[18], sizeof(float));
}

关键注意事项

  • 确保树莓派与STM32的字节序一致(示例用小端,与Arduino默认逻辑匹配),若原Arduino用大端,需将Python的struct.pack格式改为'>f',STM32转换时也需调整字节顺序。
  • 树莓派需先通过raspi-config启用I2C功能。
  • STM32的I2C从设备地址必须与树莓派代码中的SLAVE_ADDR完全一致。

内容的提问来源于stack exchange,提问作者Marius Gerhard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 23:15:36