Загрузка данных
echo '#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
const uint8_t font5x7[] = {
0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x5F,0x00,0x00, 0x00,0x07,0x00,0x07,0x00, 0x14,0x7F,0x14,0x7F,0x14,
0x24,0x2A,0x7F,0x2A,0x12, 0x23,0x13,0x08,0x64,0x62, 0x36,0x49,0x55,0x22,0x50, 0x00,0x05,0x03,0x00,0x00,
0x00,0x1C,0x22,0x41,0x00, 0x00,0x41,0x22,0x1C,0x00, 0x14,0x08,0x3E,0x08,0x14, 0x08,0x08,0x3E,0x08,0x08,
0x00,0x50,0x30,0x00,0x00, 0x08,0x08,0x08,0x08,0x08, 0x00,0x60,0x60,0x00,0x00, 0x20,0x10,0x08,0x04,0x02,
0x3E,0x51,0x49,0x45,0x3E, 0x00,0x42,0x7F,0x40,0x00, 0x42,0x61,0x51,0x49,0x46, 0x21,0x41,0x45,0x4B,0x31,
0x18,0x14,0x12,0x7F,0x10, 0x27,0x45,0x45,0x45,0x39, 0x3C,0x4A,0x49,0x49,0x30, 0x01,0x71,0x09,0x05,0x03,
0x36,0x49,0x49,0x49,0x36, 0x06,0x49,0x49,0x29,0x1E, 0x00,0x36,0x36,0x00,0x00, 0x00,0x56,0x36,0x00,0x00,
0x08,0x14,0x22,0x41,0x00, 0x14,0x14,0x14,0x14,0x14, 0x00,0x41,0x22,0x14,0x08, 0x02,0x01,0x51,0x09,0x06,
0x32,0x49,0x79,0x41,0x3E, 0x7E,0x11,0x11,0x11,0x7E, 0x7F,0x49,0x49,0x49,0x36, 0x3E,0x41,0x41,0x41,0x22,
0x7F,0x41,0x41,0x22,0x1C, 0x7F,0x49,0x49,0x49,0x41, 0x7F,0x09,0x09,0x09,0x01, 0x3E,0x41,0x49,0x49,0x7A,
0x7F,0x08,0x08,0x08,0x7F, 0x00,0x41,0x7F,0x41,0x00, 0x20,0x40,0x41,0x3F,0x01, 0x7F,0x08,0x14,0x22,0x41,
0x7F,0x40,0x40,0x40,0x40, 0x7F,0x02,0x0C,0x02,0x7F, 0x7F,0x04,0x08,0x10,0x7F, 0x3E,0x41,0x41,0x41,0x3E,
0x7F,0x09,0x09,0x09,0x06, 0x3E,0x41,0x51,0x21,0x5E, 0x7F,0x09,0x19,0x29,0x46, 0x46,0x49,0x49,0x49,0x31,
0x01,0x01,0x7F,0x01,0x01, 0x3F,0x40,0x40,0x40,0x3F, 0x1F,0x20,0x40,0x20,0x1F, 0x3F,0x40,0x38,0x40,0x3F,
0x63,0x14,0x08,0x14,0x63, 0x07,0x08,0x70,0x08,0x07, 0x61,0x51,0x49,0x45,0x43
};
const uint8_t font_cyr[][5] = {
{0x7E,0x11,0x11,0x11,0x7E},
{0x7F,0x49,0x49,0x49,0x31},
{0x7F,0x49,0x49,0x49,0x36},
{0x7F,0x01,0x01,0x01,0x03},
{0x60,0x3F,0x21,0x3F,0x60},
{0x7F,0x49,0x49,0x49,0x41},
{0x77,0x08,0x7F,0x08,0x77},
{0x41,0x49,0x49,0x49,0x36},
{0x7F,0x10,0x08,0x04,0x7F},
{0x7F,0x10,0x09,0x04,0x7F},
{0x7F,0x08,0x14,0x22,0x41},
{0x40,0x3E,0x01,0x01,0x7F},
{0x7F,0x02,0x0C,0x02,0x7F},
{0x7F,0x08,0x08,0x08,0x7F},
{0x3E,0x41,0x41,0x41,0x3E},
{0x7F,0x01,0x01,0x01,0x7F},
{0x7F,0x09,0x09,0x09,0x06},
{0x3E,0x41,0x41,0x41,0x22},
{0x01,0x01,0x7F,0x01,0x01},
{0x07,0x08,0x70,0x08,0x07},
{0x0E,0x51,0x7F,0x51,0x0E},
{0x63,0x14,0x08,0x14,0x63},
{0x3F,0x20,0x20,0x3F,0x60},
{0x07,0x08,0x08,0x7F,0x00},
{0x7F,0x40,0x7F,0x40,0x7F},
{0x7F,0x40,0x7F,0x40,0x7F},
{0x01,0x7F,0x48,0x48,0x30},
{0x7F,0x48,0x48,0x48,0x30},
{0x7F,0x48,0x30,0x00,0x7F},
{0x41,0x41,0x49,0x49,0x3E},
{0x7F,0x08,0x3E,0x41,0x3E},
{0x46,0x29,0x19,0x09,0x7F}
};
void i2c_init(void) { TWSR = 0; TWBR = 72; }
void i2c_start(uint8_t a) {
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = a;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
void i2c_stop(void) { TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); _delay_us(10); }
void i2c_write(uint8_t d) {
TWDR = d;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
uint8_t i2c_read_ack(void) {
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
return TWDR;
}
uint8_t i2c_read_nack(void) {
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
return TWDR;
}
void oled_cmd(uint8_t c) {
i2c_start(0x3C << 1); i2c_write(0x00); i2c_write(c); i2c_stop();
}
void oled_init(void) {
oled_cmd(0xAE); oled_cmd(0x20); oled_cmd(0x00); oled_cmd(0xB0);
oled_cmd(0xC8); oled_cmd(0x00); oled_cmd(0x10); oled_cmd(0x40);
oled_cmd(0x81); oled_cmd(0x7F); oled_cmd(0xA1); oled_cmd(0xA6);
oled_cmd(0xA8); oled_cmd(0x3F); oled_cmd(0xA4); oled_cmd(0xD3);
oled_cmd(0x00); oled_cmd(0xD5); oled_cmd(0x80); oled_cmd(0xD9);
oled_cmd(0xF1); oled_cmd(0xDA); oled_cmd(0x12); oled_cmd(0xDB);
oled_cmd(0x40); oled_cmd(0x8D); oled_cmd(0x14); oled_cmd(0xAF);
}
void oled_set_pos(uint8_t col, uint8_t page) {
oled_cmd(0xB0 | page);
oled_cmd(0x00 | (col & 0x0F));
oled_cmd(0x10 | (col >> 4));
}
void oled_clear(void) {
for (uint8_t p = 0; p < 8; p++) {
oled_set_pos(0, p);
i2c_start(0x3C << 1); i2c_write(0x40);
for (uint8_t i = 0; i < 128; i++) i2c_write(0x00);
i2c_stop();
}
}
void oled_draw_5x7(const uint8_t *b) {
i2c_start(0x3C << 1); i2c_write(0x40);
for (uint8_t i = 0; i < 5; i++) i2c_write(b[i]);
i2c_write(0x00);
i2c_stop();
}
void oled_print(uint8_t col, uint8_t page, const char* s) {
oled_set_pos(col, page);
while (*s) {
uint8_t c = (uint8_t)*s++;
if (c == 0xD0 || c == 0xD1) {
uint8_t c2 = (uint8_t)*s++;
uint8_t idx = 0;
if (c == 0xD0 && c2 >= 0x90 && c2 <= 0xAF) idx = c2 - 0x90;
else if (c == 0xD0 && c2 >= 0xB0 && c2 <= 0xBF) idx = c2 - 0xB0;
else if (c == 0xD1 && c2 >= 0x80 && c2 <= 0x8F) idx = c2 - 0x80 + 16;
oled_draw_5x7(font_cyr[idx]);
} else {
if (c < 32 || c > 90) c = 32;
oled_draw_5x7(&font5x7[(c - 32) * 5]);
}
}
}
void oled_num(uint8_t col, uint8_t page, int32_t n) {
char buf[10]; int8_t i = 0;
if (n < 0) { n = -n; oled_print(col, page, "-"); col += 6; }
if (n == 0) { buf[i++] = 0x30; }
else { while (n > 0) { buf[i++] = (n % 10) + 0x30; n /= 10; } }
oled_set_pos(col, page);
while (--i >= 0) {
uint8_t c = buf[i];
oled_draw_5x7(&font5x7[(c - 32) * 5]);
}
}
uint16_t dig_T1, dig_P1;
int16_t dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
int32_t t_fine;
void bmp_init(void) {
i2c_start(0x77 << 1); i2c_write(0x88); i2c_stop();
i2c_start((0x77 << 1) | 1);
dig_T1 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_T2 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_T3 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P1 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P2 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P3 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P4 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P5 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P6 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P7 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P8 = i2c_read_ack() | (i2c_read_ack() << 8);
dig_P9 = i2c_read_ack() | (i2c_read_nack() << 8);
i2c_stop();
i2c_start(0x77 << 1); i2c_write(0xF4); i2c_write(0x27); i2c_stop();
}
int32_t bmp_press_mmhg(void) {
i2c_start(0x77 << 1); i2c_write(0xF7); i2c_stop();
i2c_start((0x77 << 1) | 1);
int32_t p_raw = ((int32_t)i2c_read_ack() << 12) | ((int32_t)i2c_read_ack() << 4) | (i2c_read_ack() >> 4);
int32_t t_raw = ((int32_t)i2c_read_ack() << 12) | ((int32_t)i2c_read_ack() << 4) | (i2c_read_nack() >> 4);
i2c_stop();
int32_t v1 = ((((t_raw >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;
int32_t v2 = (((((t_raw >> 4) - ((int32_t)dig_T1)) * ((t_raw >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = v1 + v2;
int64_pv1;
int64_t pv1 = ((int64_t)t_fine) - 128000;
int64_t pv2 = pv1 * pv1 * (int64_t)dig_P6;
pv2 = pv2 + ((pv1 * (int64_t)dig_P5) << 17);
pv2 = pv2 + (((int64_t)dig_P4) << 35);
pv1 = ((pv1 * pv1 * (int64_t)dig_P3) >> 8) + ((pv1 * (int64_t)dig_P2) << 12);
pv1 = (((((int64_t)1) << 47) + pv1)) * ((int64_t)dig_P1) >> 33;
if (pv1 == 0) return 0;
int64_t p = 1048576 - p_raw;
p = (((p << 31) - pv2) * 3125) / pv1;
pv1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
pv2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + pv1 + pv2) >> 8) + (((int64_t)dig_P7) << 4);
return (int32_t)((p / 256) * 75 / 10000);
}
void aht_init(void) {
_delay_ms(40);
i2c_start(0x38 << 1); i2c_write(0xBE); i2c_write(0x08); i2c_write(0x00); i2c_stop();
_delay_ms(10);
}
void aht_read(int16_t *temp, uint8_t *hum) {
i2c_start(0x38 << 1); i2c_write(0xAC); i2c_write(0x33); i2c_write(0x00); i2c_stop();
_delay_ms(80);
i2c_start((0x38 << 1) | 1);
uint8_t st = i2c_read_ack();
if (st & 0x80) {
_delay_ms(20);
}
uint32_t h_raw = ((uint32_t)i2c_read_ack() << 12) | ((uint32_t)i2c_read_ack() << 4);
uint8_t mid = i2c_read_ack();
h_raw |= (mid >> 4);
uint32_t t_raw = ((uint32_t)(mid & 0x0F) << 16) | ((uint32_t)i2c_read_ack() << 8) | i2c_read_nack();
i2c_stop();
*hum = (uint8_t)(((uint64_t)h_raw * 100) >> 20);
*temp = (int16_t)((((int64_t)t_raw * 2000) >> 20) - 500);
}
void render_labels(void) {
oled_print(20, 0, "МЕТЕОСТАНЦИЯ");
oled_print(0, 2, "ТЕМП: ");
oled_print(0, 4, "ВЛАЖ: ");
oled_print(0, 6, "ДАВЛ: ");
}
void update_screen(void) {
int16_t t = 0; uint8_t h = 0;
aht_read(&t, &h);
int32_t p = bmp_press_mmhg();
oled_num(45, 2, t / 10);
oled_print(65, 2, ". ");
oled_num(75, 2, (t < 0 ? -t : t) % 10);
oled_print(90, 2, "C ");
oled_num(45, 4, h);
oled_print(70, 4, " % ");
oled_num(45, 6, p);
oled_print(75, 6, " ММ.РТ ");
}
ISR(INT0_vect) {
}
int main(void) {
DDRD &= ~(1 << PD2);
PORTD |= (1 << PD2);
EICRA &= ~((1 << ISC01) | (1 << ISC00));
EIMSK |= (1 << INT0);
sei();
i2c_init();
_delay_ms(100);
oled_init();
bmp_init();
aht_init();
while (1) {
oled_init();
oled_clear();
render_labels();
oled_cmd(0xAF);
for (uint8_t i = 0; i < 5; i++) {
update_screen();
_delay_ms(5000);
}
oled_cmd(0xAE);
_delay_ms(200);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
sleep_disable();
_delay_ms(200);
}
}' > meteo.c; and avr-gcc -mmcu=atmega328p -Wall -Os meteo.c -o meteo.elf; and avr-objcopy -O ihex -R .eeprom meteo.elf meteo.hex; and avrdude -p m328p -c arduino -P /dev/ttyUSB0 -b 57600 -D -U flash:w:meteo.hex:i