Das alphanumerische LCD-Modul 162B von Displaytech verfügt über zwei Zeilen mit jeweils 16 Zeichen und verwendet den Controller KS0070B, der kompatibel zum Industriestandard HD44780 ist. Die Ansteuerung erfolgt parallel mit einem wahlweise 4 Bit oder 8 Bit breiten Datenbus.

Displaytech 162B - Pinbelegung:

Anschlussplan:

Hier eine C-Routine, welche ein LCD-Display (Displaytech 162B) im 2-Zeilen-4-Bit-Modus ansteuert.
/**************************************************************** * LCD Ausgabe für Hitachi HD44780 kompatible LCD Controller * * Mikroontroller: AT90PWM316 * Clock: 8MHz intern * 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 R = 1kOhm) = LCD A ****************************************************************/
#define F_CPU 8000000
#include <avr/io.h> #include <util/delay.h>
#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 #define LCD_SETDDRAM 0x80 // Set Display RAM Address
/***** 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 0x0E // 0x0E = LCD ON, Cursor ON #define LCD_OFF 0x08 // Display OFF
/***** HILFSDEFINITIONEN *****/
#define BEFEHL 0 #define DATEN 1 #define sbi(sfr, bit) (sfr |= (1<<bit)) #define cbi(sfr, bit) (sfr &= ~(1<<bit))
/****** Sendet ein Byte an den LCD Controller ******/ void lcd_send(unsigned char type, unsigned char c) { 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(c, 7)) sbi(LCDPORT, LCD_PIN_D7); else cbi(LCDPORT, LCD_PIN_D7); if (bit_is_set(c, 6)) sbi(LCDPORT, LCD_PIN_D6); else cbi(LCDPORT, LCD_PIN_D6); if (bit_is_set(c, 5)) sbi(LCDPORT, LCD_PIN_D5); else cbi(LCDPORT, LCD_PIN_D5); if (bit_is_set(c, 4)) sbi(LCDPORT, LCD_PIN_D4); else cbi(LCDPORT, LCD_PIN_D4);
/* Flanke zur Übernahme der Daten senden ... ******/ sbi(LCDPORT, LCD_PIN_E); _delay_ms(1); cbi(LCDPORT, LCD_PIN_E);
/* (2) LOW NIBBLE wird gesendet ******/ if (bit_is_set(c, 3)) sbi(LCDPORT, LCD_PIN_D7); else cbi(LCDPORT, LCD_PIN_D7);
if (bit_is_set(c, 2)) sbi(LCDPORT, LCD_PIN_D6); else cbi(LCDPORT, LCD_PIN_D6);
if (bit_is_set(c, 1)) sbi(LCDPORT, LCD_PIN_D5); else cbi(LCDPORT, LCD_PIN_D5);
if (bit_is_set(c, 0)) sbi(LCDPORT, LCD_PIN_D4); else cbi(LCDPORT, LCD_PIN_D4);
/* Flanke zur Übernahme der Daten senden ... ******/ sbi(LCDPORT, LCD_PIN_E); _delay_ms(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) { unsigned char i; for (i=0;i<255;i++) { if (t[i]==0) // String-Ende? Dann raus hier ... return; else lcd_send(DATEN, t[i]); } }
/****** Initialisierung des LCD Controllers *****/ void lcd_init() { /* Port auf Ausgang schalten */ LCDPORT = 0x00; LCDDDR = 0xFF;
_delay_ms(40); // Warten bis LCD bereit ...
/* 4-bit Modus konfigurieren ------Function-Set 1*/ sbi(LCDPORT, LCD_PIN_D5); cbi(LCDPORT, LCD_PIN_D4);
_delay_ms(40); /* 4-bit Modus konfigurieren ------Function-Set 2*/ sbi(LCDPORT, LCD_PIN_D5); cbi(LCDPORT, LCD_PIN_D4); _delay_ms(5); /* 4-bit Modus konfigurieren ------Function-Set 3*/ sbi(LCDPORT, LCD_PIN_D5); cbi(LCDPORT, LCD_PIN_D4);
/* 4-Bit Modus starten ... */ sbi(PORTD, LCD_PIN_E); cbi(PORTD, LCD_PIN_E); _delay_ms(5);
/* 2 Zeilen, 4-Bit Modus */ lcd_send(BEFEHL, 0x28); //lcd_send(BEFEHL, 0x14);
lcd_send(BEFEHL, LCD_OFF); lcd_send(BEFEHL, LCD_CLEAR);
lcd_send(BEFEHL, 0x06); lcd_send(BEFEHL, LCD_ON); }
/****** Hilfsfunktion: Warte i Sekunden ******/ void sekunde(char i) { unsigned char k; for (;i>0;i--) { for (k=0;k<10;k++) _delay_ms(50); } }
/***** HAUPTPROGRAMM *****/ int main(void) { _delay_ms(50); lcd_init(); lcd_write("Starting LCD...");
while (1) { sekunde(5); lcd_send(BEFEHL, LCD_CLEAR); lcd_write("LCD-Test Zeile1");
sekunde(5); lcd_send(BEFEHL, LCD_CLEAR); lcd_send(BEFEHL, LCD_SETDDRAM +0x40); //Cursor auf 1.Position Zeile 2 lcd_write("LCD-Test Zeile2"); } }
Praxisbeispiel Temperatursensor mit LCD-Anzeige
Dieses Beispiel misst mittels Temperatursensor MCP9700 und ADC-Wandlung die Temperatur. Die Temperatur wird als int-Wert in der Variablen "ergebnis" gespeichert und durch die Funktion itoa in einen String für die LCD-Anzeige umgewandelt.
Die itoa-Funktion ist ein Bestandteil von WinAVR und erfordert das Einbinden von #include <stdlib.h>
Mehr zur itoa-Funktion finden Sie hier>>
C-Code für das abgeänderte Hauptprogramm:
/***** HAUPTPROGRAMM *****/ int main(void) { int x,ergebnis; _delay_ms(50); lcd_init(); lcd_write("Starting LCD...");
//**** Init ADC **** ADCSRA |= 1<<ADEN; // ADC aktivieren ADCSRA |= (1<<ADPS1)|(1<<ADPS2); // Vorteiler auf 64 ADMUX |= (1<<REFS0)|(1<<REFS1); // Einstellung Uref = 2,56V ADMUX |= (1<<MUX2)|(1<<MUX0); // ADC5 (PIN PB2) als ADC-Kanal definieren ADMUX |= (0<<ADLAR); // Ausgabe = linksbündig DIDR0 |= 1<<ADC5D; // Digital Input Kanal ADC5 disabled
// nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest // also einen Wert ein und verwirft diesen, um den ADC "warmlaufen zu lassen" ADCSRA |= (1<<ADSC); // Start ADC-Wandlung while (ADCSRA & (1<<ADSC)); // auf Abschluss der Konvertierung warten x = ADC; // ADCW muss einmal gelesen werden, sonst wird das // Ergebnis der nächsten Wandlung nicht übernommen char Buffer[20];
while (1) { ADCSRA |= (1<<ADSC); // Start ADC-Wandlung while (ADCSRA & (1<<ADSC)); // auf Abschluss der Konvertierung warten ergebnis = (ADC-200)/4; // Anpassung an die Temperaturkennlinie // (y=kx+d) + etwaiger Korrekturfaktor
itoa(ergebnis,Buffer,10); // Aufruf der itoa-Funktion // Die itoa-Funktion wandelt einen int-Wert in einen String um // Unter WinAVR ist diese Funktion durch einbinden von #include <stdlib.h> verfügbar
sekunde(5); lcd_send(BEFEHL, LCD_CLEAR); lcd_write("LCD-Thermometer");
sekunde(5); lcd_send(BEFEHL, LCD_CLEAR); lcd_send(BEFEHL, LCD_SETDDRAM +0x40); //1.Position Zeile 2 lcd_write("Es hat "); lcd_write(Buffer); lcd_write(" C"); } }
|