CSDN专栏:

第32讲:实战——I2C传感器极简驱动快速验证

一、I2C传感器驱动基础

I2C是最常用的传感器接口,快速验证I2C传感器驱动是嵌入式开发的基本功。

1.1 I2C传感器特点

优点

  • 只需两根线(SCL、SDA)
  • 支持多设备共享总线
  • 协议简单

常见I2C传感器

  • 温湿度:SHT30、BME280
  • 加速度:MPU6050、LIS3DH
  • 气压:BMP280
  • 光照:BH1750
  • 颜色:TCS34725

1.2 I2C驱动要点

基本操作

  • 写寄存器:发送设备地址+寄存器地址+数据
  • 读寄存器:发送设备地址+寄存器地址,然后读取数据

时序要求

  • Start/Stop条件
  • ACK/NACK应答
  • 总线恢复时间

二、SHT30温湿度传感器

2.1 快速验证流程

Prompt

生成STM32F103 SHT30驱动:
- I2C1:PB6(SCL)、PB7(SDA)
- 地址:0x44
- 功能:读取温度和湿度
- 使用HAL库

AI生成

#include "stm32f1xx_hal.h"

I2C_HandleTypeDef hi2c1;
#define SHT30_ADDR  0x44

void I2C1_Init(void) {
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    HAL_I2C_Init(&hi2c1);
}

int8_t SHT30_Read(float *temperature, float *humidity) {
    uint8_t cmd[2] = {0x2C, 0x06};
    uint8_t data[6];
    
    // 发送测量命令
    if(HAL_I2C_Master_Transmit(&hi2c1, SHT30_ADDR << 1, cmd, 2, 100) != HAL_OK) {
        return -1;
    }
    
    // 等待测量完成
    HAL_Delay(20);
    
    // 读取数据
    if(HAL_I2C_Master_Receive(&hi2c1, SHT30_ADDR << 1, data, 6, 100) != HAL_OK) {
        return -1;
    }
    
    // 计算温度
    uint16_t rawTemp = (data[0] << 8) | data[1];
    *temperature = -45.0f + 175.0f * (float)rawTemp / 65535.0f;
    
    // 计算湿度
    uint16_t rawHumi = (data[3] << 8) | data[4];
    *humidity = 100.0f * (float)rawHumi / 65535.0f;
    
    return 0;
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    I2C1_Init();
    UART_Init();
    
    float temp, humi;
    
    while(1) {
        if(SHT30_Read(&temp, &humi) == 0) {
            printf("Temperature: %.2f°C, Humidity: %.2f%%\r\n", temp, humi);
        } else {
            printf("SHT30 read failed\r\n");
        }
        HAL_Delay(1000);
    }
}

2.2 验证方法

检查设备是否就绪

void SHT30_Check(void) {
    if(HAL_I2C_IsDeviceReady(&hi2c1, SHT30_ADDR << 1, 3, 100) == HAL_OK) {
        printf("SHT30 found at 0x%02X\r\n", SHT30_ADDR);
    } else {
        printf("SHT30 not found\r\n");
    }
}

I2C总线扫描

void I2C_Scan(void) {
    printf("I2C Scan:\r\n");
    
    for(uint8_t addr = 0; addr < 128; addr++) {
        if(HAL_I2C_IsDeviceReady(&hi2c1, addr << 1, 1, 10) == HAL_OK) {
            printf("Device found at 0x%02X\r\n", addr);
        }
    }
}

三、MPU6050加速度传感器

3.1 MPU6050驱动

Prompt

生成STM32F103 MPU6050驱动:
- I2C1:PB6(SCL)、PB7(SDA)
- 地址:0x68
- 功能:读取加速度和陀螺仪
- 使用HAL库

AI生成

#define MPU6050_ADDR  0x68

int8_t MPU6050_Init(void) {
    uint8_t data;
    
    // 唤醒MPU6050
    data = 0x00;
    if(HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR << 1, 0x6B, 1, &data, 1, 100) != HAL_OK) {
        return -1;
    }
    
    // 配置加速度量程(±2g)
    data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR << 1, 0x1C, 1, &data, 1, 100);
    
    // 配置陀螺仪量程(±250°/s)
    data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR << 1, 0x1B, 1, &data, 1, 100);
    
    return 0;
}

int8_t MPU6050_ReadAccel(float *ax, float *ay, float *az) {
    uint8_t data[6];
    
    if(HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR << 1, 0x3B, 1, data, 6, 100) != HAL_OK) {
        return -1;
    }
    
    int16_t rawX = (data[0] << 8) | data[1];
    int16_t rawY = (data[2] << 8) | data[3];
    int16_t rawZ = (data[4] << 8) | data[5];
    
    // 转换为g(±2g量程)
    *ax = (float)rawX / 16384.0f;
    *ay = (float)rawY / 16384.0f;
    *az = (float)rawZ / 16384.0f;
    
    return 0;
}

四、BME280环境传感器

4.1 BME280驱动

Prompt

生成STM32F103 BME280驱动:
- I2C1:PB6(SCL)、PB7(SDA)
- 地址:0x76
- 功能:读取温度、湿度、气压
- 使用HAL库

AI生成核心代码

#define BME280_ADDR  0x76

int8_t BME280_Init(void) {
    uint8_t data;
    
    // 检查芯片ID
    if(HAL_I2C_Mem_Read(&hi2c1, BME280_ADDR << 1, 0xD0, 1, &data, 1, 100) != HAL_OK) {
        return -1;
    }
    
    if(data != 0x60) {  // BME280芯片ID
        return -1;
    }
    
    // 配置湿度过采样(x1)
    data = 0x01;
    HAL_I2C_Mem_Write(&hi2c1, BME280_ADDR << 1, 0xF2, 1, &data, 1, 100);
    
    // 配置温度和气压过采样、工作模式
    data = 0x27;  // 温度x1、气压x1、正常模式
    HAL_I2C_Mem_Write(&hi2c1, BME280_ADDR << 1, 0xF4, 1, &data, 1, 100);
    
    // 配置待机时间、滤波器
    data = 0x00;
    HAL_I2C_Mem_Write(&hi2c1, BME280_ADDR << 1, 0xF5, 1, &data, 1, 100);
    
    return 0;
}

int8_t BME280_Read(float *temperature, float *pressure, float *humidity) {
    uint8_t data[8];
    
    // 读取所有数据
    if(HAL_I2C_Mem_Read(&hi2c1, BME280_ADDR << 1, 0xF7, 1, data, 8, 100) != HAL_OK) {
        return -1;
    }
    
    // 解析数据(简化版,实际需要补偿计算)
    uint32_t rawPress = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
    uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
    uint16_t rawHumi = (data[6] << 8) | data[7];
    
    // 简化计算(实际需要补偿)
    *temperature = (float)rawTemp / 100.0f;
    *pressure = (float)rawPress / 100.0f;
    *humidity = (float)rawHumi / 1024.0f;
    
    return 0;
}

五、I2C调试技巧

5.1 常见问题

问题一:设备未找到

原因:
- 设备地址错误
- I2C引脚配置错误
- 设备未供电

解决:
- I2C总线扫描
- 检查引脚配置
- 检查供电

问题二:读取数据错误

原因:
- 寄存器地址错误
- 时序问题
- 总线干扰

解决:
- 添加延时
- 降低I2C速率
- 检查寄存器地址

5.2 调试代码

I2C读取调试

int8_t I2C_Read_Debug(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len) {
    printf("I2C Read: Addr=0x%02X, Reg=0x%02X, Len=%d\r\n", addr, reg, len);
    
    HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&hi2c1, addr << 1, reg, 1, data, len, 100);
    
    if(status == HAL_OK) {
        printf("Data: ");
        for(uint16_t i = 0; i < len; i++) {
            printf("%02X ", data[i]);
        }
        printf("\r\n");
        return 0;
    } else {
        printf("Error: %d\r\n", status);
        return -1;
    }
}

六、本讲核心要点

6.1 记住这三句话

  1. I2C传感器驱动:写寄存器、读寄存器、数据转换

  2. 快速验证:设备扫描、读取数据、验证合理性

  3. 调试技巧:I2C扫描、读取调试、时序检查

6.2 实践建议

对于新手

  • 学习I2C协议
  • 实践传感器驱动
  • 使用调试技巧

对于有经验工程师

  • 建立传感器驱动模板库
  • 实现通用I2C驱动框架
  • 优化性能

6.3 下讲预告

第33讲将深入讲解:实战:ADC采集、电压采样快速代码生成

ADC是模拟量采集的基础,如何快速生成ADC采集代码?下一讲将详细讲解。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐