Raw Text Content QR
mole-wasp-pig



main.c /*
 * menu.c
 *
 * Created: 30.05.2025 08:26:15
 * Author : Student
 */ 


#include <avr/io.h>
#define F_CPU 11059200UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "lcd.h"
#include "ds18b20.h"
#include "spi.h"
#include "I2C.h"

#define HIH8120_ADDR 0x27

volatile int8_t ekran = 0;      // 0..4
volatile int8_t subscreen = 0;  // 0 lub 1
volatile uint8_t running = 1;   // sekundnik ON/OFF






// --- Enkoder INT0 ---
// PD2 - A (CLK)
// PD3 - B (DT)
// PD4 - SW (przycisk)
void encoder_init(void) {
	DDRD &= ~((1 << PD2) | (1 << PD3) | (1 << PD4));
	PORTD |= (1 << PD2) | (1 << PD3) | (1 << PD4); // Pull-up
	MCUCR |= (1 << ISC01); MCUCR &= ~(1 << ISC00); // INT0 on falling edge
	GICR |= (1 << INT0);
	sei();
}
ISR(INT0_vect) {
	if (subscreen == 1) {
		subscreen = 0; // wyj�cie z podmenu
		return;
	}

	if (PIND & (1 << PD3)) ekran++;
	else ekran--;

	if (ekran > 6) ekran = 0;
	if (ekran < 0) ekran = 6;
	subscreen = 0;
}


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];

	while (1) {
		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:
			if (subscreen == 0) {
				lcd_gotoxy(0, 0);
				lcd_puts("Czujnik HIH8120");
				lcd_gotoxy(0, 1);
				lcd_puts("I2C - wilg/temp");
				} else {
				// Zmienna na dane
				uint8_t data[4];
				volatile uint16_t res_H, res_T;
				volatile uint16_t humidity, temperature; // *100

				// Sekwencja I2C — działająca:

				TWI_start();
				TWI_address_transmit();
				TWI_stop();

				_delay_ms(50);  // minimum 36 ms — spokojnie 50 ms OK

				TWI_start();
				TWI_address_receive();

				data[0] = TWI_receive_ACK();
				data[1] = TWI_receive_ACK();
				data[2] = TWI_receive_ACK();
				data[3] = TWI_receive_NACK();

				TWI_stop();

				// Konwersja danych:

				res_H = ((uint16_t)(data[0] & 0x3F) << 8) | data[1];
				humidity = (uint16_t)(((float)res_H / 16382.0f) * 10000.0f);  // *100

				res_T = ((uint16_t)(data[2]) << 6) | (data[3] >> 2);
				temperature = (uint16_t)(((float)res_T / 16382.0f) * 16500.0f - 4000.0f);  // *100

				lcd_gotoxy(0, 0);
				char buf[32];
				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);
	}
}
i2c.c : /*
 * I2C_LCD.c
 *
 * Created: 06.05.2025
 * Author : Student
 */ 

#include <avr/io.h>
#define F_CPU 11059200UL
#include <util/delay.h>
#include <stdio.h>

// LCD PINY
#define LCD_RS PA0
#define LCD_RW PA1
#define LCD_E  PA2
#define LCD_D4 PA3
#define LCD_D5 PA4
#define LCD_D6 PA5
#define LCD_D7 PA6

volatile uint8_t odp;
volatile uint8_t MSB_H, LSB_H, MSB_T, LSB_T;
volatile uint16_t res_H, res_T;
volatile uint16_t humidity, temperature; // *100 (czyli np. 2345 = 23.45)


// --------------------- LCD ---------------------
void pulse_E() {
	PORTA |= (1 << LCD_E);
	_delay_us(1);
	PORTA &= ~(1 << LCD_E);
	_delay_us(50);
}

void lcd_send_half(uint8_t data) {
	PORTA &= ~((1 << LCD_D7) | (1 << LCD_D6) | (1 << LCD_D5) | (1 << LCD_D4));

	if (data & (1 << 3)) PORTA |= (1 << LCD_D7);
	if (data & (1 << 2)) PORTA |= (1 << LCD_D6);
	if (data & (1 << 1)) PORTA |= (1 << LCD_D5);
	if (data & (1 << 0)) PORTA |= (1 << LCD_D4);

	pulse_E();
}

void lcd_send_byte(uint8_t data, uint8_t is_data) {
	if (is_data)
		PORTA |= (1 << LCD_RS);
	else
		PORTA &= ~(1 << LCD_RS);

	PORTA &= ~(1 << LCD_RW); // RW = 0

	lcd_send_half(data >> 4);
	lcd_send_half(data & 0x0F);
	_delay_ms(2);
}

void lcd_init(void) {
	DDRA |= (1 << LCD_RS) | (1 << LCD_RW) | (1 << LCD_E) |
			(1 << LCD_D4) | (1 << LCD_D5) | (1 << LCD_D6) | (1 << LCD_D7);

	_delay_ms(15);
	lcd_send_half(0x03);
	_delay_ms(5);
	lcd_send_half(0x03);
	_delay_us(100);
	lcd_send_half(0x03);
	_delay_us(100);
	lcd_send_half(0x02); // tryb 4-bitowy

	lcd_send_byte(0x28, 0); // 2 linie
	lcd_send_byte(0x0C, 0); // ekran ON, kursor OFF
	lcd_send_byte(0x06, 0); // auto inkrementacja
	lcd_send_byte(0x01, 0); // czyszczenie
	_delay_ms(2);
}

void lcd_clear(void) {
	lcd_send_byte(0x01, 0);
	_delay_ms(2);
}

void lcd_gotoxy(uint8_t x, uint8_t y) {
	uint8_t addr = (y == 0) ? 0x00 : 0x40;
	lcd_send_byte(0x80 | (addr + x), 0);
}

void lcd_puts(const char* str) {
	while (*str) {
		lcd_send_byte(*str++, 1);
	}
}

// --------------------- TWI ---------------------
void TWI_start(){
	TWCR = (1 << TWEN) | (1 << TWSTA) | (1 << TWINT);
	while (!(TWCR & (1 << TWINT)));
	PORTD = TWSR;
	_delay_ms(200);
}

void TWI_address_transmit(){
	TWDR = 0b01001000; // Write address
	TWCR = (1 << TWEN) | (1 << TWINT);
	while (!(TWCR & (1 << TWINT)));
	PORTD = TWSR;
	_delay_ms(200);
}

void TWI_address_receive(){
	TWDR = 0b01001001; // Read address
	TWCR = (1 << TWEN) | (1 << TWINT);
	while (!(TWCR & (1 << TWINT)));
	PORTD = TWSR;
	_delay_ms(200);
}

uint8_t TWI_receive_ACK(void) {
    TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWEA);  // ACK
    while (!(TWCR & (1 << TWINT)));
    return TWDR;
}

uint8_t TWI_receive_NACK(void) {
    TWCR = (1 << TWEN) | (1 << TWINT);  // NACK
    while (!(TWCR & (1 << TWINT)));
    return TWDR;
}


void TWI_stop(){
	TWCR = (1 << TWEN) | (1 << TWSTO);
	_delay_ms(200);
	PORTD = TWSR;
}

void TWI_calc(){
	res_H = ((uint16_t)(MSB_H & 0x3F) << 8) | LSB_H;
    humidity = (uint16_t)(((float)res_H / 16382.0f) * 10000.0f);  // *100
	res_T = ((uint16_t)(MSB_T) << 6) | (LSB_T >> 2);
    temperature = (uint16_t)(((float)res_T / 16382.0f) * 16500.0f - 4000.0f); // *100

}

// --------------------- MAIN ---------------------
int main(void)
{
	DDRD = 0xFF;  // LEDy
	PORTD = 0x00;

	DDRC = 0x00;
	PORTC = 0xFF;

	lcd_init();


	
//ERROR TU CO� JEST NIE TAK Z M�ODSZA CZ�SCI� BIT�W
	while (1)
{
    TWI_start();
    TWI_address_transmit();
    // Możesz tu np. wysłać numer rejestru czujnika
    TWI_stop();

    _delay_ms(10);

    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();

    // Wyświetlenie danych
    char buf[32];
    lcd_clear();
    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);

    _delay_ms(2000);  // odświeżanie co 2 sekundy
}

}

Read 5 times, last 27 hours ago