DMC.29 · Датчики · ATmega328P
Задача
Проверить ID барометра, настроить режим и прочитать сырые значения давления и температуры.
Алгоритм
Читать регистр 0xD0 (id=0x58). Записать ctrl_meas (0xF4) и config (0xF5). Читать блок 0xF7..0xFC.
Исходный код (C, avr-gcc)
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#define BMP 0x76
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 a){ TWCR=(1<<TWINT)|(1<<TWEN)|(a?(1<<TWEA):0); while(!(TWCR&(1<<TWINT))); return TWDR; }
static void wreg(uint8_t r,uint8_t v){ start(); tw(BMP<<1); tw(r); tw(v); stop(); }
static uint8_t rreg(uint8_t r){ start(); tw(BMP<<1); tw(r); start(); tw((BMP<<1)|1); uint8_t v=rd(0); stop(); return v; }
int main(void){
twi_init(); DDRB|=(1<<PB5);
uint8_t id=rreg(0xD0);
wreg(0xF4,0x27); wreg(0xF5,0xA0); // normal mode, oversampling
for(;;){
uint32_t praw=((uint32_t)rreg(0xF7)<<12)|((uint32_t)rreg(0xF8)<<4)|(rreg(0xF9)>>4);
if(id==0x58 && praw) PORTB^=(1<<PB5);
_delay_ms(200);
}
}
Сборка: avr-gcc -mmcu=atmega328p -DF_CPU=16000000UL -Os файл.c -o файл.elf
Пояснения
Для физических единиц нужны калибровочные коэффициенты и компенсация по даташиту Bosch. Здесь — сырые данные.