/* * I2C_LCD.c * * Created: 06.05.2025 * Author : Student */ #include #define F_CPU 11059200UL #include #include // 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 } }