EADOGM162W-A-Anzeige mit XMEGA

Gast #7797688
Lesenswert?

Hallo zusammen,

ich versuche, meine Hardware mit ATxmega128A1 zu programmieren. Ich benutze ein Display EADOM162W-A, 3.V, 4bit, parallel, ohne LED-Hintergrundbeleuchtung. Wenn ich den Code hochlade, sehe ich nur schwarze Kästchen, außerdem sehe ich in meinem Code Spannung am RS-Pin immer hoch, E-Pin immer niedrig und D4-D7 auch niedrig. Die Spannungen an diesen Pins schalten nur um, wenn ich sie explizit in 'int main' zum Umschalten programmiere. Mein Code ist unten angehängt, ich würde mich über jeden Vorschlag freuen. Ich danke Ihnen.

#define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h>

// Define LCD pins #define LCD_E PIN0_bm // Enable (PC0) #define LCD_RS PIN1_bm // Register Select (PC1) #define LCD_D4 PIN3_bm // Data Bit 4 (PC3) #define LCD_D5 PIN2_bm // Data Bit 5 (PC2) #define LCD_D6 PIN5_bm // Data Bit 6 (PC5) #define LCD_D7 PIN4_bm // Data Bit 7 (PC4)

// Helper macros #define LCD_E_HIGH() (PORTC.OUTSET = LCD_E) #define LCD_E_LOW() (PORTC.OUTCLR = LCD_E) #define LCD_RS_HIGH() (PORTC.OUTSET = LCD_RS) #define LCD_RS_LOW() (PORTC.OUTCLR = LCD_RS)

// Function Prototypes void lcd_init(); void lcd_send_command(uint8_t cmd); void lcd_send_data(uint8_t data); void lcd_send_nibble(uint8_t nibble); void lcd_print(const char *str); void lcd_clear(); void lcd_set_cursor(uint8_t row, uint8_t col);

// Initialize the LCD void lcd_init() { // Configure LCD pins as outputs PORTC.DIRSET = LCD_E | LCD_RS | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;

1
_delay_ms(50); // Wait for power stabilization
2

3
// Send initialization commands
4
lcd_send_command(0x39); // Function set: 2-line, extended instruction set
5
_delay_ms(5);
6
lcd_send_command(0x14); // Bias set
7
_delay_ms(5);
8
lcd_send_command(0x55); // Power control: Booster ON, Contrast C5, C4
9
_delay_ms(5);
10
lcd_send_command(0x6D); // Follower control: Voltage follower and gain
11
_delay_ms(200);         // Allow voltage follower to stabilize
12
lcd_send_command(0x74); // Contrast set (low bits)
13
_delay_ms(5);
14
lcd_send_command(0x38); // Function set: Normal instruction set
15
_delay_ms(5);
16
lcd_send_command(0x0C); // Display ON: Display ON, cursor OFF, blink OFF
17
_delay_ms(5);
18
lcd_send_command(0x01); // Clear display
19
_delay_ms(10);           // Wait for clear command to execute
20
lcd_send_command(0x06); // Entry mode set: Increment cursor, no shift
21
_delay_ms(5);

}

// Send a command to the LCD void lcd_send_command(uint8_t cmd) { LCD_RS_LOW(); // Command mode lcd_send_nibble(cmd >> 4); // Send high nibble lcd_send_nibble(cmd & 0x0F); // Send low nibble _delay_us(100); // Wait for the command to execute }

// Send data to the LCD void lcd_send_data(uint8_t data) { LCD_RS_HIGH(); // Data mode lcd_send_nibble(data >> 4); // Send high nibble lcd_send_nibble(data & 0x0F); // Send low nibble _delay_us(100); // Wait for the data to execute }

// Send a nibble (4 bits) to the LCD void lcd_send_nibble(uint8_t nibble) { PORTC.OUTCLR = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7; // Clear data lines

1
// Set data lines based on nibble
2
if (nibble & 0x01) PORTC.OUTSET = LCD_D4;
3
if (nibble & 0x02) PORTC.OUTSET = LCD_D5;
4
if (nibble & 0x04) PORTC.OUTSET = LCD_D6;
5
if (nibble & 0x08) PORTC.OUTSET = LCD_D7;
6

7
LCD_E_HIGH(); // Pulse E pin
8
_delay_us(2); // Increased pulse width
9
LCD_E_LOW();
10
_delay_us(200); // Increased latch time

}

// Print a string to the LCD void lcd_print(const char *str) { while (*str) { lcd_send_data(*str++); // Send characters in data mode _delay_ms(2); // Added delay between characters } }

// Clear the LCD display void lcd_clear() { lcd_send_command(0x01); // Clear display command _delay_ms(10); // Wait for clear command to execute }

// Set the cursor to a specific position void lcd_set_cursor(uint8_t row, uint8_t col) { uint8_t address = (row == 0) ? col : (0x40 + col); lcd_send_command(0x80 | address); // Set DDRAM address _delay_ms(2); // Added delay for cursor set }

// Main program int main() { lcd_init(); // Initialize the LCD

1
lcd_clear(); // Clear the display
2

3
// Write "Hello" to the top row
4
lcd_set_cursor(0, 0);
5
lcd_print("Hello");
6

7
// Write "World!" to the bottom row
8
lcd_set_cursor(1, 0);
9
lcd_print("World!");
10

11
while (1) {
12
    // Main loop
13
}
14

15
return 0;

}

Angehängte Dateien:
#7797713
Lesenswert?

Dreh mal den Kontrast runter

1
Procedure DOGM_Init;
2
  Begin
3
    LCDCtrl_M(LCD_m1,$39);               // 8 Bit, 2 Zeilen, InstructionSet 01
4
    LCDCtrl_M(LCD_m1,$1C);               // BIAS 1/4, 2 Zeilen
5
    LCDCtrl_M(LCD_m1,$52);               // Booster aus, Contrast C5 & C4
6
    LCDCtrl_M(LCD_m1,$69);               // Follower-Control
7
    LCDCtrl_M(LCD_m1,$70);               // Contrast C3, C2, C1 & C0
8
    LCDCtrl_M(LCD_m1,$0C);               // Display On, Cursor & Cursor Position Off
9
    LCDCtrl_M(LCD_m1,$38);               // 8 Bit, 2 Zeilen, InstructionSet 00
10
    LCDCtrl_M(LCD_m1,$01);               // Clear Display
11
    LCDCtrl_M(LCD_m1,$06);               // Cursor AutoIncrement
12
  End DOGM_Init;
13
  
14
  
15
Procedure DOGM_Contrast(Contrast:Byte);  // Contrast-Werte 0-63
16
  Var HC, LC :Byte;
17
  Begin
18
    HC:=(Contrast and %00110000) Div 16; // Contrast C5 & C4
19
    LC:=Contrast and %00001111;          // Contrast C3, C2, C1 & C0
20
    LCDCtrl_M(LCD_m1,$39);               // 8 Bit, 2 Zeilen, InstructionSet 01
21
    LCDCtrl_M(LCD_m1,$70 or LC);         // Booster aus, Contrast C5 & C4
22
    LCDCtrl_M(LCD_m1,$50 or HC);         // Contrast C3, C2, C1 & C0
23
    LCDCtrl_M(LCD_m1,$38);               // 8 Bit, 2 Zeilen, InstructionSet 00
24
  End DOGM_Contrast;

Achtung für 5V

Gast #7797812
Lesenswert?

Danke. Aber die schwarzen Kästen erscheinen immer noch. Auch die Spannungen schalten nicht um. RS ist immer hoch, E ist immer niedrig, D4 hoch, D5-D7 niedrig.

Ich habe den folgenden Code verwendet:

#define F_CPU 16000000UL // Define the CPU frequency as 16 MHz #include <avr/io.h> #include <util/delay.h>

// Define pin connections #define RS 1 // PC1 #define E 0 // PC0 #define D4 3 // PC3 #define D5 2 // PC2 #define D6 5 // PC5 #define D7 4 // PC4

// Function Prototypes void LCD_Init(void); void LCD_Command(unsigned char cmd); void LCD_Data(unsigned char data); void LCD_SetContrast(uint8_t contrast); void LCD_EnablePulse(void); void SendNibble(unsigned char nibble);

int main(void) { // Set RS, E, D4-D7 as outputs PORTC.DIR |= (1 << RS) | (1 << E) | (1 << D4) | (1 << D5) | (1 << D6) | (1 << D7);

// Initialize the LCD LCD_Init();

// Set contrast to a middle value (e.g., 32 out of 63) LCD_SetContrast(32);

// Display a test message LCD_Command(0x80); // Set cursor to the first position LCD_Data('H'); LCD_Data('E'); LCD_Data('L'); LCD_Data('L'); LCD_Data('O');

while (1) { // Infinite loop (do nothing) } }

void LCD_Init(void) { _delay_ms(20); // Wait for LCD to power up

// DOGM162 initialization sequence LCD_Command(0x39); // Function Set: 8-bit, 2-line, instruction set 01 LCD_Command(0x1C); // Bias 1/4, 2-line display LCD_Command(0x52); // Booster off, contrast C5 & C4 LCD_Command(0x69); // Follower Control LCD_Command(0x70); // Contrast C3, C2, C1, & C0 LCD_Command(0x0C); // Display ON, Cursor OFF LCD_Command(0x38); // Function Set: 8-bit, 2-line, instruction set 00 LCD_Command(0x01); // Clear Display _delay_ms(2); // Clear display requires longer delay LCD_Command(0x06); // Cursor AutoIncrement _delay_ms(2); }

void LCD_SetContrast(uint8_t contrast) { uint8_t HC, LC;

// Extract high and low contrast bits HC = (contrast & 0x30) >> 4; // Contrast C5 & C4 LC = (contrast & 0x0F); // Contrast C3, C2, C1 & C0

// Send commands to adjust contrast LCD_Command(0x39); // Function Set: 8-bit, 2-line, instruction set 01 LCD_Command(0x70 | LC); // Set lower contrast bits (C3-C0) LCD_Command(0x50 | HC); // Set higher contrast bits (C5-C4) LCD_Command(0x38); // Function Set: 8-bit, 2-line, instruction set 00 }

void LCD_Command(unsigned char cmd) { PORTC.OUT &= ~(1 << RS); // RS = 0 for command

// Send upper nibble SendNibble(cmd >> 4); LCD_EnablePulse();

// Send lower nibble SendNibble(cmd & 0x0F); LCD_EnablePulse();

_delay_us(50); // Short delay for command processing }

void LCD_Data(unsigned char data) { PORTC.OUT |= (1 << RS); // RS = 1 for data

// Send upper nibble SendNibble(data >> 4); LCD_EnablePulse();

// Send lower nibble SendNibble(data & 0x0F); LCD_EnablePulse();

_delay_us(50); // Short delay for data processing }

void SendNibble(unsigned char nibble) { PORTC.OUT &= ~((1 << D4) | (1 << D5) | (1 << D6) | (1 << D7)); // Clear data pins if (nibble & 0x01) PORTC.OUT |= (1 << D4); // Set D4 if (nibble & 0x02) PORTC.OUT |= (1 << D5); // Set D5 if (nibble & 0x04) PORTC.OUT |= (1 << D6); // Set D6 if (nibble & 0x08) PORTC.OUT |= (1 << D7); // Set D7 }

void LCD_EnablePulse(void) { PORTC.OUT |= (1 << E); // Set E HIGH _delay_us(1); // Pulse width PORTC.OUT &= ~(1 << E); // Set E LOW _delay_us(100); // Command processing delay }

#7807012
Lesenswert?

Wäre jemand so freundlich, meinen Code zu überprüfen?

Nachdem sich niemand meldet, versuche ich es mal, allerdings ohne allzu große Hoffnung, denn: ich habe hier nur ein Uralt-LCD, 2*16 stellig (ist wohl ein HD44780). Damit funktioniert das vorgestellte Programm, wenn ich die 10 Zeilen nach 'Initialization sequence as per datasheet' ersetze durch

1
lcd_send_byte(0x28, 1);
2
lcd_send_byte(0x06, 1);
3
lcd_send_byte(0x0C, 1);

Dass ich mit einem ATmega4809 arbeite, sollte keine Rolle spielen.

Beitrag #7807034 wurde von einem Moderator gelöscht.
Gast #7807306
Lesenswert?

Hallo zusammen, vielen Dank für die vielen Anregungen. Ich habe in der Lage gewesen, die Zeichen auf dem Display zu sehen, aber es geht zurück zu schwarzen Boxen Gewinn nach ein paar Millisekunden. Ich habe die Initialisierung gemäß der Seite 41 von https://www.lcd-module.com/eng/pdf/zubehoer/st7036.pdf durchgeführt.

Könnte es möglicherweise irgendwelche anderen Probleme im Code geben? Vielen Dank für Ihre Erkenntnisse.

Angehängte Dateien:
Beitrag #7807322 wurde von einem Moderator gelöscht.
(Firma: L-E-A) #7807334
Lesenswert?

Arnab schrieb:

Könnte es möglicherweise irgendwelche anderen Probleme im Code geben? Vielen Dank für Ihre Erkenntnisse.

Du solltest bei der Initialisierung des I/O-Ports zuerst das Datenregister initialisieren und dann erst die Bits im Direction-Register setzen. Ansonsten gibt es kurze Impulse, falls im Datenrigister Bits gesetzt waren.

Grüßle, Volker

(Firma: L-E-A) #7807338
Lesenswert?

Arnab schrieb:

Ich habe in der Lage gewesen, die Zeichen auf dem Display zu sehen, aber es geht zurück zu schwarzen Boxen Gewinn nach ein paar Millisekunden.

So ganz verstehe ich Deine Aussage nicht. Wenn die Zeichen zuerst lesbar waren und dann verschwinden, würde ich auf eine falsche Einstellung des Kontrastst tippen.

Respekt, dass Deine Augen "ein paar Millisekunden" auflösen. Bei mir liegt's in der Größenordnung von hundert Millisekunden. :-)

Grüßle, Volker

Gast #7807344
Lesenswert?

Volker B. schrieb:

So ganz verstehe ich Deine Aussage nicht. Wenn die Zeichen zuerst lesbar waren und dann verschwinden, würde ich auf eine falsche Einstellung des Kontrastst tippen.

Respekt, dass Deine Augen "ein paar Millisekunden" auflösen. Bei mir liegt's in der Größenordnung von hundert Millisekunden. :-)

Grüßle, Volker

Ich meine, dass es nach der Anzeige der Zeichen wieder zu schwarzen Kästchen wird, sobald ich den Code flashe. Der Unterschied zwischen den Vout und Vin Pins des Displays ist 2.584 Volt. Könnte dies ein Problem sein? Ich habe es mit verschiedenen Kontrastwerten im Code versucht, aber es wird immer noch das Gleiche angezeigt.

Vielen Dank für Ihre Anregungen!

(Firma: L-E-A) #7807360
Lesenswert?

Arnab schrieb:

Ich meine, dass es nach der Anzeige der Zeichen wieder zu schwarzen Kästchen wird, sobald ich den Code flashe.

Sorry, aber das verstehe ich nicht. Wieso werden Zeichen angezeigt bevor Dein Code überhaupt ausgeführt wird?

Der Unterschied zwischen den Vout und Vin Pins des Displays ist 2.584 Volt. Könnte dies ein Problem sein?

Ich kenne das verwendete LCD leider nicht. Meine Erfahrungen beziehen sich auf den 44780 und für diesen scheint mir Deine Initialisierung zu funktionieren. Der Begriff "Voltage Booster" aus dem Datenblatt deutet darauf hin, dass es wohl einen Spannungsunterschied geben wird. Ist Vout höher als Vin?

Ich habe es mit verschiedenen Kontrastwerten im Code versucht, aber es wird immer noch das Gleiche angezeigt.

Ich würde die Werte nicht fest in den Code schreiben sondern in einem Vorversuch, z.B. über die serielle Schnittstelle, eingeben und dann schrittweise den gesamten Wertebreich "durchspielen", inkl. "booster on" und "booster off".

Grüße, Volker

#7807402
Lesenswert?

Arnab schrieb:

Initialisierung gemäß der Seite 41 von https://www.lcd-module.com/eng/pdf/zubehoer/st7036.pdf durchgeführt.

Dort ist angegeben lcd_send_byte(0x30); du machst daraus cd_send_nibble(0x03); Das ist sicher nicht das Gleiche. Wenn du schon Send_nibble() verwenden willst dann so:

1
  lcd_send_nibble(0x03);
2
  lcd_send_nibble(0x00);
3
  ....

Mach einfach was im DB steht dann geht das.

#7807409
Lesenswert?

Thomas Z. schrieb:

du machst daraus cd_send_nibble(0x03); Das ist sicher nicht das Gleiche.

Das ist schon korrekt. Bei der Initialisierung wird das LCD immer erst im 8-Bit-Modus angesprochen, deshalb ohne lcd_send_byte(), was daraus jeweils zwei Nibbles machen würde.

Das passiert dreimal, um es ggf. auch erstmal sauber aus dem 4-Bit-Modus zurückzuholen zu können, erst danach wird es dann auf 4-Bit umgeschaltet und dann nibbleweise angesprochen.

#7807421
Lesenswert?

Hmmm schrieb:

Das ist schon korrekt. Bei der Initialisierung wird das LCD immer erst im 8-Bit-Modus angesprochen, deshalb ohne lcd_send_byte(), was daraus jeweils zwei Nibbles machen würde.

nö ist eben nicht ok. Im Datenblatt steht ja eindeutig wie das Display zu initialisieren ist. Da steht nix davon dass man am Anfang nur Nibbles senden darf. Wenn also mit lcd_send_nipple() dann etwa so:

1
  //3 times functionset
2
  lcd_send_nibble(0x03); lcd_send_nibble(0x00);
3
  lcd_send_nibble(0x03); lcd_send_nibble(0x00);
4
  lcd_send_nibble(0x03); lcd_send_nibble(0x00);
5
  ...

übrigens ist ein delay() bei lcd_send_nipple() vollkommen überflüssig. Die delays sind immer nach einem vollständigen cmd notwendig.

(Firma: L-E-A) #7807427
Lesenswert?

Thomas Z. schrieb:

Im Datenblatt steht ja eindeutig wie das Display zu initialisieren ist. Da steht nix davon dass man am Anfang nur Nibbles senden darf.

Komisch, der Hitachi 44780 ist mit 4 Nibbles zufrieden, um ihn in den 4-Bit-Modus zu bringen. Es wäre auch unlogisch, 8-Bit-Daten zu fordern, wenn das LCD nur mit 4 Datenleitungen an die MCU gekoppelt ist.

Da die unteren 4 Datenleitungen nicht beschaltet sind, "sieht" das LCD bei Ausgabe des 0x03 Nibbles das Byte 0x30. Aber an diesem Punkt würde mir zu denken geben, dass der Hersteller des hier verwendeten LCD explizit fordert, die unbeschalteten Datenleitungen auf Vdd zu legen.

Wenn also mit lcd_send_nipple() dann etwa so:

1
>   //3 times functionset
2
>   lcd_send_nibble(0x03); lcd_send_nibble(0x00);
3
>   lcd_send_nibble(0x03); lcd_send_nibble(0x00);
4
>   lcd_send_nibble(0x03); lcd_send_nibble(0x00);
5
>   ...
6
>

...mit etwas Glück ignoriert der Controller die unötigen Null-Nibbles.

Grüßle, Volker

#7807441
Lesenswert?

Volker B. schrieb:

Komisch, der Hitachi 44780 ist mit 4 Nibbles zufrieden,

auch beim Hitachi ist es nicht anders. Ich benutzte seit 30 Jahren 3 Functionsets um in den 4 Bit Mode zu kommen. Das war so auch im alten Hitachi DB beschrieben. Erst die neueren DBs von Hitachi sind da anders. Nicht umsonst ist das Low nibble dont care. Die haben sich das damals ganz geschickt ausgedacht. Beim 3. FunktionSet kann man dann 1 bzw 2 Zeilen einstellen.

(Firma: L-E-A) #7807449
Lesenswert?

Thomas Z. schrieb:

Nicht umsonst ist das Low nibble dont care. Die haben sich das damals ganz geschickt ausgedacht.

Der Aussage stimme ich zu, nur Deine Folgerung, dass dann im 4-Bit-Modus explizit Null-Nibbles anzulegen seien, kann ich nicht nachvollziehen.

Aber, was soll's ich bin glücklich mit meinem Code und Du mit Deinem.:-)

Grüßle, Volker

#7807456
Lesenswert?

Thomas Z. schrieb:

Im Datenblatt steht ja eindeutig wie das Display zu initialisieren ist. Da steht nix davon dass man am Anfang nur Nibbles senden darf.

Ob Du die Funktion lcd_send_nibble() oder lcd_send_without_chopping_bytes_into_nibbles() nennst, ist völlig egal.

Es geht darum, was im Endeffekt passiert, nämlich Ansteuerung im 8-Bit-Modus. Erst wenn das LCD sicher im 4-Bit-Modus ist, sendet man jeweils 2 Nibbles.

Gast #7807505
Lesenswert?

Vielen Dank an alle für die Vorschläge. Nur ein kurzes Update, ich verband die D0-D3-Pins an die VDD, aber jetzt das Display nicht einschalten mit dem Code, den ich vor beigefügt. Auch die Vout-Pin-Spannung ist jetzt weniger als 3,3 V, die um 5,5 V war, während D0-D3 unverbunden gelassen wurden.

Außerdem zeigte D0-D3 3,28V an, wenn es nicht an VDD angeschlossen war.

Gast #7807560
Lesenswert?

S. L. schrieb:

Auch RS(39) und E(36) zeigen 0 Volt an.

Merkwürdig: RS ist mit PC1 des uCs verbunden, und zeigt bei mir nach Programmende High-Pegel, es erfolgt ja zum Schluss eine Textausgabe, also Daten, und RS wird nicht mehr explizit zurückgesetzt.

Für den Moment kehre ich zum vorherigen Aufbau zurück, wobei D0-D3 nicht angeschlossen sind. Das Display ist wieder eingeschaltet, die Zeichen blinken kurz auf und werden dann zu Kästchen. Auffallend ist, dass die Zeichenkästen blau sind, der Rest ist schwarz.

Die Spannungen am Rs-Pin zeigen 3,287 V, am E-Pin 0 V. D0-D3 (unverbundene Pins) zeigen 3,244 V

#7807567
Lesenswert?

Ein allerletzter Versuch von meiner Seite: was passiert denn, wenn Sie die ST7036-spezifischen Kommandos weglassen bzw. auskommentieren ('Contrast Control Commands', diese 0x70, 0x5E, 0x6C), d.h. für den Anfang auf die Reset-Werte des ST7036 vertrauen?

#7807609
Lesenswert?

Arnab schrieb:

Ich habe die Initialisierung gemäß der Seite 41 von https://www.lcd-module.com/eng/pdf/zubehoer/st7036.pdf durchgeführt.

Und wo ist der Schritt (s. Anlage) ?

Die 3,3V an den unbenutzten Pins sollten schon angelegt werden - steht ja nicht umsonst im Datenblatt.

Kann es an Deiner Platine / Lötstellen liegen? Sieht ja nicht unbedingt "Fabrikfrisch" aus :-)

Hast Du das auch wirklich so ("ungewöhnlich") verschaltet?

#define LCD_D4 PIN3_bm // Data Bit 4 (PC3) #define LCD_D5 PIN2_bm // Data Bit 5 (PC2) #define LCD_D6 PIN5_bm // Data Bit 6 (PC5) #define LCD_D7 PIN4_bm // Data Bit 7 (PC4)

Angehängte Dateien:
Beitrag #7807637 wurde von einem Moderator gelöscht.
Gast #7807638
Lesenswert?

Hugo H. schrieb:

Schön wäre es, wenn Du auch Fragen beantworten würdest.

Verwendets Du wirklich einen

Arnab schrieb:

ATxmega128A1

?

Falls ja, wo stellst Du denn den Takt für den X-mega ein? Und woher soll der kommen? Intern oder extern? Im Standard läuft der nicht mit 16 MHz.

Ja, ich verwende ATxmega128A1, der externe Takt von 16MHz ist in die Xmega-Hardware integriert.

Gast #7807646
Lesenswert?

Hugo H. schrieb:

Arnab schrieb:

der externe Takt von 16MHz ist in die Xmega-Hardware integriert

Das wäre mir neu - wo steht das? Nach meiner Kenntnis müssen dazu Bits in Control-Registern eingestellt werden - in der "Startup-Sequenz".

Hier kannst Du Dich schlau machen: https://www.kampis-elektroecke.de/mikrocontroller/xmega-clock/

Der Takt ist hier nicht das Problem. Ein externer 16MHz-Takt wurde an die MCU angeschlossen. Tut mir leid, wenn Sie mich falsch verstehen. Trotzdem vielen Dank für die Anregung :)

Gast #7808044
Lesenswert?

Leider hat es bisher nicht funktioniert. Das Zeichen erscheint nur kurz und verwandelt sich dann in Kästchen. Ich kann die Zeichen sehen, wenn ich das Display aus einem bestimmten Winkel betrachte.

Ich habe die Pins D0-D3 wieder an VDD angeschlossen. Die Lötung ist in Ordnung und ein 16MHz externer Quarz (HC6035/4-16MHz) ist an die MCU angeschlossen. Die am E-Pin beobachtete Spannung war niedrig und lag in allen Testfällen bei 3,286 V.

Gast #7808096
Lesenswert?

S. L. schrieb:

Klingt nach falsch eingestelltem Kontrast.

Das sehe ich ähnlich, aber meine Frage von gestern nachmittag war keiner Antwort wert ...

Es hat nicht geklappt..

Ich habe auch bemerkt, dass der E-Pin in allen Testfällen immer 0 Volt und der Rs-Pin immer hoch war.

#7808106
Lesenswert?

Ich wollte eigentlich nichts mehr schreiben, aber das kann nicht funktionieren:

1
// Step 2: 8-bit Mode Initialization (3 times Function Set 0x30)
2
  lcd_send_nibble(0x03); lcd_send_nibble(0x00); // First function set
3
  _delay_ms(5);                                  // Longer delay after the first command
4
  lcd_send_nibble(0x03); lcd_send_nibble(0x00); // Second function set
5
  _delay_us(200);                                // Shorter delay for subsequent commands
6
  lcd_send_nibble(0x03); lcd_send_nibble(0x00); // Third function set
7
  _delay_us(200);
8
  // Step 3: Force 4-bit Mode (0x20)
9
  lcd_send_nibble(0x02); lcd_send_nibble(0x00); // Force 4-bit mode
10
  _delay_us(200);

Das jeweils 2. "lcd_send_nibble(0x00)" gehört da nicht hin - es wird ein zusätzlicher Enable-Impuls erzeugt, der (mit Wert 0) nicht in die Initialisierungs-Sequenz gehört.

Erst nach Einstellung auf 4-Bit-Modus werden jeweils 2 Nibble mit 2 Enable-Impulsen erwartet.

Gast #7808116
Lesenswert?

S. L. schrieb:

Der Code ist beigefügt :)

Ich schrieb "die ST7036-spezifischen Kommandos weglassen ... ('Contrast Control Commands')", aber das steht nach wie vor drin: step 4..6.

Leider ist es immer noch so.

Ich möchte mich noch einmal bei allen bedanken, die hier kommentieren, das hilft wirklich :)

#7808121
Lesenswert?

Arnab schrieb:

Leider ist es immer noch so.

Hast Du denn mal versucht, den Kontrast zu variieren?

Ich habe immer mehr das Gefühl, dass Du gar nicht verstehst, was Du tust, sondern nur mit Copy&Paste und unseren Anmerkungen ziellos etwas zusammenwurstelst.

Was soll z.B. das manuelle Zerlegen der 4-Bit-Kommunikation in Nibbles, wenn Du genau dafür lcd_send_byte() hast?

#7808463
Lesenswert?

Aus meiner Sich gibt es 2 Möglichkeiten:

1.) Hmmm schrieb im Beitrag #7808121:

Ich habe immer mehr das Gefühl, dass Du gar nicht verstehst, was Du tust, sondern nur mit Copy&Paste und unseren Anmerkungen ziellos etwas zusammenwurstelst.

Dazu kann es Fehler in der Schaltung / auf dem PCB geben, die wir nicht kennen.

Ferner vermute ich, dass permanent ein Programmer (ggf. aktiv) über ISP an Port C hängt (parallel zum Display) und dort für "interessante Effekte" sorgt.

2.) Troll

(Firma: L-E-A) #7808535
Lesenswert?

Hugo H. schrieb:

Ferner vermute ich, dass permanent ein Programmer (ggf. aktiv) über ISP an Port C hängt (parallel zum Display) und dort für "interessante Effekte" sorgt.

Oh, eine KI, die halluziniert? Xmegas werden üblicherweise über zwei dedizierte Pins programmiert, die nicht mit I/O-Ports geteilt werden. Der ATxmega128A1(U) besitzt auch noch ein JTAG-Interface, welches aber an PortB hängt.

Nachtrag: Aber eine Kollision mit der Peripherie an Port C wäre möglich: TWIC, SPIC, USARTC0 und -C1 sowie TCC0 und -1. Aber der TO wird diesen Hinweis sicherlich ebenfalls ignorieren. :-(

Grüßle, Volker

#7809161
Lesenswert?

Das hat mir keine Ruhe gelassen. Ich kann es zwar selbst nicht glauben, aber probiere mal diese Sequenz für die Initialisierung:

1
lcd_send_byte(0x30);
2
lcd_send_byte(0x33);
3
lcd_send_byte(0x32);
4
lcd_send_byte(0x21); (2. Halbbyte 1 oder ggf. 9 bei 2-zeilig - ausprobieren)

Dann mit "Clear" und "Display on" und irgendwelchen Ausgaben weiter.

Auf einem 163er Display (habe ich hier und jetzt ausprobiert) funktioniert das - muss man nicht verstehen ...

Und ja, stammt von hier:

1
// (C) 2020 by Oliver Kuhlemann                        //
2
// Bei Verwendung freue ich mich ueber Namensnennung,  //
3
// Quellenangabe und Verlinkung                        //
4
// Quelle: http://cool-web.de/arduino/                 //
Beitrag #7813538 wurde von einem Moderator gelöscht.
#7813541
Lesenswert?

Na, da war ja wieder mal ein Minus-Kasper unterwegs :-)

Falls irgendwann jemand nochmal danach sucht nachstehend 2 Hinweise:

Den habe ich gefunden, indem ich eigentlich diesen Thread gesucht habe

Beitrag "gewünschter Code für EADOGM Display"

Und als Anlage habe ich ein kleines Arduino-Beispiel nach "meinem Gusto" zusammengestellt (bevor ich vorstehenden Link gefunden hatte). Im ST7306 Datenblatt von SILABS wird "empfohlen", das Busy-Flag abzufragen. Dort gibt es auch Assembler-Beispiele, an die ich mich angelehnt habe. Ich verwende _delay_us() statt NOP, damit ist die Wartezeit zwar etwas zu lang, aber immer dem CPU-Takt (der hoffentlich richtig eingestellt ist) angepasst. Das Beispiel ist für ein 3-zeiliges EADOGM163.. ausgelegt.

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren