---
# System prepended metadata

title: How to use STM32 to drive ADXL345 three-axis acceleration sensor?
tags: [stm32]

---

To interface the [ADXL345](https://www.ampheo.com/search/ADXL345) three-axis accelerometer with an [STM32](https://www.ampheo.com/search/STM32) [microcontroller](https://www.ampheo.com/c/microcontrollers), you can use either I2C or SPI (the sensor supports both). Below is a complete guide using I2C with STM32 HAL, which is the most common and beginner-friendly setup.
![ADXL345_Connection](https://hackmd.io/_uploads/ry9wEbpBgx.png)

 **1. ADXL345 Overview**
* 3-axis accelerometer
* Digital output via I2C or SPI
* Resolution: 10-bit (±2g to ±16g range)
* Address: 0x53 (when ALT address pin = LOW)

 **2. Hardware Connections (I2C Mode)**
![企业微信截图_20250710170615](https://hackmd.io/_uploads/rJo5fbprgg.png)

Add 4.7kΩ pull-up [resistors](https://www.onzuu.com/category/resistors) to SDA and SCL lines if needed.

 **3. STM32CubeMX Setup**
1. Enable I2C1
2. Assign pins (e.g., PB6 = SCL, PB7 = SDA)
3. Set I2C clock speed (100 kHz or 400 kHz)
4. Generate code with HAL drivers

 **4. [ADXL345](https://www.ampheoelec.de/search/ADXL345) Register Summary**
![企业微信截图_20250710170711](https://hackmd.io/_uploads/rkU0fb6rxg.png)

 **5. STM32 I2C Code Example (HAL)**
**a) Read Device ID**
```
c

uint8_t devID;
HAL_I2C_Mem_Read(&hi2c1, 0xA6, 0x00, 1, &devID, 1, HAL_MAX_DELAY);
// 0xA6 = 0x53 << 1 (write address for I2C)
```
**b) Initialize Sensor**
```
c

// Set POWER_CTL (0x2D) to measurement mode (0x08)
HAL_I2C_Mem_Write(&hi2c1, 0xA6, 0x2D, 1, (uint8_t[]){0x08}, 1, HAL_MAX_DELAY);

// Set DATA_FORMAT (0x31) to ±2g and full resolution (0x08)
HAL_I2C_Mem_Write(&hi2c1, 0xA6, 0x31, 1, (uint8_t[]){0x08}, 1, HAL_MAX_DELAY);
```
**c) Read Acceleration Data**
```
c

uint8_t data[6];
int16_t ax, ay, az;

HAL_I2C_Mem_Read(&hi2c1, 0xA6, 0x32, 1, data, 6, HAL_MAX_DELAY);

ax = (int16_t)(data[1] << 8 | data[0]);
ay = (int16_t)(data[3] << 8 | data[2]);
az = (int16_t)(data[5] << 8 | data[4]);

float accel_x = ax * 0.0039; // assuming ±2g, 4mg/LSB
float accel_y = ay * 0.0039;
float accel_z = az * 0.0039;
```
 **6. Notes on Scaling**
* Scale factor: 4 mg/LSB at ±2g range
* To convert to m/s²: multiply by 9.81

```
c

float accel_ms2 = accel_x * 9.81; // m/s²
```
 **7. Best Practices**
* Add delays after writing to configuration registers.
* Use DMA or interrupts for real-time applications.
* Verify DEVID returns 0xE5 to confirm communication.