Forum: Mikrocontroller und Digitale Elektronik LCD ansprechen Probleme


von Sonke A. (soeni)


Lesenswert?

Ich habe ein Problem und zwar möchte ich ein LCD an die Pins 7 6 5 4 
eines Ports anschließend und die RS und Enable an 0 und 1. Das mache ich 
deshalb, weil ich so den Port optimal ausnutze (2 und 3 sind für den 
UART.)

Ich Benutze einen Atmega128.

Meine Initialisierung scheint soweit zu funktionieren, denn der Cursor 
blinkt und ist an der richtigen Stelle. nun hab ich versucht die 
Dataroutine des Tutorials hier abzuändern, dass die oberen 4 Bits des 
Ports als Datenleitung genutzt werden.

Hier der Code wie ich ihn abgeändert habe:

1
 void lcd_data(unsigned char temp1){
2
3
    
4
   unsigned char temp2 = (temp1<<4);
5
 
6
  LCD_PORT |= (1<<LCD_RS);                     // RS setzen
7
8
  LCD_PORT = (  (LCD_PORT & 0x0F) | (temp1 & 0xF0) );  // ausgeben
9
10
  lcd_enable();           // Enableimpuls senden                    
11
  _delay_us(42);
12
13
  LCD_PORT = (  (LCD_PORT & 0x0F) | (temp2 & 0xF0) );  // ausgeben
14
15
  lcd_enable();           // Enableimpuls senden                   
16
  _delay_us(42);
17
18
19
  }

von Sonke A. (soeni)


Lesenswert?

achso und zur ergänzung noch es wird ein zeichen angezeigt, nur nicht 
das, was ich sende. irgendwann rückt nurnoch der cursor vor, ohne dass 
Zeichen angezeigt werden.

von Niels H. (monarch35)


Lesenswert?

Der Teil des Code sieht aber ok aus. Hört sich nach einem Timingproblem 
an.

Getreu nach dem Motto "Pausenzeiten können nicht zu gross sein" solltest 
du mal versuchen, die delays anzupassen. Musst halt nur aufpassen, daß 
du nicht über die maximalwerte entsprechend der Taktgeschwindigkeit 
hinausgehst.

Wenn das immernoch nicht zieht, empfehle ich alle Leitungen zum Display 
auf kurzschlüsse bzw unterbrechnungen zu untersuchen.

von Benedikt K. (benedikt)


Lesenswert?

Du möchtest die Daten auf D4-7 übertragen ?
Du machst das aber genau umgekehrt, du überträgst auf D0-3:

LCD_PORT = (  (LCD_PORT & 0x0F) | (temp1 & 0xF0) );  // ausgeben

Du muss 0x0F und 0xF0 vertauschen.
Entsprechend muss dann auch noch
 unsigned char temp2 = (temp1<<4);
angepasst werden.

von Sonke A. (soeni)


Lesenswert?

inwiefern angepasst?

von Niels H. (monarch35)


Lesenswert?

Benedikt K. wrote:
> Du möchtest die Daten auf D4-7 übertragen ?
> Du machst das aber genau umgekehrt, du überträgst auf D0-3:

Kann es sein, daß du dich vertutest?

> LCD_PORT = (  (LCD_PORT & 0x0F) | (temp1 & 0xF0) );  // ausgeben

Das ist m. E. absolut korrekt.
1
LCD_PORT & 0x0F
blendet D4-7 vom bestehenden Port aus. Dann werden mit
1
temp1 & 0xF0
von temp1 D4-7 in LCD_PORT übernommen.

von Sonke A. (soeni)


Lesenswert?

zum Timingproblem: es wird ja was angezeigt, nur kein a wnn ich ein a 
sende.

von Niels H. (monarch35)


Lesenswert?

Sönke Paschko wrote:
> zum Timingproblem: es wird ja was angezeigt, nur kein a wnn ich ein a
> sende.

Ja, das spricht für ein Timingproblem...z.B. wenn durch eine 
Befehlsausführung ein Nibble auf dem Bus am Display "vorbei" geht. 
Wärend der Displaykontroller "buzy" ist, nimmt er Signale auf dem Bus 
nicht wahr.

Durch eine falsche Beschaltung (kurzschluss unterbrechung) kann es aber 
auch sein, daß gewisse signale falsch interpretiert werden. Hat der 
ATmega128 nicht auch JTAG defaultmässig eingeschaltet?

von Benedikt K. (benedikt)


Lesenswert?

Niels Hüsken wrote:
> Kann es sein, daß du dich vertutest?

Ja, hast recht. Ich bin noch im Halbschlaf, bei der Hitze kann ich nicht 
schlafen.

von Niels H. (monarch35)


Lesenswert?

Hab gerade mal nachgeschaut. JTAG ist beim mega128 per default 
eingeschaltet. Ich hoffe deine Portwahl ist nicht auf PortF gefallen?! 
:)

von Sonke A. (soeni)


Lesenswert?

nein ist Port D, ich habe die delays jezt auf 60 us gesezt und es geht 
immer noch nicht.

von Benedikt K. (benedikt)


Lesenswert?

Hast du schonmal versucht den Cursor an eine andere Stelle zu setzen ?
Wenn das geht, dann liegt der Fehler nur in dieser Funktion und nicht 
irgendwo anderst.

von Niels H. (monarch35)


Lesenswert?

Sönke Paschko wrote:
> nein ist Port D, ich habe die delays jezt auf 60 us gesezt und es geht
> immer noch nicht.

du hast doch noch ein paar mehr delays als nur diese beiden....
Schreck auch nicht davor zurück, mal ein paar delay_ms() einzubauen...

von Sonke A. (soeni)


Lesenswert?

momentan bin ich auf was gestoßen, ich habe manuell direkt nach dewr 
Initialisierung folgende Daten an das LCD gesendet:
1
_delay_ms(1000); // 1 sec warten
2
3
    _delay_ms(1);
4
5
   LCD_PORT = 0b01100010;
6
      lcd_enable();
7
8
    _delay_ms(1);
9
10
   LCD_PORT = 0b00110010;
11
      lcd_enable();

man sollte laut tabelle meinen, dass ein zeichen richtig angezeigt wird. 
so ist es auch. hierbei wird eine "6" angezeigt. andere zeichen 
funktionieren genauso. wenn ich aber zwei zeichen hintereinander 
anzeigen lasse (auf die gleiche Weise) werden bei gewolltem Anzeigebild 
"6+" folgende Buchstaben angezeigt: "&;" diese zeichen stehen jeweils in 
der selben reihe mit den Sollzeichen (in der Ascitabelle)??

von spess53 (Gast)


Lesenswert?

Hi

Also wenn bei deinem geposteten Code '6' rauskommt, stimmt etwas nicht. 
Deine Binärzahlen entsprechen ASCII 'b' und '2'.
Ist in BASCOM folgendes möglich  'LCD_PORT = '6';' ?

MfG Spess

von Benedikt K. (benedikt)


Lesenswert?

spess53 wrote:

> Also wenn bei deinem geposteten Code '6' rauskommt, stimmt etwas nicht.

Doch, das passt schon, zumindest halb
Er verwendet den 4bit Modus.
Das Bitmuster ist daher 01100011
Allerdings ist '6' eigentlich 00110110, also genau umgekehrt.
Ich vermute da ist bei der Initialisierung irgendwas durcheinander, 
wodurch High und Low Nibble sich verschieben.

von Sonke A. (soeni)


Lesenswert?

ah das kann sein, ich poste mal die Initialisierung:
1
   LCD_PORT = 0b00100000;
2
     lcd_enable();
3
    _delay_ms(1);
4
5
     lcd_enable(); // 2 mal senden
6
    _delay_ms(1);
7
8
   LCD_PORT = 0b00000000;
9
     lcd_enable();
10
       _delay_ms(1);
11
12
     lcd_enable();  // 2 mal senden
13
    _delay_ms(1);
14
15
   LCD_PORT = 0b11110000;
16
      lcd_enable();
17
    _delay_ms(1);
18
19
   LCD_PORT = 0b00000000;
20
      lcd_enable();
21
    _delay_ms(1);
22
23
   LCD_PORT = 0b00010000;
24
      lcd_enable();
25
    _delay_ms(1);
26
27
   LCD_PORT = 0b00000000;
28
      lcd_enable();
29
    _delay_ms(1);
30
31
   LCD_PORT = 0b01100000;
32
      lcd_enable();
33
34
    _delay_ms(15);

PS: die hab ich aus dem Datenblatt von meinem LCD übernommen.

von Benedikt K. (benedikt)


Lesenswert?

Zeig mal das Datenblatt. 44780 kompatibel ist das nämlich nicht. Bei dem 
sieht die Init etwas anderst aus. (3x 0011 senden usw.)

von Sonke A. (soeni)


Lesenswert?


von spess53 (Gast)


Lesenswert?

Hi

Und welches hast du nun?

MfG Spess

von Benedikt K. (benedikt)


Lesenswert?

Mach die Pausen beim Init mal sehr viel länger. Laut Datenblatt muss man 
nach dem ersten Befehl >4,1ms warten.
Auch der return home Befehl braucht 1,5ms.

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
Noch kein Account? Hier anmelden.