基于STM32的ADXL345加速度计IIC读写程序(HAL库实现)

基于STM32的ADXL345加速度计IIC读写程序(HAL库实现)

一、系统概述

ADXL345是一款低功耗、3轴MEMS加速度计,支持±2g/±4g/±8g/±16g量程,通过I2C/SPI接口通信。本程序基于STM32F103C8T6(或兼容型号)和HAL库,实现ADXL345的I2C驱动,包括初始化配置、寄存器读写、三轴加速度数据采集与数据转换,适用于姿态检测、运动监测、振动分析等场景。

二、硬件设计

2.1 核心组件

模块 型号/参数 功能说明
主控 STM32F103C8T6(72MHz,I2C1) I2C通信、数据处理、加速度值转换
加速度计 ADXL345(I2C接口,3轴,±2g~±16g) 采集X/Y/Z轴加速度(分辨率13位)
I2C接口 PB6(SCL)、PB7(SDA)(I2C1) 连接ADXL345的SCL/SDA引脚
电源 3.3V供电(ADXL345兼容3.3V/5V) 为传感器和STM32供电

2.2 硬件连接

ADXL345引脚 STM32引脚(F103C8T6) 说明
VCC 3.3V 电源正极
GND GND 电源负极
SCL PB6(I2C1_SCL) I2C时钟线
SDA PB7(I2C1_SDA) I2C数据线
SDO GND(或VCC) I2C地址选择(GND→0x53,VCC→0x1D)

三、软件设计(STM32 HAL库)

3.1 开发环境

3.2 核心代码实现

3.2.1 头文件 adxl345.h(寄存器定义与函数声明)

#ifndef __ADXL345_H
#define __ADXL345_H

#include "stm32f1xx_hal.h"

// ==================== ADXL345 I2C地址(SDO接地=0x53,接VCC=0x1D) ====================
#define ADXL345_ADDR 0x53 << 1  // I2C设备地址(7位地址左移1位,HAL库要求)

// ==================== ADXL345寄存器地址 ====================
#define DEVID        0x00    // 设备ID(固定0xE5)
#define POWER_CTL    0x2D    // 电源控制寄存器
#define DATA_FORMAT  0x31    // 数据格式寄存器
#define DATAX0       0x32    // X轴数据低8位
#define DATAX1       0x33    // X轴数据高8位
#define DATAY0       0x34    // Y轴数据低8位
#define DATAY1       0x35    // Y轴数据高8位
#define DATAZ0       0x36    // Z轴数据低8位
#define DATAZ1       0x37    // Z轴数据高8位
#define BW_RATE      0x2C    // 带宽速率寄存器(采样率)

// ==================== 函数声明 ====================
HAL_StatusTypeDef ADXL345_Init(I2C_HandleTypeDef *hi2c);  // 初始化ADXL345
HAL_StatusTypeDef ADXL345_WriteReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t data);  // 写寄存器
HAL_StatusTypeDef ADXL345_ReadReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *data);   // 读单个寄存器
HAL_StatusTypeDef ADXL345_ReadRegs(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *buf, uint8_t len);  // 读多个寄存器
HAL_StatusTypeDef ADXL345_ReadAccel(I2C_HandleTypeDef *hi2c, float *ax, float *ay, float *az);  // 读取三轴加速度(g)

#endif

3.2.2 源文件 adxl345.c(驱动逻辑实现)

#include "adxl345.h"

// ==================== 初始化ADXL345(配置测量模式、数据格式) ====================
HAL_StatusTypeDef ADXL345_Init(I2C_HandleTypeDef *hi2c) {
    uint8_t dev_id;
    HAL_StatusTypeDef status;

    // 1. 验证设备ID(应返回0xE5)
    status = ADXL345_ReadReg(hi2c, DEVID, &dev_id);
    if (status != HAL_OK || dev_id != 0xE5) {
        return HAL_ERROR;  // 设备未连接或ID错误
    }

    // 2. 配置电源控制寄存器(POWER_CTL):启动测量模式(bit3=1)
    status = ADXL345_WriteReg(hi2c, POWER_CTL, 0x08);  // 0x08=00001000(测量模式)
    if (status != HAL_OK) return status;

    // 3. 配置数据格式寄存器(DATA_FORMAT):±2g量程,全分辨率,右对齐
    status = ADXL345_WriteReg(hi2c, DATA_FORMAT, 0x00);  // 0x00=±2g,13位分辨率
    if (status != HAL_OK) return status;

    // 4. 配置带宽速率寄存器(BW_RATE):100Hz采样率(0x0A=100Hz)
    status = ADXL345_WriteReg(hi2c, BW_RATE, 0x0A);
    return status;
}

// ==================== 写单个寄存器 ====================
HAL_StatusTypeDef ADXL345_WriteReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t data) {
    return HAL_I2C_Mem_Write(hi2c, ADXL345_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 100);
}

// ==================== 读单个寄存器 ====================
HAL_StatusTypeDef ADXL345_ReadReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *data) {
    return HAL_I2C_Mem_Read(hi2c, ADXL345_ADDR, reg, I2C_MEMADD_SIZE_8BIT, data, 1, 100);
}

// ==================== 读多个寄存器(批量读取加速度数据) ====================
HAL_StatusTypeDef ADXL345_ReadRegs(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *buf, uint8_t len) {
    return HAL_I2C_Mem_Read(hi2c, ADXL345_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 100);
}

// ==================== 读取三轴加速度(转换为g单位) ====================
HAL_StatusTypeDef ADXL345_ReadAccel(I2C_HandleTypeDef *hi2c, float *ax, float *ay, float *az) {
    uint8_t data[6];
    int16_t raw_x, raw_y, raw_z;
    HAL_StatusTypeDef status;

    // 1. 读取6字节数据(X低8+X高8+Y低8+Y高8+Z低8+Z高8)
    status = ADXL345_ReadRegs(hi2c, DATAX0, data, 6);
    if (status != HAL_OK) return status;

    // 2. 组合16位有符号整数(ADXL345数据右对齐,13位有效)
    raw_x = (int16_t)((data[1] << 8) | data[0]);  // X轴原始值
    raw_y = (int16_t)((data[3] << 8) | data[2]);  // Y轴原始值
    raw_z = (int16_t)((data[5] << 8) | data[4]);  // Z轴原始值

    // 3. 转换为加速度(g):±2g量程时,灵敏度=3.9mg/LSB=0.0039g/LSB
    *ax = raw_x * 0.0039f;  // X轴加速度(g)
    *ay = raw_y * 0.0039f;  // Y轴加速度(g)
    *az = raw_z * 0.0039f;  // Z轴加速度(g)

    return HAL_OK;
}

3.2.3 I2C初始化与主函数(CubeMX配置+示例)

CubeMX配置步骤

  1. 启用I2C1(PB6=SCL,PB7=SDA),模式为I2C,速率100kHz(标准模式);
  2. 启用USART1(PA9=TX,PA10=RX),用于打印加速度数据(调试用);
  3. 生成代码(含HAL库初始化)。

主函数示例

#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "adxl345.h"

I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;

int main(void) {
    HAL_Init();
    SystemClock_Config();  // 72MHz时钟配置
    MX_I2C1_Init();        // I2C1初始化(100kHz)
    MX_USART1_UART_Init(); // USART1初始化(115200bps)

    // 初始化ADXL345
    if (ADXL345_Init(&hi2c1) != HAL_OK) {
        printf("ADXL345初始化失败!\r\n");
        while (1);
    }
    printf("ADXL345初始化成功!\r\n");

    float ax, ay, az;
    while (1) {
        // 读取三轴加速度
        if (ADXL345_ReadAccel(&hi2c1, &ax, &ay, &az) == HAL_OK) {
            printf("加速度:X=%.2fg, Y=%.2fg, Z=%.2fg\r\n", ax, ay, az);
        } else {
            printf("读取加速度失败!\r\n");
        }
        HAL_Delay(500);  // 500ms刷新一次
    }
}

// printf重定向到USART1(需实现fputc)
int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
    return ch;
}

四、关键问题与解决方案

4.1 I2C通信失败

4.2 加速度数据异常

4.3 数据抖动

参考代码 基于STM32单片机ADXL345加速度计IIC读写程序 www.youwenfan.com/contentcst/182726.html

五、测试与验证

  1. 硬件连接:按2.2节连接STM32与ADXL345,确保I2C引脚上拉电阻(4.7kΩ)已接;
  2. 功能测试:读取设备ID(0xE5),确认初始化成功;
  3. 数据验证:将传感器静止放置,Z轴加速度应≈1g(±0.1g),X/Y轴≈0g;倾斜传感器,观察加速度变化。

六、总结

基于STM32 HAL库实现了ADXL345的I2C驱动,核心是寄存器配置、I2C读写与数据转换。通过模块化设计,可扩展支持SPI接口、中断唤醒、自由落体检测等功能,适用于嵌入式运动监测场景。

专注于matlab/simulink,电子电路,编程