Created
May 16, 2019 12:43
-
-
Save avr-programmierung/d8eb245292b1c7f76a9e94d11aec632f to your computer and use it in GitHub Desktop.
ATmega88 @ 8MHz LCD Ausgabe für Hitachi HD44780 kompatible LCD Controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**************************************************************** | |
* LCD Ausgabe für Hitachi HD44780 kompatible LCD Controller | |
* LCD-Initialisierung: 4-Bit Interface | |
* Mikrocontroller: ATmega88 @ 8MHz | |
* LCD-Display: Displaytech 162B (LCD-Controller KS0070B) | |
* | |
* Konfiguration: PORT D7 = LCD D7 | |
* PORT D6 = LCD D6 | |
* PORT D5 = LCD D5 | |
* PORT D4 = LCD D4 | |
* PORT D3 = LCD E | |
* PORT D2 = LCD RS | |
* GND = LCD Vss + LCD R/W + LCD K | |
* +5V = LCD Vdd | |
* Poti = LCD V0 | |
* +5V (über 1kOhm) = LCD A | |
****************************************************************/ | |
#include <avr/io.h> | |
#include <util/delay.h> | |
#include // Definitionen für die ITOA-Funktion einbinden | |
/***** LCD Pinbelegung *****/ | |
#define LCDPORT PORTD | |
#define LCDDDR DDRD | |
#define LCD_PIN_RS 2 | |
#define LCD_PIN_E 3 | |
#define LCD_PIN_D4 4 | |
#define LCD_PIN_D5 5 | |
#define LCD_PIN_D6 6 | |
#define LCD_PIN_D7 7 | |
/***** LCD STEUERBEFEHLE *****/ | |
#define LCD_CLEAR 0x01 // Display löschen | |
#define LCD_HOME 0x02 // Cursor an den Anfang zurück | |
#define LCD_ON 0x0C // 0x0C = LCD ON, Cursor OFF | |
#define LCD_ON_C 0x0E // 0x0E = LCD ON, Cursor ON | |
#define LCD_OFF 0x08 // Display OFF | |
#define LCD_SET_4Bit 0x28 // Set Function = 4-Bit, 2 Zeilen, 5x7 Matrix | |
#define LCD_SET_2 0x06 // Entry Mode = Cursor increase, Display is not shifted | |
#define LCD_SETDDRAM 0x80 // Set Display RAM Address | |
/***** HILFSDEFINITIONEN *****/ | |
#define BEFEHL 0 | |
#define DATEN 1 | |
#define sbi(port, bit) (port |= (1<<bit)) | |
#define cbi(port, bit) (port &= ~(1<<bit)) | |
/****** Sendet ein Byte an den LCD Controller ******/ | |
void lcd_send(uint8_t type, uint8_t lcd_command) | |
{ | |
if (type == BEFEHL) | |
cbi(LCDPORT, LCD_PIN_RS); // RS=0: Befehl folgt ... | |
else | |
sbi(LCDPORT, LCD_PIN_RS); // RS=1: Daten folgen ... | |
/* (1) HIGH NIBBLE wird gesendet */ | |
if (bit_is_set(lcd_command, 7)) | |
sbi(LCDPORT, LCD_PIN_D7); | |
else | |
cbi(LCDPORT, LCD_PIN_D7); | |
if (bit_is_set(lcd_command, 6)) | |
sbi(LCDPORT, LCD_PIN_D6); | |
else | |
cbi(LCDPORT, LCD_PIN_D6); | |
if (bit_is_set(lcd_command, 5)) | |
sbi(LCDPORT, LCD_PIN_D5); | |
else | |
cbi(LCDPORT, LCD_PIN_D5); | |
if (bit_is_set(lcd_command, 4)) | |
sbi(LCDPORT, LCD_PIN_D4); | |
else | |
cbi(LCDPORT, LCD_PIN_D4); | |
/* Flanke zur Übernahme der Daten für das High-Nibble senden ... */ | |
sbi(LCDPORT, LCD_PIN_E); | |
_delay_us(1); | |
cbi(LCDPORT, LCD_PIN_E); | |
_delay_us(1); | |
/* (2) LOW NIBBLE wird gesendet */ | |
if (bit_is_set(lcd_command, 3)) | |
sbi(LCDPORT, LCD_PIN_D7); | |
else | |
cbi(LCDPORT, LCD_PIN_D7); | |
if (bit_is_set(lcd_command, 2)) | |
sbi(LCDPORT, LCD_PIN_D6); | |
else | |
cbi(LCDPORT, LCD_PIN_D6); | |
if (bit_is_set(lcd_command, 1)) | |
sbi(LCDPORT, LCD_PIN_D5); | |
else | |
cbi(LCDPORT, LCD_PIN_D5); | |
if (bit_is_set(lcd_command, 0)) | |
sbi(LCDPORT, LCD_PIN_D4); | |
else | |
cbi(LCDPORT, LCD_PIN_D4); | |
/* Flanke zur Übernahme der Daten für das Low-Nibble senden ... */ | |
sbi(LCDPORT, LCD_PIN_E); | |
_delay_us(1); | |
cbi(LCDPORT, LCD_PIN_E); | |
/* (3) Auf den LCD Controller warten ...*/ | |
_delay_ms(5); | |
} | |
/****** Stellt eine Zeichenkette am LCD dar ******/ | |
void lcd_write(char *t) // *t = pointer auf übergebenes Zeichen | |
{ | |
uint8_t i; | |
for (i=0; i<255; i++) | |
{ | |
if (t[i]==0) // String-Ende (bei Wert = 0)? Dann raus hier ... | |
return; | |
else | |
lcd_send(DATEN, t[i]); | |
} | |
} | |
/****** Enable Impuls zur Übernahme der LCD-Daten ******/ | |
void toggle_enable(void) | |
{ | |
sbi(LCDPORT, LCD_PIN_E); | |
_delay_us(1); | |
cbi(LCDPORT, LCD_PIN_E); | |
} | |
/****** Initialisierung des LCD Controllers *****/ | |
void lcd_init() | |
{ | |
_delay_ms(60); // LCD-Power-On delay (min. 40ms) | |
/* LCD Soft-Reset 1 – Kommando 0011xxxx */ | |
sbi(LCDPORT, LCD_PIN_D5); // D5 = 1 | |
sbi(LCDPORT, LCD_PIN_D4); // D4 = 1 | |
toggle_enable(); // Kommando übernehmen | |
_delay_ms(40); // Auf die Ausführung des LCD warten | |
/* LCD Soft-Reset 2 – Kommando 0011xxxx */ | |
toggle_enable(); // Kommando übernehmen (D5=1, D4=1) | |
_delay_ms(1); // Auf die Ausführung des LCD warten | |
/* LCD Soft-Reset 3 – Kommando 0011xxxx */ | |
toggle_enable(); // Kommando übernehmen (D5=1, D4=1) | |
_delay_ms(5); // Auf die Ausführung des LCD warten | |
// Ab hier ist sicher der 8-Bit Mode eingestellt! | |
// Jetzt folgt die Umstellung auf den 4-Bit Modus! | |
/* 4-Bit Modus einschalten */ | |
sbi(LCDPORT, LCD_PIN_D5); // LCD D5 = 1 | |
cbi(LCDPORT, LCD_PIN_D4); // LCD D4 = 0 | |
toggle_enable(); // Kommando übernehmen | |
_delay_ms(5); | |
// Ab hier im 4-Bit Modus (High-Nibble / Low-Nibble senden) | |
// LCD auf 2 Zeilen, 4-Bit Modus, 5x7 Matrix einstellen | |
lcd_send(BEFEHL, LCD_SET_4Bit); // Register SET FUNCTION = 0010 1000 | |
lcd_send(BEFEHL, LCD_OFF); // Set LCD OFF | |
lcd_send(BEFEHL, LCD_CLEAR); // Clear LCD | |
lcd_send(BEFEHL, LCD_SET_2); // Set ENTRY MODE = 0000 0110 | |
lcd_send(BEFEHL, LCD_ON); // Set LCD ON | |
} | |
/****** Hilfsfunktion: Warte i Sekunden ******/ | |
void sekunde(uint8_t i) | |
{ | |
uint8_t k; | |
for (;i>0;i--) // Solange i>0 dekrementiere i um 1 | |
{ | |
for (k=0;k<10;k++) // 10 Durchläufe mit je 50ms | |
_delay_ms(50); | |
} | |
} | |
/***** HAUPTPROGRAMM *****/ | |
int main(void) | |
{ | |
LCDDDR = 0xFF; // Port auf Ausgang schalten | |
LCDPORT = 0x00; | |
lcd_init(); // LCD initialisieren | |
lcd_write("Starting LCD..."); | |
char Buffer[20]; // Datentyp char für Zeichen | |
uint8_t dezimalwert = 22; | |
while (1) | |
{ | |
// Aufruf der itoa-Funktion zur ASCII-Darstellung einer Dezimalzahl (Basis = 10) | |
itoa(dezimalwert,Buffer,10); | |
sekunde(5); | |
lcd_send(BEFEHL, LCD_CLEAR); // LCD clear | |
lcd_write("HALLO LCD!"); // Der Cursor befindet sich an 1.Position Zeile 1 | |
sekunde(5); | |
lcd_send(BEFEHL, LCD_CLEAR); // LCD clear | |
lcd_send(BEFEHL, LCD_SETDDRAM +0x40); // Cursor auf die 1.Position Zeile 2 | |
lcd_write("Wert = "); | |
lcd_write(Buffer); // Schreibe den Inhalt des itoa-Buffers | |
sekunde(5); | |
lcd_send(BEFEHL, LCD_CLEAR); // LCD clear | |
lcd_send(BEFEHL, LCD_SETDDRAM +0x42); // Cursor auf die 3.Position Zeile 2 | |
lcd_write("Wert = "); | |
lcd_write(Buffer); // Schreibe den Inhalt des itoa-Buffers | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment