Skip to content

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

I2C Device Driver for the MPU-6050 — STM32F103 (no HAL)

A register-level I2C master driver for the STM32F103, with a small MPU-6050 (6-axis IMU / GY-521) driver layered on top. No vendor HAL — the bus transport is implemented directly against the I2C1 peripheral registers per the STM32F103 reference manual (RM0008). Maps directly to embedded device-driver work for peripherals such as GPIO, I2C, and SPI.

Architecture

  • i2c.c — transport layer: START/STOP conditions, 7-bit addressing, ACK/NACK handling, and byte-level transmit/receive by driving the I2C1 registers. Every wait loop is bounded by a timeout, so an unpowered or stuck bus returns an error instead of hanging the firmware.
  • mpu6050.c — device layer: wakes the sensor, verifies WHO_AM_I, and burst-reads the 14 data registers, reassembling the big-endian 16-bit axes.
  • main.c — demo: blinks PC13 at a rate that changes with tilt, so the full path (I2C transfer → sensor register → decoded value → visible output) is observable without a UART.

Build

Requires the ARM bare-metal toolchain (arm-none-eabi-gcc) and make.

make          # produces imu.elf and imu.bin

Toolchain on Windows: in the MSYS2 UCRT64 terminal, pacman -S mingw-w64-ucrt-x86_64-arm-none-eabi-gcc make

Wiring (Blue Pill ↔ GY-521)

PB6 -> SCL      PB7 -> SDA      3V3 -> VCC      GND -> GND

The GY-521 breakout includes I2C pull-up resistors, so no external parts are needed.

Run it

  • Real board: flash imu.bin with an ST-Link (make flash) or a USB-DFU bootloader; stream readings over UART to see live values.
  • No board: wire an MPU-6050 to an STM32/Arduino in Wokwi, or model the sensor in Renode.

Design highlights

  • Layered design: the I2C transport knows nothing about the sensor, so it can be reused for any I2C device; the device layer knows nothing about bus-level timing. Each layer is testable independently.
  • STM32F1 read edge cases: the F1 I2C peripheral requires different ACK/STOP handling for reading 1, 2, or N>2 bytes. The driver implements all three per the reference-manual procedure — a common source of "wrong last byte" bugs.
  • Bounded waits: no unbounded busy-wait on a hardware flag; every blocking loop times out and returns a status code.

Files

i2c.c / i2c.h           bare-metal I2C1 master (100 kHz standard mode)
mpu6050.c / mpu6050.h   sensor init + 14-byte burst read
main.c                  tilt-reactive LED demo
startup.c               vector table, reset handler, .data/.bss init
stm32f103.ld            memory map (64 KB flash, 20 KB RAM)
Makefile                cross-compile to imu.elf / imu.bin

License

Released under the MIT License — free to use and adapt.

About

Register-level I2C master driver for STM32F103 (no HAL) with a layered MPU-6050 IMU driver — bounded timeouts and STM32F1 multi-byte read handling

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages