Forum: Mikrocontroller und Digitale Elektronik AVR Atmega EA DOGM163x-A 4-bit


von B. H. (bluehazzard)


Lesenswert?

Hallo,
ich versuche gerade das EA DOGM163x-A (3 Zeiliges LCD mit ST7036 
controller) im 4bit Modus zum laufen zu bekommen. Mein Controller ist 
ein Atmega32 mit integriertem Taktgeber von 1Mhz (wird später aber mit 
16MHz betrieben)
Mein Problem ist, dass die Pin Belegung schon vorgegeben ist:
1
#define DB4    PA7
2
#define DB5    PA6
3
#define DB6           PA5
4
#define DB7    PA4

Also das Display hängt am PORTA aber die Pins sind vertauscht also: PA7 
-> DB4 usw... (wie man dem #define entnehmen kann...).

Ich habe nun eine Initialisierungsroutine geschrieben, aber sie 
funktioniert nicht:
1
void lcd_init()
2
{
3
     LCD_DDR = LCD_DDR | 0xF0 | (1<<LCD_RS) | (1<<LCD_EN);   // Port auf Ausgang schalten
4
5
     LCD_PORT |= (1<<LCD_EN);
6
  LCD_PORT &= ~(1<<LCD_RS);
7
  _delay_us(40);      //Hier eventuell 40ms wie im Datenblatt
8
  
9
  LCD_PORT |= (1<<DB4) | (1<<DB5);
10
  lcd_enable();
11
  _delay_ms(2);      //Hier konnte man auch rumschrauben...
12
  lcd_enable();
13
  _delay_us(30);
14
  lcd_enable();
15
  _delay_us(30);
16
  
17
  LCD_PORT &= ~(1<<DB4);
18
  lcd_enable();
19
  _delay_us(30);
20
21
  //LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
22
  //Das ganze noch einmal                    //Function set
23
  lcd_enable();
24
  //Jetz das untere Byte
25
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
26
  LCD_PORT |= (1<<DB7) | (1<<DB4);
27
  lcd_enable();
28
  _delay_us(30);
29
  
30
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Internal OSC Frequenze
31
  LCD_PORT |= (1<<DB4);
32
  lcd_enable();
33
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
34
  LCD_PORT |= (1<<DB6) | (1<<DB4);
35
  lcd_enable();
36
  _delay_us(30);
37
38
  
39
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Contrast set
40
  LCD_PORT |= (1<<DB6) | (1<<DB5) | (1<<DB4);
41
  lcd_enable();
42
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  
43
  LCD_PORT |= (1<<DB7) | (1<<DB6);
44
  lcd_enable();
45
  _delay_us(30);
46
47
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Power ICON Contrast control
48
  LCD_PORT |= (1<<DB6) | (1<<DB4);
49
  lcd_enable();
50
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
51
  LCD_PORT |= (1<<DB7) | (1<<DB6);
52
  lcd_enable();
53
  _delay_us(30);
54
55
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Follower Controll
56
  LCD_PORT |= (1<<DB6) | (1<<DB5);
57
  lcd_enable();
58
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
59
  LCD_PORT |= (1<<DB7) | (1<<DB6);
60
  lcd_enable();
61
  _delay_us(30);
62
63
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Display ON/OFF control
64
  //LCD_PORT |= (1<<DB6) | (1<<DB5);
65
  lcd_enable();
66
  //LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
67
  LCD_PORT |= (1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7);
68
  lcd_enable();
69
  _delay_us(30);
70
71
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Display Loschen Cursor Home
72
  //LCD_PORT |= (1<<DB6) | (1<<DB5);
73
  lcd_enable();
74
  //LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
75
  LCD_PORT |= (1<<DB4);
76
  lcd_enable();
77
  _delay_us(30);
78
79
  LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));  //Display Loschen Cursor Home
80
  //LCD_PORT |= (1<<DB6) | (1<<DB5);
81
  lcd_enable();
82
  //LCD_PORT &= ~((1<<DB4) | (1<<DB5) | (1<<DB6) | (1<<DB7));
83
  LCD_PORT |= (1<<DB5) | (1<<DB6);
84
  lcd_enable();
85
  _delay_us(30);
86
87
}

im moment schaut sie sperrig aus, aber ich werde sie, wenn sie 
funktioniert schon noch zusammenfassen....
Findet hier jemand den Fehler? Angeschlossen ist alles richtig, das habe 
ich schon überprüft.

mfg.
und Danke.

von Hans (Gast)


Lesenswert?

Warum schreibst Du das in C - das geht doch in Hex viel übersichtlicher 
:-)

Sorry, aber lesbar ist der Code nicht wirklich, wer soll sich das 
antun?

Hans

von Tobias J. (tobiasjohn) Benutzerseite


Lesenswert?

Hans wrote:
> Warum schreibst Du das in C - das geht doch in Hex viel übersichtlicher
> :-)
Das musst du mir vormachen... also das in HEX schreiben G

von AVR-Tester (Gast)


Lesenswert?

Hallo,

 so schaut es aus, wenn es funktioniert(DOGM163).
 Beachte meine 4Bit und 8Bit Anweisungen.
 Der Code ist halt nur bei mir lauffähig, aber die Reihenfolge der 
Befehle (Hex-Werte) ist einzuhalten.

 #ifdef LCD_DATA_4BIT      /* Function set1. */
   lcdControlWrite(0x28);   /* 4 Bit   */
  #else
   lcdControlWrite(0x38);   /* 8 Bit  */
  #endif

  #ifdef LCD_DATA_4BIT    /* Function set2. */
   lcdControlWrite(0x29);    /* 4 Bit   */
  #else
   lcdControlWrite(0x39);    /* 8 Bit  */
  #endif                   /* Function set2. */

  lcdControlWrite(0x15);    /* Bias 1/5, 2 lines. */
  lcdControlWrite(0x55);    /* Power/ICON/Contrast control.*/
  lcdControlWrite(0x6E);    /* Follower control. */
  lcdControlWrite(0x72);    /* Booster on, Contrast set.

 #ifdef LCD_DATA_4BIT      /* switch back to instruction */
  lcdControlWrite(0x28);  /* 4 Bit   */
 #else
  lcdControlWrite(0x38);   /* 8 Bit  */
 #endif

    lcdControlWrite(0x0F);    /* Display on. */
    lcdControlWrite(0x01);    /* Clear display. */
    lcdControlWrite(0x06);    /* Entry mode set. */

Gruß avr-tester

von AVR-Tester (Gast)


Lesenswert?

Hallo, bin nochmals da, habe was vergessen!

Schau dir doch mal meine Homepage an, da findest du einige Infos zu 
DOGM's

http://www.basteln-mit-avr.de/

Gruß AVR-Tester

von B. H. (bluehazzard)


Lesenswert?

@Hans:
Das der Code so schwerer zu lesen ist weis ich, aber wenn man nur 
schnell mal ein bit löschen oder setzen will, kommt es mir so effektiver 
vor...
Wie ich schon schrie werde ich dann alles in Hex umschreiben, wenn es 
mal funktioniert....

@ AVR-Tester:
Danke für den Beispielcode, ich werde die Reihenfolge testen..., aber 
was für Wartezeiten benutzt du? die wie sie im Datenblatt des st**** 
angeführt sind?
Deine Seite habe ich übrigens schon mit meinem Freund google gefunden, 
aber leider keinen passenden Beispielcode...

mfg.
und danke

von Jörg G. (joergderxte)


Lesenswert?

@ OP:
Suchst du sowas:
1
#define LCD_D4 (1<<PA7)
2
#define LCD_D5 (1<<PA6)
3
#define LCD_D6 (1<<PA5)
4
#define LCD_D7 (1<<PA4)
5
#define LCD_DATA_MASK (LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7)
6
/* REMAP() unbedingt auf Konstanten anwenden
7
   Damit der Compiler das alles aufloesen kann */
8
#define REMAP(_byte) (( _byte & (1<<4)? LCD_D4 : 0)\
9
                     |( _byte & (1<<5)? LCD_D5 : 0)\
10
                     |( _byte & (1<<6)? LCD_D6 : 0)\
11
                     |( _byte & (1<<7)? LCD_D7 : 0))
12
//...
13
LCD_PORT = LCD_PORT              // Falls es noch mehr pins gibt ;)
14
           & ~LCD_DATA_MASK      // loesche Datenbits
15
           | REMAP( daten_byte); // setze neue Daten
Und sortier' deinen Code aus (extra static Funktion zum Nibble-, 
(Daten-,Befehls-)Byteübertragen), _delay_ms() ist wahrscheinlich besser 
um 40ms zu warten, definiere Namen (Macros) für die LCD-Befehle usw.

hth, Jörg

von B. H. (bluehazzard)


Lesenswert?

Hallo,
@Jörg: Danke, das hilft mir schon km weit weiter!!!!

Jetzt habe ich das Display so weit, dass es mir einen Cursor Anzeigt, 
und dieser blinkt auch.
Wenn ich nun einen Buchstaben Sende hüpft der Cursor zwar eine Stelle 
weiter, aber es erscheint kein Zeichen auf dem Display....

Zudem flackert es ab und zu, nicht die Hintergrundbeleuchtung, sondern 
die Flüssigkristalle, an was könnte das liegen?

mfg.

von AVR-Tester (Gast)


Lesenswert?

Hallo bluehazzard,

Wennn der Code stimmt, und das  Ganze lauffähig ist, ist die Wartezeit 
nicht das Thema. Da kann man ordentlich drehen. Generelle gilt, lieber 
die Zeiten vergrößern als kürzen.
Wenn im Datenblatt 40ms steht solltest Du auch die Zeit verwenden.
Meine: delay(60000);  // wait 60ms an diesem Punkt
Bei den 26,3us verwende ich 40us. Mit Oszi. am Port kontrolliert!!

Des weiteren ist am Ende der Routine ein weiterer Reset nötig.
Hier sollten die Zeiten bei einigen 100ms sein. Besser eine Sekunde 
warten.

Eine Erfolgreiche Init. ist ohne nachfolgende Daten nur schwer zu 
überprüfen. Das Ding macht ohne Daten nichts!
Stimmt das Senden der Daten auch nicht, drehst du dich im Kreis.

Ich würde mir mal ein lauffähiges System installieren. Dann weis man 
dass die Hardware (DOGM163) in Ordnung ist. Es gibt im Internet 
mittlerweile diverse kleine und erprobte Programme die deinem sehr 
ähnlich sind.

Dann , und nur dann würde ich meinen Code verwenden und geringfügige 
Displayänderungen durchführen.

Noch was zu Deinen kleinen Änderungen an den Display-Rourinen:
In einer gut geschrieben Display-Lib ist es ein Klacks auch die 
kleinsten Änderungen im Modus zu bewerkstelligen.

Zwei Routinen in einem Programm sind immer schlecht.

Das soll aber Deinen Ergeiz nicht bremsen, so und nicht anders habe ich 
auch meine Kenntnisse im Bereich AVR vertiefen können.

PS: Mir geht es zur Zeit mit dem Atxmegas genau so. Bit für Bit alles 
neu erkunden.


Gruß AVR-Tester

von B. H. (bluehazzard)


Lesenswert?

Hallo,
"Ich würde mir mal ein lauffähiges System installieren. Dann weis man
dass die Hardware (DOGM163) in Ordnung ist. Es gibt im Internet
mittlerweile diverse kleine und erprobte Programme die deinem sehr
ähnlich sind."

Diese Möglichkeit habe ich leider nicht.... bin ziemlich in der Pampa 
was elektronische Bauteile betrift, und brauche mindestens 3 Wochen um 
eine weitere Platine zu erstellen, muss das ganze aber so schnell wie 
möglich zum Laufen bringen.

Ich habe das Display mittlerweile so weit, dass es ohne Probleme Startet 
und sich initialisiert. Auch das flackern ist weg.
Mein Problem ist jetzt, dass es wenn ich es einschalte Sinnlose Zeichen 
zeigt, und der Befehl clr display keine Reaktion hervorruft. Wenn ich 
nun Daten schicke wandert zwar der Zeiger, aber es erscheinen keine 
Zeichen auf dem Display, und die die schon dort waren werden einfach 
übersprungen.
Was könnte da falsch sein?

mfg.
und Danke

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.