#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
// Definition der I2C-Schnittstelle und LCD-Adresse (Standardmäßig 0x27 oder 0x3F)
#define I2C_PORT i2c0
#define LCD_ADDR 0x27 // Falls nicht funktioniert, probiere 0x3F
// LCD Steuerbefehle
#define LCD_BACKLIGHT 0x08 // Hintergrundbeleuchtung aktivieren
#define ENABLE 0x04 // Enable-Bit zum Senden von Daten
/**
* Sendet ein Byte an das LCD
* @param val: Das zu sendende Byte (Daten oder Befehl)
* @param mode: 0 für Befehl, 1 für Daten (Zeichen)
*/
void lcd_send_byte(uint8_t val, bool mode) {
uint8_t high = mode | (val & 0xF0) | LCD_BACKLIGHT; // Höhere 4 Bits
uint8_t low = mode | ((val << 4) & 0xF0) | LCD_BACKLIGHT; // Niedrigere 4 Bits
uint8_t data[4] = { high | ENABLE, high, low | ENABLE, low };
// Daten an das LCD senden
i2c_write_blocking(I2C_PORT, LCD_ADDR, data, 4, false);
sleep_ms(2); // Kurze Pause zur Verarbeitung
}
/**
* Sendet einen Befehl an das LCD
* @param cmd: Der Befehlscode
*/
void lcd_send_command(uint8_t cmd) {
lcd_send_byte(cmd, 0);
}
/**
* Sendet ein Zeichen an das LCD
* @param data: Das darzustellende Zeichen
*/
void lcd_send_data(uint8_t data) {
lcd_send_byte(data, 1);
}
/**
* Initialisiert das LCD im 4-Bit-Modus
*/
void lcd_init() {
sleep_ms(50); // Wartezeit nach dem Einschalten des Displays
// Initialisierungssequenz für den 4-Bit-Modus
lcd_send_command(0x03);
sleep_ms(5);
lcd_send_command(0x03);
sleep_us(150);
lcd_send_command(0x03);
lcd_send_command(0x02); // Umschalten auf 4-Bit-Modus
// LCD Grundeinstellungen
lcd_send_command(0x28); // 4-Bit Modus, 2 Zeilen, 5x8 Punkte
lcd_send_command(0x0C); // Display ein, Cursor aus
lcd_send_command(0x06); // Cursor nach rechts bewegen
lcd_send_command(0x01); // Display löschen
sleep_ms(2);
}
/**
* Schreibt einen String auf das LCD
* @param str: Der anzuzeigende String
*/
void lcd_print(const char *str) {
while (*str) {
lcd_send_data(*str++);
}
}
/**
* Setzt den Cursor auf eine bestimmte Position
* @param row: Die Zeile (0 oder 1)
* @param col: Die Spalte (0 bis 15)
*/
void lcd_set_cursor(uint8_t row, uint8_t col) {
uint8_t pos = (row == 0) ? (0x80 + col) : (0xC0 + col);
lcd_send_command(pos);
}
int main() {
// Standardausgabe initialisieren (für Debugging über USB)
stdio_init_all();
// I2C-Schnittstelle initialisieren (100 kHz)
i2c_init(I2C_PORT, 100000);
gpio_set_function(4, GPIO_FUNC_I2C); // SDA-Pin
gpio_set_function(5, GPIO_FUNC_I2C); // SCL-Pin
gpio_pull_up(4);
gpio_pull_up(5);
// LCD initialisieren
lcd_init();
// Text auf LCD anzeigen
lcd_set_cursor(0, 0);
lcd_print("Hallo, Pico!");
lcd_set_cursor(1, 0);
lcd_print("I2C LCD Test");
// Endlosschleife
while (1) {
sleep_ms(1000);
}
return 0;
}