DMC.27 · Датчики · ATmega328P
Задача
Разбудить MPU6050 и считать 6 значений акселерометра и гироскопа.
Алгоритм
Записать 0 в PWR_MGMT_1 (0x6B). Читать блок с 0x3B: ax,ay,az,temp,gx,gy,gz по 2 байта.
Исходный код (C, avr-gcc)
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#define MPU 0x68
static void twi_init(void){ TWSR=0; TWBR=72; }
static void tw(uint8_t d){ TWDR=d; TWCR=(1<<TWINT)|(1<<TWEN); while(!(TWCR&(1<<TWINT))); }
static void start(void){ TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while(!(TWCR&(1<<TWINT))); }
static void stop(void){ TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN); }
static uint8_t rd(uint8_t ack){ TWCR=(1<<TWINT)|(1<<TWEN)|(ack?(1<<TWEA):0); while(!(TWCR&(1<<TWINT))); return TWDR; }
static void wreg(uint8_t r,uint8_t v){ start(); tw(MPU<<1); tw(r); tw(v); stop(); }
int main(void){
int16_t ax,ay,az,gx,gy,gz; twi_init();
wreg(0x6B,0x00); // выход из сна
DDRB|=(1<<PB5);
for(;;){
start(); tw(MPU<<1); tw(0x3B); start(); tw((MPU<<1)|1);
ax=(rd(1)<<8)|rd(1); ay=(rd(1)<<8)|rd(1); az=(rd(1)<<8)|rd(1);
rd(1); rd(1); // temp
gx=(rd(1)<<8)|rd(1); gy=(rd(1)<<8)|rd(1); gz=(rd(0)<<8)|rd(0); stop();
(void)ax;(void)ay;(void)az;(void)gx;(void)gy;(void)gz;
_delay_ms(20);
}
}
Сборка: avr-gcc -mmcu=atmega328p -DF_CPU=16000000UL -Os файл.c -o файл.elf
Пояснения
Адрес 0x68 (AD0=0). Значения сырые (16 бит); масштаб зависит от выбранного диапазона.