Hi Leute! Hab ein Problem mit dem Pollin-Evaluations-Board und dem dazugehörigen Addon-Board mit LC-Display. Hab die ganze Sache komplett selbst zusammengebaut und mit dem Demotool überprüft. Passt alles, Funktioniert einwandfrei. Bei meinem eigenen Programm soll eine LED 5x Blinken und dann den Text "Hallo Welt" auf dem Display schreiben. Die LED blinkt dann weiter. Ich bekomme aber nur folgendes auf dem Display dargestellt: H`}ln1Fu}d Belegung des Displays: DB0 FREI DB1 FREI DB2 FREI DB3 FREI DB4 PD4 DB5 PD5 DB6 PD6 DB7 PD7 E PB2 NC FREI RS PB0 R/W GND bzw. PB1 (hat keine Auswirkung) Komm einfach nicht mehr weiter! Muss ich DB0-DB3 auf GND legen oder frei lassen. Stimmt mein Programm nicht? Display ist ein TC1602A-08 Hab ich falsche Ports genommen?Ich bin so langsam am verzweifeln. Danke für eure Hilfe
Dann zeig doch mal den Code deines eigenen Programmes. Eventuell schon mal andere, fertige Libaries für die Ansteuerung benutzt? Peter Fleury scheint da schon einen quasi-Standart etabliert zu haben. Sehr einfach zu benutzen.
So hier meine einzelnen Dateien mit dem Code. Wie gesagt, ich hatte mal das Demoprogramm von Pollin für dieses Board aufgespielt und es hat auch erst nach etlichen Versuchen geklappt, aber es hat 100% funktioniert. Ich glaub, damals hatte ich ein Masse-Problem bei den Steckbrücken. Das Schaltbild vom Board ist nicht gerade aussagekräftig. Auch wie ich welche Kontakte auf GND legen muss und welche nicht kann man hier nicht rauslesen. Müssen die freien Kontakte beim Display auf GND gelegt werden? Ich hab es so weit hinbekommen, das ich "wenigstens" ein paar wirre Zeichen angezeigt bekomme. Also viel kann es doch jetzt nicht mehr sein. Das untenstehende Programm haben wir von unserem Lehrer bekommen, sollte mit Port-Anpassungen auch für das Pollin-Board funktionieren. Funktioniert auf den ET Stamp- Boards einwandfrei. Über Programmers Notepad und makefile wandel ich das ganze um. Auch die makefile Datei haben wir vom Lehrer ______________________________________________________________________ __ Datei hallowelt.c // LED blinken lassen und Ausgabe "Hallo Welt" auf dem LC-Display #include "led.h" #include "lcd.h" int main() { LED_init(); LCD_init(); LCD_instruction(LCD_DISP_ON); LED_blinken(5); LCD_puts("Hallo Welt"); while(1) { LED_blinken(5); } } ______________________________________________________________________ __ Datei led.c #include <avr/io.h> #include <util/delay.h> #include "ledmap.h" #define delaytime 500 void LED_init() { //PA1 als Ausgang setzen LED_DDR = LED_DDR | 1 << LED_PIN; } void LED_blinken() { int i; for(i=1; i<=5; i=i+1) { LED_PORT = LED_PORT | (1 << LED_PIN);//LED an _delay_ms(delaytime); LED_PORT = LED_PORT & ~(1 << LED_PIN);//LED aus _delay_ms(delaytime); } } ______________________________________________________________________ __ led.h void LED_init (); void LED_blinken(unsigned char anzahl); ______________________________________________________________________ __ Datei ledmap.h // LED Verbindungen mit AVR #define LED_DDR DDRA #define LED_PORT PORTA #define LED_PIN PA0 ______________________________________________________________________ __ Datei lcd.c /*********************************************************************** ******** File: lcd.c Compiler: AVR-GCC 3.3 Hardware: AVR Date: 04.06.2009 Basic routines for interfacing a HD44780U-based text LC-Display 4bit mode, microcontroller I/O port, write only (rw pin -> GND), dual- or single-line display ************************************************************************ *******/ #include <avr/io.h> #include <avr/pgmspace.h> #include <util/delay.h> #include "lcd.h" #include "lcdmap.h" // execution time for instructions (LCD specific) #define EXETIMELONG 1640 // execution time (us) for CLR and HOME instruction #define EXETIMESHORT 40 // execution time (us) for all other instructions /*********************************************************************** ******** Low-level function to write byte to LCD controller Input: b byte to write to LCD rs 1: data write 0: instruction write ************************************************************************ *******/ static void write(unsigned char b, _Bool rs) { if(rs) PORT(RS_PORT) |= (1 << RS); else PORT(RS_PORT) &= ~(1 << RS); // output high nibble PORT(EN_PORT) |= (1 << EN); if(b & 0x80) PORT(DB7_PORT) |= (1 << DB7); else PORT(DB7_PORT) &= ~(1 << DB7); if(b & 0x40) PORT(DB6_PORT) |= (1 << DB6); else PORT(DB6_PORT) &= ~(1 << DB6); if(b & 0x20) PORT(DB5_PORT) |= (1 << DB5); else PORT(DB5_PORT) &= ~(1 << DB5); if(b & 0x10) PORT(DB4_PORT) |= (1 << DB4); else PORT(DB4_PORT) &= ~(1 << DB4); PORT(EN_PORT) &= ~(1 << EN); // output low nibble PORT(EN_PORT) |= (1 << EN); if(b & 0x08) PORT(DB7_PORT) |= (1 << DB7); else PORT(DB7_PORT) &= ~(1 << DB7); if(b & 0x04) PORT(DB6_PORT) |= (1 << DB6); else PORT(DB6_PORT) &= ~(1 << DB6); if(b & 0x02) PORT(DB5_PORT) |= (1 << DB5); else PORT(DB5_PORT) &= ~(1 << DB5); if(b & 0x01) PORT(DB4_PORT) |= (1 << DB4); else PORT(DB4_PORT) &= ~(1 << DB4); PORT(EN_PORT) &= ~(1 << EN); } /*********************************************************************** ******** Low-level function to write nibble to LCD controller Input: byte, high nibble is written to LCD ************************************************************************ *******/ static void write_nibble(unsigned char b) { PORT(RS_PORT) &= ~(1 << RS); // instruction // output high nibble PORT(EN_PORT) |= (1 << EN); if(b & 0x80) PORT(DB7_PORT) |= (1 << DB7); else PORT(DB7_PORT) &= ~(1 << DB7); if(b & 0x40) PORT(DB6_PORT) |= (1 << DB6); else PORT(DB6_PORT) &= ~(1 << DB6); if(b & 0x20) PORT(DB5_PORT) |= (1 << DB5); else PORT(DB5_PORT) &= ~(1 << DB5); if(b & 0x10) PORT(DB4_PORT) |= (1 << DB4); else PORT(DB4_PORT) &= ~(1 << DB4); PORT(EN_PORT) &= ~(1 << EN); } /*********************************************************************** ******** Initialize display, see HD44780 data sheet After initialisation the display is off! ************************************************************************ *******/ void LCD_init() { // configure RW pin, if available #ifdef RW DDR(RW_PORT) |= (1 << RW); // output PORT(RW_PORT) &= ~(1 << RW); // write #endif // configure data pins as output DDR(DB7_PORT) |= (1 << DB7); DDR(DB6_PORT) |= (1 << DB6); DDR(DB5_PORT) |= (1 << DB5); DDR(DB4_PORT) |= (1 << DB4); // configure control pins as output DDR(RS_PORT) |= (1 << RS); DDR(EN_PORT) |= (1 << EN); _delay_us(15000); // wait for more then 15ms write_nibble(0x30); _delay_us(4100); // wait for more then 4.1ms write_nibble(0x30); _delay_us(100); // wait for more then 100us write_nibble(0x30); _delay_us(EXETIMESHORT); write_nibble(0x20); // Function Set: 4bit Mode _delay_us(EXETIMESHORT); #if DISPLAY_LINES == 1 LCD_instruction(0x20); // Function Set: 1 line, 5x8 dot character font #else LCD_instruction(0x28); // Function Set: 2 lines, 5x8 dot character font #endif LCD_instruction(LCD_DISP_OFF); // Display off, Cursor off, Blinking off LCD_instruction(LCD_CLR); // Clear display LCD_instruction(LCD_ENTRY_INC); // Entry Mode Set: Increment, no shift } /*********************************************************************** ******** Load custom character. This function change the cursor position! Input: pointer to array of char character code (0x00 - 0x07) ************************************************************************ *******/ void LCD_loadCustomChar(unsigned char* customCharArray, unsigned char charCode) { register unsigned char i; charCode = (charCode << 3); // calculate CG RAM address // copy the 8 bytes into CG (character generator) RAM for(i=0; i<8; i++) { write(0x40 | (charCode + i), 0); // set CG RAM address _delay_us(EXETIMESHORT); write(pgm_read_byte(customCharArray + i), 1); // write character data _delay_us(EXETIMESHORT); } } /*********************************************************************** ******** Send instruction to LCD unit Input: Instruction code (use predefined codes from lcd.h) ************************************************************************ *******/ void LCD_instruction(unsigned char cmd) { write(cmd, 0); if (cmd==LCD_CLR || cmd==LCD_HOME) _delay_us(EXETIMELONG); else _delay_us(EXETIMESHORT); } /*********************************************************************** ******** Set cursor to specified position Input: vertical position (0: first line) horizontal position (0: left most position) ************************************************************************ *******/ void LCD_setpos(unsigned char y, unsigned char x) { if (y==0) // first line write(0x80 | x, 0); else // second line write(0x80 | (0x40+x), 0); _delay_us(EXETIMESHORT); } /*********************************************************************** ******** Display character at current cursor position Input: character to be displayed ************************************************************************ *******/ void LCD_putchar(char c) { write(c, 1); _delay_us(EXETIMESHORT); } /*********************************************************************** ******** Display string without auto linefeed Input: string to be displayed ************************************************************************ *******/ void LCD_puts(const char *string) { char c; while (c = *string++) LCD_putchar(c); } ______________________________________________________________________ __ Datei lcd.h /*********************************************************************** ******** File: lcd.h Compiler: AVR-GCC 3.3 Hardware: AVR Date: 04.06.2009 Basic routines for interfacing a HD44780U-based text LC-Display ************************************************************************ *******/ // Clear enter display area, restore display from shift, and load address // counter with DD RAM adress 0x00 #define LCD_CLR 0x01 // Restore display from shift, and load address counter with DD RAM adress 0x00 #define LCD_HOME 0x02 // Specify cursor advance direction and display shift mode // This operation takes place after each data transfer #define LCD_ENTRY_DEC 0x04 // cursor moves to the left #define LCD_ENTRY_INC 0x06 // cursor moves to the right #define LCD_ENTRY_DEC_SHIFT 0x05 // shift display to the left #define LCD_ENTRY_INC_SHIFT 0x07 // shift display to the right // Specify activation of display, cursor, and blinking of character #define LCD_DISP_OFF 0x08 // display off #define LCD_DISP_ON 0x0C // display on #define LCD_DISP_ON_CURSOR 0x0E // display on, cursor on #define LCD_DISP_ON_BLINK 0x0D // display on, blink char #define LCD_DISP_ON_CURSOR_BLINK 0x0F // display on, cursor on, blink char // Shift display or move cursor #define LCD_MOVE_CURSOR_LEFT 0x10 // move cursor left (decrement) #define LCD_MOVE_CURSOR_RIGHT 0x14 // move cursor right (increment) #define LCD_MOVE_DISP_LEFT 0x18 // shift display left #define LCD_MOVE_DISP_RIGHT 0x1C // shift display right /*********************************************************************** ******** Initialize display, see HD44780 data sheet After initialisation the display is off! ************************************************************************ *******/ void LCD_init(); /*********************************************************************** ******** Load custom character. This function change the cursor position! Input: pointer to array of char character code (0x00 - 0x07) ************************************************************************ *******/ void LCD_loadCustomChar(unsigned char* customCharArray, unsigned char charCode); /*********************************************************************** ******** Send instruction to LCD unit Input: Instruction code (use predefined codes from lcd.h) ************************************************************************ *******/ void LCD_instruction(unsigned char); /*********************************************************************** ******** Set cursor to specified position Input: vertical position (0: first line) horizontal position (0: left most position) ************************************************************************ *******/ void LCD_setpos(unsigned char, unsigned char); /*********************************************************************** ******** Display character at current cursor position Input: character to be displayed ************************************************************************ *******/ void LCD_putchar(char); /*********************************************************************** ******** Display string without auto linefeed Input: string to be displayed ************************************************************************ *******/ void LCD_puts(const char *); ______________________________________________________________________ __ Datei lcdmap.h /*********************************************************************** ******** File: lcdmap.h Compiler: AVR-GCC 3.3 Hardware: AVR Date: 21.05.2009 LCD hardware settings and pin connections Layout for olimex-board ************************************************************************ *******/ #define DISPLAY_LINES 1 // Display Lines (1 or 2) #define RS_PORT B // register select #define RS PB0 #define RW_PORT B // read/write #define RW PB1 #define EN_PORT B // enable #define EN PB2 #define DB4_PORT D #define DB4 PD4 #define DB5_PORT D #define DB5 PD5 #define DB6_PORT D #define DB6 PD6 #define DB7_PORT D #define DB7 PD7 // extend register names with port characters #define GLUE(a, b) a##b #define PORT(x) GLUE(PORT, x) #define PIN(x) GLUE(PIN, x) #define DDR(x) GLUE(DDR, x)
das LED_blinken(5) und das void LED_blinken() passt irgendwie nicht zusammen.
Warum passt das nicht? Wie müsste das ganze heißen? Hab kaum Erfahrung im Bereich der Mikrocontroller. Die LED blinkt aber 5x und dann erscheint auf dem Display "H`}ln1Fu}d" Gruß
Wenn du wirre Zeichen auf dem LCD hast, kommt das sehr oft von nicht passenden Wartezeiten. Ist die Taktfrequenz in dein Programm eingebunden.
Schon mal drauf geachtet ob der Compiler irgendwelche Warnungen ausspuckt? Ich hab nirgendwo ein #define F_CPU gefunden, aber vielleicht hat der Herr Lehrer das ja im Makefile versteckt.
Die nicht benötigten Datenleitungen DB0-DB3 sollten nicht "FREI" sein sondern definiert auf Masse liegen. Sonst is nämlich schnell passiert, dass sich die je nach Mondphase doch nen High-Pegel einfangen und dann wars das mit der 4-Bit-Ansteuerung.
>dass sich die je nach Mondphase doch nen High-Pegel einfangen und dann >wars das mit der 4-Bit-Ansteuerung. huch, hab ich da was übersehen? Hab schon zig verschiedene Displays verbaut mit offenen unterm Nibble. Es gab noch nie Probleme damit. Z8
>hab ich da was übersehen? Hab schon zig verschiedene Displays verbaut >mit offenen unterm Nibble. Es gab noch nie Probleme damit. Hatte damit auch noch nie Probleme.
Normal schon... Dann warens bisher gute Displays, denen das entweder egal ist oder die selber nen kleinen Pulldown haben (wie auch immer der aussieht). Selber hatt ich (leider) schon ein paar Billigteile aus nem asiatischen Land... da sucht man sich nen Wolf, wenn man eben auch die guten gewohnt ist, und dann so ne Grütze kriegt, wo sogar Anatmen (!) bei offenen Datenleitungen was aufs Display zaubert. Darum einfach vorsorglich runterziehen; schadet nie und vermeidet im Fall der Fälle Fehler.
hab gerade mal nachgemessen, an den "offenen" Eingängen liegt ein stabieler "H" Pegel. Offensichtlich haben die Dinger Pull-Up-Rs. Es wär strommäßig kontraproduktiv die Eingänge auf Masse zu legen. Wenn mans mag dann eher auf Vcc. Z8 :)
Wenn schon, dann nicht auf Masse, sondern auf Vcc ziehen. Zumindest alle HD44780 kompatibel Displays haben einen Pullup eingebaut. Und wenn ein Display keine Pullups hat, dann sollte es nicht als HD44780 kompatibel bezeichnet werden. Mir ist zumindest noch kein solches Display begegnet und ich habe noch keine kommerzielle Schaltung gesehen, die Pullups verwendet hat: Die Pins waren immer offen.
So, danke erstmal für eure zahlreiche Hilfe. Ich habe das Ding heute zum laufen bekommen. Hab das originale Testprogramm überspielt und alles richtig verdrahtet. Als das Testprogramm lief, hab ich einfach RS --> PB7 RW --> PB0 EN --> PB6 DB4--> PB2 DB5--> PB3 DB6--> PB4 DB7--> PB5 programmiert. Danach hat es geklappt. Hab dann die unnötigen Leitungen wieder entfernt. DB0 bis DB3 sind frei, liegen nicht auf GND. Klappt einwandfrei. Kann es sein, das von alten Programmen noch im Speicher waren? Im alten Programm waren DB4 - DB7 auf PORTD und RS, RW und EN auf PORTB Gibt es da irgendwelche komplikationen. Wieso das Programm jetzt läuft kann ich mir einfach nicht erklären... Danke für eure Hilfe
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.