Hallo, ich habe die Platine (16MHz) aus dem Shop hier und möchte einen LCD anschließen. Dafür habe ich mich für den Port B entschieden. Soweit so gut, wenn ich Spannung anlege, dann sehe ich auf dem LCD in der 1. und 3. Zeile einen schwarzen Balken. Was mich aber verwundert, ist dass die LED auf der Entwicklungsplatine nicht leuchtet! Ich habe nachgemessen, Spannung liegt an PB01 an, aber trotzdem leuchtet die LED nicht! Ich dachte mir vielleicht ist mein Mikrocontroller kaputt, da ich ja das LCD weder initialisieren, noch sonst was kann. Kann das sein? Was allerdings (zumindest meiner Meinung nach) dagegenspricht, ist, dass ich den Mikrocontroller ja programmieren kann, also Programme in den Controller + Speicher schreiben sowie auch lesen kann - das scheint einwandfrei zu funktionieren. An was kann denn das Problem liegen? Ist es möglich, dass der Controller kaputt ist? Oder soll ich das LCD, das derzeit an den PortB's liegt, an einen anderen Port (D) anschließen? Vielen Dank für Eure Hilfe Markus
Was noch zu sagen wäre: Falsch angeschlossen ist das Ding ja nicht, ich habe alle Ports so angeschlossen, wie im AVR-Tutorial beschrieben, nur anstatt der D's eben die B-Ports genommen.
Hi Markus, ich kenne die Platine jetzt zwar nicht, aber zur LED: Vielleicht hängt die ja schon fest an Vcc und geht somit nur an, wenn Du den Port-Pin auf Low ziehst, anstatt auf High? Sebastian
Du kannst dir bei Olimex die Doku zu der Platine runterladen. Dann siehst du, dass die LED nach + angeschlossen ist, daher nur leuchtet wenn der Ausgang auf Low liegt. Eigentlich ist es egal an welchen Port das LCD hängt, sofern du das in der LCD-Bibliothek richtig änderst. Du solltest dort auch die delay() Routine anpassen, da die wahrscheinlich für 4MHz ausgelegt ist, und sonst das Timing nicht passt.
Ich habe ein bisschen im Forum gesurft (bin leider gerade nicht daheim, sonst hätte ich das mit dem delay schon ausprobiert) und bin darauf gestoßen, dass es evtl. auch was mit der Hintergrundbeleuchtung zu tun haben könnte (habe ein LCD mit 16 pins) - kann das sein, oder dürften dann gar keine Balken in der 1. und 3. Zeile erscheinen? Vielen Dank schon einmal für Eure Antworten. Grüßle Markus
Aber es scheint so, als schließt ihr einen defekten Mikrocontroller aus, richtig? Das wäre schon mal ne gute Nachricht.
So langsam krieg ich echt nen Koller. Das mit dem Delay hat nicht so wirklich funktioniert (muss ich da vielleicht irgendwelche FuseBits noch setzen, oder was weiß ich)? Ich würd jetzt gern einfach mal testen, ob mein Mikrocontroller funktioniert und würd gerne die LED an PB01 testen (wie oben beschrieben). Könnte mir da vielleicht jemand helfen mit ein bisschen Code? Vielen vielen Dank Der enttäuschte Markus
Kanns dir nur für gcc aufschreiben: #include <avr/io.h> void main(void) { DDRB=1; PORTB=0; oder korrekter: PORTB&=~_BV(0); } Wie ich oben schon geschrieben habe, der Pin muss auf 0!!!!
Sorry, loop sollte drüber: void main(void) { DDRB=1; PORTB=0; // LED aus (einfache Methode) for (;;) { PORTB|=_BV(0); // setzt pin auf high, also LED aus // da kannst dein delay rein PORTB&=~_BV(0); // pin auf low, also LED ein } } }
Ha, ich werd verrückt. Vielen Dank, Fritz, die LED leuchtet wirklich!!! Juhu! Damit wäre einmal sichergestellt, dass der Mikrocontroller nicht im Eimer ist! Jetzt muss nur noch der LCD funktionieren. Nochmal meine Frage von vorhin: Kann es vielleicht daran liegen, dass ich an der Kontrastspannung herumspielen muss? Aber warum werden dann nur in der 1. und 3. Zeile schwarze Balken angezeigt und nicht in allen Zeilen? Ist dann doch unwahrscheinlich, oder?
Wenn der LCD-Controller Strom kriegt, dann sieht man die schwarzen Balken. Oder wenn er per Software initialisiert wird, hab ich vergessen. Auf jeden Fall passt der Kontrast wenn du was siehst. Mit lcd_clrscr oder wie es bei dir heisst, sollten die weggehen, vorher musst aber noch sowas wie lcd_init machen.
Ja, genau und das ist das Problem. Mit folgendem Code tut sich rein gar nichts (außer den schwarzen Balken) :-((( .include "2313def.inc" .def temp1 = r16 .def temp2 = r17 .def temp3 = r18 ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten ;RAM-Adresse out SPL, temp1 ldi temp1, 0xFF ;Port D = Ausgang out DDRB, temp1 rcall lcd_init ;Display initialisieren rcall lcd_clear ;Display löschen ldi temp1, 'T' ;Zeichen anzeigen rcall lcd_data ldi temp1, 'e' ;Zeichen anzeigen rcall lcd_data ldi temp1, 's' ;Zeichen anzeigen rcall lcd_data ldi temp1, 't' ;Zeichen anzeigen rcall lcd_data loop: rjmp loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LCD-Routinen ;; ;; ============ ;; ;; (c)andreas-s@web.de ;; ;; ;; ;; 4bit-Interface ;; ;; DB4-DB7: PB0-PB3 ;; ;; RS: PB4 ;; ;; E: PB5 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;sendet ein Datenbyte an das LCD lcd_data: mov temp2, temp1 ;"Sicherungskopie" für ;die Übertragung des 2.Nibbles swap temp1 ;Vertauschen andi temp1, 0b00001111 ;oberes Nibble auf Null setzen sbr temp1, 1<<4 ;entspricht 0b00010000 out PORTB, temp1 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen ;2. Nibble, kein swap da es schon ;an der richtigen stelle ist andi temp2, 0b00001111 ;obere Hälfte auf Null setzen sbr temp2, 1<<4 ;entspricht 0b00010000 out PORTB, temp2 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen rcall delay50us ;Delay-Routine aufrufen rcall delay50us rcall delay50us ret ;zurück zum Hauptprogramm ;sendet einen Befehl an das LCD lcd_command: ;wie lcd_data, nur ohne RS zu setzen mov temp2, temp1 swap temp1 andi temp1, 0b00001111 out PORTB, temp1 rcall lcd_enable andi temp2, 0b00001111 out PORTB, temp2 rcall lcd_enable rcall delay50us rcall delay50us rcall delay50us ret ;erzeugt den Enable-Puls lcd_enable: sbi PORTB, 5 ;Enable high nop ;3 Taktzyklen warten nop nop nop nop nop cbi PORTB, 5 ;Enable wieder low ret ;Und wieder zurück ;Pause nach jeder Übertragung delay50us: ;50us Pause ldi temp1, $42 delay50us_:dec temp1 brne delay50us_ ret ;wieder zurück ;Längere Pause für manche Befehle delay5ms: ;5ms Pause ldi temp1, $21 WGLOOP0: ldi temp2, $C9 WGLOOP1: dec temp2 brne WGLOOP1 dec temp1 brne WGLOOP0 ret ;wieder zurück ;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden lcd_init: ldi temp3,50 powerupwait: rcall delay5ms rcall delay5ms rcall delay5ms dec temp3 brne powerupwait ldi temp1, 0b00000011 ;muss 3mal hintereinander gesendet out PORTB, temp1 ;werden zur Initialisierung rcall lcd_enable ;1 rcall delay5ms rcall delay5ms rcall delay5ms rcall lcd_enable ;2 rcall delay5ms rcall delay5ms rcall delay5ms rcall lcd_enable ;und 3! rcall delay5ms rcall delay5ms rcall delay5ms ldi temp1, 0b00000010 ;4bit-Modus einstellen out PORTB, temp1 rcall lcd_enable rcall delay5ms rcall delay5ms rcall delay5ms ldi temp1, 0b00101000 ;noch was einstellen... rcall lcd_command ldi temp1, 0b00001100 ;...nochwas... rcall lcd_command ldi temp1, 0b00000100 ;endlich fertig rcall lcd_command ret ;Sendet den Befehl zur Löschung des Displays lcd_clear: ldi temp1, 0b00000001 ;Display löschen rcall lcd_command rcall delay5ms rcall delay5ms rcall delay5ms ret
Beziehungsweise analog dazu mit der originalen, unveränderten Peter Fleury Bibliothek: /*********************************************************************** ** Title: testing output to a HD44780 based LCD display. Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury File: $Id: test_lcd.c,v 1.3 2003/12/10 19:32:48 peter Exp $ Software: AVR-GCC 3.3 Hardware: HD44780 compatible LCD text display ATS90S8515/ATmega if memory-mapped LCD interface is used any AVR with 7 free I/O pins if 4-bit IO port mode is used ************************************************************************ **/ #include <stdlib.h> #include <avr/io.h> #include "lcd.h" /* ** constant definitions */ /* ** function prototypes */ int main(void) { char buffer[7]; int num=134; /* initialize display, cursor off */ lcd_init(LCD_DISP_ON); for (;;) { /* loop forever */ /* * Test 1: write text to display */ /* clear display and home cursor */ lcd_clrscr(); /* put string to display (line 1) with linefeed */ lcd_puts("LCD Test Line 1\n"); /* cursor is now on second line, write second line */ lcd_puts("Line 2"); /* move cursor to position 8 on line 2 */ lcd_gotoxy(7,1); /* write single char to display */ lcd_putc(':'); } }
es gibt bei der Fleury bibliothek ein lcd.h da musst du einstellen ob du memory maped oder i/o machst. Ich hab die delay routine auch an die 8MHz angepasst.
Da ich mich jetzt voll auf Fleurys Bibliothek konzentrieren möchten, werde ich nun den Pin PB5 mit R/W (das war ja bisher auf GND gesetzt - wegen Tutorial) und den Pin PB6 mit Enable (war davor PB5) verbinden. So wie es eben in Fleurys Anleitung steht (http://homepage.sunrise.ch/mysunrise/pfleury/avr-lcd44780.html). Ich melde mich dann gleich wieder.
Jippie, es funktioniert!!! Fritz vielen Dank für deine aufopferungsvolle Hilfe - das hat mir mehr als geholfen. Wenn ich noch ein paar Fragen habe, darf ich dich dann fragen :-P? Tausend Dank an allen, die sich die Mühe gemacht haben, mir zu helfen. Nun bin ich fast fertig mit meinem LCD (naja, gut, schon noch ein Stück, aber mal schaun). Danke Markus
Ich versuche nun, in mein EEPROM mit folgender Funktion die Zahl 732 hineinzuschreiben: #include <stdlib.h> #include <avr/io.h> #include <inttypes.h> #include <eeprom.h> #include "lcd.h" #define EEPROM_SECTION _attribute_ ((section (".eeprom"))) uint16_t eeprom_var1 EEPROM_SECTION = 1027; int main(void) { char buffer[20]; uint16_t state1=732; eeprom_write_byte(&eeprom_var1, state1); /* initialize display, cursor off */ lcd_init(LCD_DISP_ON); lcd_clrscr(); ... } Dann hatte ich versucht, die Zahl mittels int main(void) { char buffer[20]; uint16_t state1=732; /* initialize display, cursor off */ lcd_init(LCD_DISP_ON); lcd_clrscr(); state1 = eeprom_read_word(&eeprom_var1); for (;;) { ... } auszulesen, und mittels itoa( state1 , buffer, 20); /* put converted string to display */ lcd_puts(buffer); auf den LCD zu schreiben. Doch auf dem LCD sehe ich nur 839f anstatt 732. Die Zahl state1 muss bis zu 36600 groß werden, darum habe ich mich für einen uint16_t entschieden - ich hoffe, das war richtig. Warum aber zeigt mein LCD nun das falsche an?
Ich meinte natürlich itoa (state1, buffer, 10). Und habe dabei auch state1 nicht auf 732, sondern auf die Höchstzahl 36600 gebracht. Auf dem LCD habe ich dann nur -1 anstatt 36600 gesehen. Wahrscheinlich kann ich mit eeprom_write_byte(&eeprom_var1, state1); keine so großen Werte speichern, sondern nur Byte-Werte von 0-255, oder? Wie löse ich dann das Problem? Oder muss ich beim Wertebereich 0-36600 einfach einen anderen Variablentyp nehmen? Aber welchen? Vielen Dank Markus
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.