/* * menu.c — wersja z transmisją HIH8120 w tle * * Created: 30.05.2025 * Author : Student */ #include #define F_CPU 11059200UL #include #include #include #include "lcd.h" #include "ds18b20.h" #include "spi.h" #define HIH8120_ADDR 0x27 volatile int8_t ekran = 0; // 0..6 volatile int8_t subscreen = 0; // 0 lub 1 volatile uint8_t running = 1; // sekundnik ON/OFF volatile uint8_t MSB_H, LSB_H, MSB_T, LSB_T; volatile uint16_t res_H, res_T; volatile uint16_t humidity, temperature; // *100 void encoder_init(void) { DDRD &= ~((1 << PD2) | (1 << PD3) | (1 << PD4)); PORTD |= (1 << PD2) | (1 << PD3) | (1 << PD4); MCUCR |= (1 << ISC01); MCUCR &= ~(1 << ISC00); GICR |= (1 << INT0); sei(); } ISR(INT0_vect) { if (subscreen == 1) { subscreen = 0; return; } if (PIND & (1 << PD3)) ekran++; else ekran--; if (ekran > 6) ekran = 0; if (ekran < 0) ekran = 6; subscreen = 0; } // --- TWI (I2C) --- void TWI_start(void) { TWCR = (1 << TWEN) | (1 << TWSTA) | (1 << TWINT); while (!(TWCR & (1 << TWINT))); _delay_ms(10); } void TWI_address_transmit(void) { TWDR = 0b01001000; TWCR = (1 << TWEN) | (1 << TWINT); while (!(TWCR & (1 << TWINT))); _delay_ms(10); } void TWI_address_receive(void) { TWDR = 0b01001001; TWCR = (1 << TWEN) | (1 << TWINT); while (!(TWCR & (1 << TWINT))); _delay_ms(10); } uint8_t TWI_receive_ACK(void) { TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWEA); while (!(TWCR & (1 << TWINT))); return TWDR; } uint8_t TWI_receive_NACK(void) { TWCR = (1 << TWEN) | (1 << TWINT); while (!(TWCR & (1 << TWINT))); return TWDR; } void TWI_stop(void) { TWCR = (1 << TWEN) | (1 << TWSTO); _delay_ms(10); } void TWI_calc(void) { res_H = ((uint16_t)(MSB_H & 0x3F) << 8) | LSB_H; humidity = (uint16_t)(((float)res_H / 16382.0f) * 10000.0f); res_T = ((uint16_t)(MSB_T) << 6) | (LSB_T >> 2); temperature = (uint16_t)(((float)res_T / 16382.0f) * 16500.0f - 4000.0f); } int main(void) { lcd_init(); encoder_init(); ds18b20_init(); SPI_MasterInit(); _delay_ms(50); DDRB = 0xFF; PORTB = 0x00; uint16_t sekundy = 0; char buf[17]; static uint8_t counter = 0; while (1) { // Co ~10 pętli — odśwież komunikację HIH8120 counter++; if (counter > 10) { // około co 3 sekundy counter = 0; TWI_start(); TWI_address_transmit(); TWI_stop(); _delay_ms(50); TWI_start(); TWI_address_receive(); MSB_H = TWI_receive_ACK(); LSB_H = TWI_receive_ACK(); MSB_T = TWI_receive_ACK(); LSB_T = TWI_receive_NACK(); TWI_stop(); TWI_calc(); } lcd_clear(); if (!(PIND & (1 << PD4))) { _delay_ms(300); if (ekran == 2) { lcd_show_startstop(running); running = !running; } else if (ekran != 3) { lcd_show_loading(); subscreen = 1; } while (!(PIND & (1 << PD4))) _delay_ms(10); } switch (ekran) { case 0: if (subscreen == 0) { lcd_gotoxy(0, 0); lcd_puts("Imie, nazwisko"); } else { lcd_gotoxy(0, 0); lcd_puts("Daniel"); lcd_gotoxy(0, 1); lcd_send_byte(0, 1); lcd_puts("wi"); lcd_send_byte(1, 1); lcd_puts("cki"); } break; case 1: if (subscreen == 0) { lcd_gotoxy(0, 0); lcd_puts("Numer indeksu"); } else { lcd_gotoxy(0, 0); lcd_puts("275777"); } break; case 2: lcd_gotoxy(0, 0); lcd_puts("Czas:"); lcd_gotoxy(0, 1); sprintf(buf, "%us", sekundy); lcd_puts(buf); if (running) sekundy++; _delay_ms(1000); break; case 3: lcd_gotoxy(0, 0); lcd_puts("Resetuj czas"); lcd_gotoxy(0, 1); lcd_puts("Wcisnij przycisk"); break; case 4: if (subscreen == 0) { lcd_gotoxy(0, 0); lcd_puts("Temperatura"); } else { lcd_gotoxy(0, 0); lcd_puts("Temperatura:"); int16_t temp_raw = ds18b20_read_temp(); if (temp_raw == -1000) { lcd_gotoxy(0, 1); lcd_puts("Brak czujnika"); } else { int16_t temp_c = temp_raw / 16; uint16_t temp_frac = ((temp_raw & 0x0F) * 625) / 100; lcd_gotoxy(0, 1); sprintf(buf, "%d.%02d%cC", temp_c, temp_frac, 223); lcd_puts(buf); } } break; case 5: if (subscreen == 0) { lcd_gotoxy(0, 0); lcd_puts("Temp z czujnika"); lcd_gotoxy(0, 1); lcd_puts("SPI TC77"); } else { lcd_gotoxy(0, 0); lcd_puts("Temperatura:"); int16_t raw = readTemperatureRaw_TC77(); if (raw == 0xFFFF) { lcd_gotoxy(0, 1); lcd_puts("Brak SPI danych"); } else { float temp = raw * 0.0625; int8_t cal = (int8_t)temp; uint8_t frac = (uint8_t)((temp - cal) * 100); lcd_gotoxy(0, 1); sprintf(buf, "%d.%02d%cC", cal, frac, 223); lcd_puts(buf); } } break; case 6: lcd_gotoxy(0, 0); sprintf(buf, "Temp: %d.%02d C", temperature / 100, temperature % 100); lcd_puts(buf); lcd_gotoxy(0, 1); sprintf(buf, "Wilg: %d.%02d %%", humidity / 100, humidity % 100); lcd_puts(buf); break; } _delay_ms(300); } }