hallo, will ein LCD-Display ansteuern, habe nun gerade nach dem Datenblatt die Init geschrieben, nun möchte ich mit der schreib Funktion Anfangen. Nun stehe ich vor einem Problem und zwar muss ich ja zuerst die DD-RAM Adresse setzen dazu steht im Datenblatt: Set DDRAM address: RS = L, RW = L, DB7 = H, DB6 = AC6, DB5 = AC5, DB4 = AC4, DB3 = AC3, DB2 = AC2, DB1 = AC1, DB0 = AC0 Also mit L ist ja Low gemeint also 0, mit H High also 1, nur was soll ich dann bei AC0 - 6 machen? 0 oder 1 ?
Hallo, naja, vielleicht Datenblatt auch verstehen? ;-))) AC6...AC0 ist die gewünschte DDRAM-Adresse, an der Du demnächst ein Zeichen anzeigen willst. Die Zuordnung der Adressen zur Darstellung im Display (Zeile, Position) steht auch irgendwo im Datenblatt. Bei HD44xxx-kompatiblen meist Zeile 1 ab 0x00, Zeile 2 ab 0x40 usw. 0x00 -> 00000000 0x40 -> 01000000 DB0...DB6 davon sind Deine Bits für AC0...AC6. AC soll wohl Adress-Counter heißen oder so. Gruß aus Berlin Michael
AC0 - 6 ist die Adresse. DB7,DB6,......,DB0 1,0,0,0,0,0,0,0 für Adresse 0, 1,0,0,0,0,0,0,1 für Adresse 1 usw.
achso ok, ich hab das jetzt so gemacht, es wird aber nichts angezeigt, ist das so überhaupts richtig? // set DD-RAM address PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (1 << D0); PORTB |= (0 << D1); PORTB |= (0 << D2); PORTB |= (0 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (1 << D7); // write data PORTD |= (0 << E); PORTD |= (1 << RS); PORTD |= (0 << RW); PORTB |= (0 << D0); PORTB |= (0 << D1); PORTB |= (0 << D2); PORTB |= (0 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (1 << D7); PORTD |= (1 << E);
Man kann die Fliege auch mit dem Elefanten erschlagen ;) E muss ein- und wieder ausgeschaltet werden nachdem das Datenbyte angelegt wurde. Dann muss eine Pause mindestens 40µs, sehr wichtig, folgen.
Was ich nicht verstehe: DIESE Frage wird hier im Forum doch inzwischen so zirke 5mal pro Woche gestellt. Und immer wieder geduldig von irgendjemandem beantwortet. Ich habe dazu selber schon einen kompletten funktionierenden Code gepostet. Aber trotzdem, immer wieder neu: "Wie geht LCD-Ansteuerung?" Meine Antwort: Ohne RTFM und für 2Cent Phantasie sowieso nicht. Und keine Bange, ich werde mich nie wieder in dieses Thema einschalten. Gruß Johannes
sorry aber wenn mir das alles nicht weiterhilft? hier mein quelltext: #include <avr/io.h> #include <uart.h> #include <avr/interrupt.h> #include <avr/eeprom.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <util/delay.h> // headerdatei für _delay_ms(); #include <avr/wdt.h> // headerdatei für watchdog #include "main.h" #define SYSCLK 3686400UL //3686400 8000000 #define BAUD 300UL #define UBRR_BAUD ((SYSCLK/(16*BAUD))-1) #define VCC 5 //#define ADC_VREF_TYPE 0x00 //External VREF //#define ADC_VREF_TYPE 0x40 //AVCC #define ADC_VREF_TYPE 0xc0 //Interne 2,56V Spannung #define D0 PB0 #define D1 PB1 #define D2 PB2 #define D3 PB3 #define D4 PB4 #define D5 PB5 #define D6 PD6 #define D7 PD7 #define RS PD4 #define RW PD3 #define E PD2 int crash; int light; int wert; double temp; int count = 0; int sec = 0; int min = 42; int hour = 20; int day = 0; int month = 0; ISR( TIMER0_OVF_vect ) { count++; if (count == 1800) { // (Takt / 8) / 256 sec++; count = 0; if (sec == 60) { min++; sec = 1; } if (min == 60) { hour++; min = 0; } if (hour == 24) { day++; hour = 1; } if (day == 30) { month++; day = 1; } } } int main(void) { int status = 0; // LCD Init Start DDRB = 0xff; // PORTB als Ausgang DDRD = 0xff; // PORTD als Ausgang // Function Set PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (0 << D0); PORTB |= (0 << D1); PORTB |= (1 << D2); // Display On PORTB |= (0 << D3); // 1 Line Mode PORTB |= (1 << D4); PORTB |= (1 << D5); PORTD |= (0 << D6); PORTD |= (0 << D7); _delay_us(40); // Display On PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (1 << D0); PORTB |= (1 << D1); PORTB |= (1 << D2); PORTB |= (1 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (0 << D7); _delay_us(40); // Display clear PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (1 << D0); PORTB |= (0 << D1); PORTB |= (0 << D2); PORTB |= (0 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (0 << D7); _delay_ms(2); // Entry mode set PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (1 << D0); PORTB |= (1 << D1); PORTB |= (1 << D2); PORTB |= (0 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (0 << D7); _delay_us(40); // Init Ende while (status == 0) { // set DD-RAM address PORTD |= (0 << E); PORTD |= (0 << RS); PORTD |= (0 << RW); PORTB |= (1 << D0); PORTB |= (0 << D1); PORTB |= (0 << D2); PORTB |= (0 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (0 << D6); PORTD |= (1 << D7); _delay_us(40); // write data PORTD |= (0 << E); PORTD |= (1 << RS); PORTD |= (0 << RW); PORTB |= (0 << D0); PORTB |= (0 << D1); PORTB |= (0 << D2); PORTB |= (1 << D3); PORTB |= (0 << D4); PORTB |= (0 << D5); PORTD |= (1 << D6); PORTD |= (1 << D7); _delay_us(44); PORTD |= (1 << E); PORTD &= ~( 1 << E); _delay_us(40); } // Schleifen Ende }
Hallo, @Johannes A.: ich verstehe es auch nicht....... Datenblatt Controller Timingdiagramm lesen und verstehen! E ist der Übernahme-Eingang. Der ist immer L Dann Daten und RS und RW passend setzen DANN E auf H, mindestens ca. 750ns auf H lassen, dann wieder auf L Während E auf H ist, müssen Daten, RS, RW stabil am Display anliegen. Dann gibt es noch Haltezeiten vor und nach dem E-Impuls, die sind aber bei üblichen AVR-Taktfrequenzen unkritisch. Außerdem fällt es sehr schwer Deinen Code zu lesen. Schau Dir mal einfach an, wie andere es machen. Mache Dinge sind in einer Zeile zusammen merklich lesbarer. Du steuerst das Display im 8-Bit-Mode an. Da kannman das Datenwort doch eher in eine OUT-Anweisung zusammenfassen. Wenn ich ein "A" ans Display schicken will, schicke ich doch auch ein A und zerlege es nicht erst in einzelne Bits. Auch schon hundertmal geschrieben: die 0-Schieberei ist witzlos. PORTB |= (0 << D0); PORTB |= (0 << D1); PORTB |= (1 << D2); // Display On Wieso hier Font auf 5x10`? PORTB |= (0 << D3); // 1 Line Mode Warum? Ich denke, Du hast ein 2x16??? PORTB |= (1 << D4); PORTB |= (1 << D5); PORTD |= (0 << D6); PORTD |= (0 << D7); PORTB = 0x34; // Display On, 1 Zeile finde ich lesbarer. Gruß aus Berlin Michael
darf man fragen warum du deine datenleitungen auf PB und PD aufsplittest? unkomfortabler geht es wirklich nicht. du solltest dafür sorgen, dass du erst deine daten anlegst und dann executest. pumpkin
@Michael Danke! und @Christian D. Sorry, aber wenn Du DIESEN Code nicht selber langsam echt krank findest, wird Dir wohl kaum noch jemand helfen können... Und Tschüss Johannes
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.