/*
* 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 9 times, last 10 minutes ago