hi
ich habe mal wieder ein problem - sry
ich habe das display LCD-Modul HLM8070 von Pollin (M50530 Controller).
Dank eurer Hilfe habe ich dazu auch einen code zum ansteuern gefunden.
Nun habe ich alles verdrahtet und den Code getestet.
Allerdings kommen komische Ausgaben auf dem Display...
erst hatte ich "@\\\p P\\p"
nun habe ich die Anzeigetexte geändert und er zeigt die ganze Zeit nur eine "0" an
die Kontakte und die richtige verdrahtung habe ich geprüft.
Ach ja, ich benutze einen Tiny2313 und steuere es über 4bit an.
Beim compilieren bekamm ich folgende Warnungen (vielleicht haben die damit zu tun)
der CodeCode:main.c:20: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness main.c:22: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness main.c:24: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness
main.c
lcd-m50530.cCode:#include <avr/io.h> #include <lcd-m50530.h> // Hauptprogramm int main(void) { // wait for power up delay(250); // LCD initialisieren LCD_init(); // Modus des LCDs ändern LCD_setEntryMode(LCD_CURSOR_ADDRESS_INC_WD | LCD_DISPLAY_START_ADDRESS_NO_CHANGE); // Cursor einschalten LCD_setDisplay(LCD_DISPLAY_ON | LCD_CURSOR_ON | LCD_CURSOR_BLINK | LCD_CHARACTER_BLINK); // ein paar Zeichen ausgeben LCD_write("Hallo Welt"); LCD_setCursorPos(2,5); LCD_write("Test"); LCD_setCursorPos(4, 0); LCD_write("test successful"); while (1) ; return 0; }
Code:/*********************************************************** LCD-Routinen für Samsung 2138a mit M50530-Controller 24 x 8 Zeichen Copyright 2003-04 by Daniel Jelkmann Zur Ansteuerung wird der 4Bit-Mode verwendet. Neben den 4 Datenleitungen (Data0-3) werden 4 weitere Steuerleitungen (Read/Write, Execute, OC1, OC2) benötigt. Damit werden am AVR 8 Pins benötigt. Anschluss: Alle 8 LCD-Signale müssen an einem Port des AVR angeschlossen werden. Gemäß folgender Tabelle müssen die 4 Datenleitungen an den niederwertigsten Bits anliegen. Die Reihenfolge der restlichen 4 Steuerleitungen und der verwendete Port ist über die Konstanten im Quellcode festgelegt und muss ggf. angepasst werden. Die restlichen LCD-Signale sind in folgender Tabelle zu finden. LCD Beschreibung Anschluss ------------------------------------------------------------------------- Pin 01 Masse Masse Pin 02 Data0 nicht angeschlossen Pin 03 Data1 nicht angeschlossen Pin 04 Data2 nicht angeschlossen Pin 05 Data3 nicht angeschlossen Pin 06 Data4 AVR Port Bit 0 Pin 07 Data5 AVR Port Bit 1 Pin 08 Data6 AVR Port Bit 2 Pin 09 Data7 AVR Port Bit 3 Pin 10 EX (Execute) AVR Port Bit 4* Pin 11 R/W (Read/Write) AVR Port Bit 5* Pin 12 OC2 AVR Port Bit 7* Pin 13 OC1 AVR Port Bit 6* Pin 14 Kontrast-Regelung, ungefähr 8,2 Volt, am besten mittels Poti anschließen Pin 15 Versorgungsspannung, +5 Volt Pin 16 Masse Masse * Die Reihenfolge dieser Leitungen kann über die Konstanten im Quellcode angepasst werden. Es wird keine Gewähr für die Vollständigkeit, Korrektheit, Funktionsfähigkeit oder für sonstige Eigenschaften des Codes übernommen. Haftung ausgeschlossen. *************************************************************/ #include <avr/io.h> //#include <avr/delay.h> #include <avr/pgmspace.h> #include "lcd-m50530.h" #include <stdlib.h> /* // wartet die angegebene Zeit in Millisekunden // F_MCU muss entsprechend gesetzt sein // (benötigt delay.h) void delay(const unsigned int ms) { for (unsigned char i = ms; i > 0; --i) // 4 cycles per loop * 250 = 1.000 cycles; 1.000 x F_MCU = 1 ms _delay_loop_2(250*F_MCU); }*/ // sendet den angelegten Befehl zum LCD // setzt kurzzeitig das EX-Signal und nimmt es anschließend wieder zurück void LCD_execute(void) { delay_short(); // EX-Signal setzen LCD_PORT |= (1 << LCD_EX_PIN); delay_short(); // EX-Signal löschen LCD_PORT &= ~(1 << LCD_EX_PIN); delay_short(); } // wartet solange bis das Busy-Flag nicht mehr gesetzt ist // und das LCD weitere Befehle entgegennimmt void LCD_waitReady(void) { /* READ BUSY FLAG & FUNCTION FLAGS (RB) input: OC1 0 OC2 0 RW 1 output: DB7 busy-flag (1 = busy) */ // Datenleitungen auf Eingang schalten // dazu die Bits der Datenleitungen auf 0 setzen LCD_DDR &= 240; // RB-Befehl senden //LCD_PORT = (1 << LCD_OC1_PIN) | (1 << LCD_OC2_PIN) | (1 << LCD_RW_PIN); LCD_PORT = 1 << LCD_RW_PIN; unsigned char flags = 0; while (1) { do { delay_short(); // EX-Signal setzen LCD_PORT |= (1 << LCD_EX_PIN); delay_short(); // flags einlesen flags = LCD_PIN; // EX-Signal löschen LCD_PORT &= ~(1 << LCD_EX_PIN); } while (bit_is_set(flags, 3)); if (flags & 6) // bits 1 oder 2 gesetzt, also entweder sind wie im 8bit-mode oder wir haben gerade den zweiten Teil im 4bit-mode gelesen break; } /* unsigned char busy; do { delay_short(); LCD_execute(); // busy-Signal einlesen busy = bit_is_set(LCD_PIN, 3); LCD_execute(); } while (busy); */ // alle Leitungen als Ausgänge schalten LCD_DDR = 0xFF; } // überträgt das übergebene Byte an das LCD void LCD_sendByte(const unsigned char byte, unsigned char control) { LCD_waitReady(); // die unteren 5 Bits im Control-Byte ausblenden control &= 224; // oberes Nibble übertragen LCD_PORT = (byte >> 4) | control; LCD_execute(); // unteres Nibble übertragen LCD_PORT = (byte & 15) | control; LCD_execute(); } // löscht die Anzeige und setzt die Display + Cursor-Adresse auf 0,0 void LCD_clear(void) { /* CLEAR DISPLAY, MOVE DISPLAY/CURSOR ADDRESS HOME input: OC1 0 OC2 0 RW 0 DB7-DB1 0 DB0 1 */ LCD_sendByte(1, 0); // DB0 delay(2); } // setzt 4-Bit-Mode und initialisiert das LCD // muss als erstes aufgerufen werden, bevor das LCD angesteuert werden kann void LCD_init(void) { // alle Leitungen auf Ausgang schalten LCD_DDR = 0xFF; // auf 4-Bit-Mode umschalten /* SET FUNCTION MODE input: OC1 0 OC2 0 RW 0 DB7,DB6 1 DB5 I/O 8/4 (1 = 8 bit, 0 = 4 bit) DB4 FONT 8/12 (1 = 5x8 fonts, 0 = 5x12 fonts) DB3,DB2 DUTY DB1,DB0 RAM */ LCD_sendByte(216, 0); // DB7, DB6, DB4, DB3 LCD_clear(); } // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position void LCD_write(const unsigned char * c) { while (*c) LCD_writeChar(*c++); } // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position (für String im ROM) void LCD_write_P(const unsigned char * progmem_string) { register unsigned char c; while ((c = pgm_read_byte(progmem_string++))) LCD_writeChar(c); } // setzt den Cursor an die angegebene Position (y = Zeile, x = Spalte) void LCD_setCursorPos(const unsigned char y, const unsigned char x) { // Adresse aus x und y berechnen // Adressen sind wie folgt: Zeile 0 = 0; Zeile 1 = 64; Zeile 2 = 128; Zeile 3 = 192; Zeile 4 = 0+24; Zeile 5 = 64+24; Zeile 6 = 128+24; Zeile 7 = 192+24 unsigned char address = x + ((y % 4) << 6); if (y > 3) address += 24; LCD_sendByte(address, (1<<LCD_OC1_PIN) | (1<<LCD_OC2_PIN)); }
lcd-m50530.h
vielleicht findet ja jemand den FehlerCode:/*********************************************************** LCD-Routinen für Samsung 2138a mit M50530-Controller 24 x 8 Zeichen Copyright 2003 by Daniel Jelkmann Zur Ansteuerung wird der 4Bit-Mode verwendet. Neben den 4 Datenleitungen (Data0-3) werden 4 weitere Steuerleitungen (Read/Write, Execute, OC1, OC2) benötigt. Damit werden am AVR 8 Pins benötigt. Anschluss: Alle 8 LCD-Signale müssen an einem Port des AVR angeschlossen werden. Gemäß folgender Tabelle müssen die 4 Datenleitungen an den niederwertigsten Bits anliegen. Die Reihenfolge der restlichen 4 Steuerleitungen und der verwendete Port ist über die Konstanten im Quellcode festgelegt und muss ggf. angepasst werden. Die restlichen LCD-Signale sind in folgender Tabelle zu finden. LCD Beschreibung Anschluss ------------------------------------------------------------------------- Pin 01 Masse Masse Pin 02 Data0 nicht angeschlossen Pin 03 Data1 nicht angeschlossen Pin 04 Data2 nicht angeschlossen Pin 05 Data3 nicht angeschlossen Pin 06 Data4 AVR Port Bit 0 Pin 07 Data5 AVR Port Bit 1 Pin 08 Data6 AVR Port Bit 2 Pin 09 Data7 AVR Port Bit 3 Pin 10 EX (Execute) AVR Port Bit 5* Pin 11 R/W (Read/Write) AVR Port Bit 4* Pin 12 OC2 AVR Port Bit 7* Pin 13 OC1 AVR Port Bit 6* Pin 14 Kontrast-Regelung, ungefähr 8,2 Volt, am besten mittels Poti anschließen Pin 15 Versorgungsspannung, +5 Volt Pin 16 Masse Masse * Die Reihenfolge dieser Leitungen kann über die Konstanten im Quellcode angepasst werden. Es wird keine Gewähr für die Vollständigkeit, Korrektheit, Funktionsfähigkeit oder für sonstige Eigenschaften des Codes übernommen. Haftung ausgeschlossen. *************************************************************/ #ifndef LCD_M50530_H #define LCD_M50530_H #include <util/delay.h> //#define F_MCU 5 /* Takt-Frequenz in MHz */ // wartet die angegebene Zeit in Millisekunden // XTAL_CPU muss entsprechend gesetzt sein // (benötigt delay.h) //extern void delay(unsigned int ms); #define delay(ms) for (unsigned int i = ms; i > 0; --i) \ _delay_loop_2(XTAL_CPU / 4000); // _delay_loop_2(250*F_MCU); /**************************************************************** Ggf. hier den Port anpassen, an dem das LCD angeschlossen ist! ****************************************************************/ // Data-Direction-Register, am dem das LCD angeschlossen ist #define LCD_DDR DDRB // Port-Register, am dem das LCD angeschlossen ist #define LCD_PORT PORTB // Pin-Register, am dem das LCD angeschlossen ist #define LCD_PIN PINB #define XTAL_CPU 5000000 /************************************************* Ggf. hier die Bits der 4 Steuerleitungen anpassen! *************************************************/ // Die Datenleitungen des LCDs müssen an den Pins 0-3 anliegen (Data0 auf Pin0, Data1 auf Pin1 usw.) // Die anderen 4 Steuerleitungen sind hier einzustellen! // Port-Pin, an dem der RW-Pin des LCDs liegt #define LCD_RW_PIN 4 // Port-Pin, an dem der EX-Pin des LCDs liegt #define LCD_EX_PIN 5 // Port-Pin, an dem der OC1-Pin des LCDs liegt #define LCD_OC1_PIN 6 // Port-Pin, an dem der OC2-Pin des LCDs liegt #define LCD_OC2_PIN 7 // ein paar Konstanten zur besseren Lesbarkeit des Quelltextes :-) #define LCD_DISPLAY_ON 16 #define LCD_CURSOR_ON 8 #define LCD_UNDERLINE 4 #define LCD_CURSOR_BLINK 2 #define LCD_CHARACTER_BLINK 1 #define LCD_CURSOR_ADDRESS_NO_CHANGE 64 #define LCD_CURSOR_ADDRESS_INC_RD 72 #define LCD_CURSOR_ADDRESS_INC_WD 80 #define LCD_CURSOR_ADDRESS_INC_RDWD 88 #define LCD_CURSOR_ADDRESS_DEC_RD 104 #define LCD_CURSOR_ADDRESS_DEC_WD 112 #define LCD_CURSOR_ADDRESS_DEC_RDWD 120 #define LCD_DISPLAY_START_ADDRESS_NO_CHANGE 64 #define LCD_DISPLAY_START_ADDRESS_INC_RD 65 #define LCD_DISPLAY_START_ADDRESS_INC_WD 66 #define LCD_DISPLAY_START_ADDRESS_INC_RDWD 67 #define LCD_DISPLAY_START_ADDRESS_DEC_RD 69 #define LCD_DISPLAY_START_ADDRESS_DEC_WD 70 #define LCD_DISPLAY_START_ADDRESS_DEC_RDWD 71 #define LCD_SPECIAL_AE (char)144 // Ä, dezimal 144, oktal 220 #define LCD_SPECIAL_OE (char)145 // Ö, dezimal 145, oktal 221 #define LCD_SPECIAL_UE (char)197 // Ü, dezimal 197, oktal 305 #define LCD_SPECIAL_ae (char)160 // ä, dezimal 160, oktal 240 #define LCD_SPECIAL_oe (char)161 // ö, dezimal 161, oktal 241 #define LCD_SPECIAL_ue (char)17 // ü, dezimal 17, oktal 21 #define LCD_SPECIAL_ss (char)163 // ß, dezimal 163, oktal 243 // wartet einen kurzen Moment, 4 cycles per loop * 8 = 32 cycles, macht bei 16 MHz 2 µs #define delay_short() _delay_loop_2(8) // sendet den angelegten Befehl zum LCD // setzt kurzzeitig das EX-Signal und nimmt es anschließend wieder zurück extern void LCD_execute(void); // wartet solange bis das Busy-Flag nicht mehr gesetzt ist // und das LCD weitere Befehle entgegennimmt extern void LCD_waitReady(void); // überträgt das übergebene Byte an das LCD extern void LCD_sendByte(const unsigned char byte, unsigned char control); // setzt 4-Bit-Mode und initialisiert das LCD // muss als erstes aufgerufen werden, bevor das LCD angesteuert werden kann extern void LCD_init(void); // löscht die Anzeige und setzt die Display + Cursor-Adresse auf 0,0 extern void LCD_clear(void); // setzt den Entry-Mode des LCDs, also die automatische Erhöhung der Adresse nach einem Lese- oder Schreibbefehl // man verwende die oben deklarierten Konstanten ;) #define LCD_setEntryMode(mode) LCD_sendByte(mode, 0) // schreibt das übergebene Zeichen an die aktuelle Cursor-Position #define LCD_writeChar(c) LCD_sendByte(c, 1 << LCD_OC2_PIN) // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position extern void LCD_write(const unsigned char * c); // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position (für String im ROM) extern void LCD_write_P(const unsigned char * progmem_string); // setzt den Display-Modus // man verwende die oben deklarierten Konstanten ;) #define LCD_setDisplay(mode) LCD_sendByte(mode | 32, 0) // setzt den Cursor an die angegebene Adresse #define LCD_setCursorAddress(address) LCD_sendByte(address, (1<<LCD_OC1_PIN) | (1<<LCD_OC2_PIN)) // setzt den Cursor an die angegebene Position (y = Zeile, x = Spalte) extern void LCD_setCursorPos(const unsigned char y, const unsigned char x); #endif
den code habe ich übrigens von hier mikrocontroller.net
Danke für eure Hilfe







Zitieren

Lesezeichen