Forum: Mikrocontroller und Digitale Elektronik LCD und atmega328p -> Timingprobleme??


von Georg T. (microschorsch)


Lesenswert?

Hallo,
habe ein dummes Problem und komme gerade nicht weiter:

Ich entwickle seit einiger Zeit an einer Schaltung auf der ein LCD und 
ein atmega8 war. Das Display ist über einen 8-bit schieber via SPI im 
4-bit Modus angeschlossen. Das hat soweit immer funktioniert

Nun habe ich den Atmega8 durch einen Atmega328p ausgetauscht, weil ich 
eine SD-Karte dranhängen will. Seit dem will das Display nicht mehr.

Habe jetzt mal ein bisschen rumprobiert und gemerkt, dass ich durch 
verändern der Clock-Frequenz im Makefile das Display zum funktionieren 
bringen kann. Meine Beobachtung ist:
* Wenn das CKDIV8 Bit in den Fuses aktiviert ist, gehts überhaupt 
nichts.
* Wenn das CKDIV8 Bit deaktiviert ist und ich die CLK auf 2MHz stelle 
(obwohl intern eigentlich 8Mhz anliegen) geht das Display (in der Tat 
kommen die Pulse dann aber auch 4x zu "schnell"
* Wenn ich die CLK auf 1MHz stelle, kommt nur Kauderwelsch auf das 
Display

meine Fuses stehen momentan so: -U hfuse:w:0xd9:m -U lfuse:w:0xe2:m

Vielleicht hat jemand eine Idee, was da falsch läuft???

merci
Schorsch

von S. Landolt (Gast)


Lesenswert?

Wie war denn die Einstellung beim ATmega8?

von Mein grosses V. (vorbild)


Lesenswert?

Georg T. schrieb:
> Nun habe ich den Atmega8 durch einen Atmega328p ausgetauscht

Wenn die neue Software auf der des Atmega8 basiert, dann ist erstmal 
auch dessen Taktrate maßgebend.

von Georg T. (microschorsch)


Lesenswert?

wow, das ging schnell:

beim atmega8 hatte ich immer 8MHz und
-U hfuse:w:0xd9:m -U lfuse:w:0x24:m  // int. Clock

bzw:
-U hfuse:w:0xd1:m -U lfuse:w:0x24:m  // int. Clock, preserve EEPROM

ich hätte jetzt mal angenommen, dass der 328 mit den o.g.fuses ebenso 
8MHz macht


Schorsch

von Georg T. (microschorsch)


Lesenswert?

hab gerade auch nochmal andere settings probiert, alles größer als 2Mhz 
geht nicht

Schorsch

von Karl M. (Gast)


Lesenswert?

Schorsch das Programm für den Atmega8 kann man nicht auf den Atmega328p 
direkt ausführen.

Die Fusebits stimmen so auch nicht, schau in die beiden Datenblätter, 
dort ist ads alles beschrieben.

von S. Landolt (Gast)


Lesenswert?

E2 als low-fuse ergibt auf dem ATmega328 8 MHz, das stimmt. Und da ich 
zumindest auf den ersten Blick keine Unterschiede im SPI-Verhalten 
zwischen den beiden Controllertypen erkennen kann, muss ich erstmal 
passen.

von Georg T. (microschorsch)


Lesenswert?

Karl M. schrieb:
> Schorsch das Programm für den Atmega8 kann man nicht auf den Atmega328p
> direkt ausführen.
>
> Die Fusebits stimmen so auch nicht, schau in die beiden Datenblätter,
> dort ist ads alles beschrieben.

Hi, schon klar,
ich musste natürlich ein paar Register (TIMSK usw) anpassen, aber das 
erklärt noch nicht, weshalb das Display nicht mehr tut...

Schorsch

von c-hater (Gast)


Lesenswert?

Georg T. schrieb:

> Ich entwickle seit einiger Zeit an einer Schaltung auf der ein LCD und
> ein atmega8 war. Das Display ist über einen 8-bit schieber via SPI im
> 4-bit Modus angeschlossen. Das hat soweit immer funktioniert
>
> Nun habe ich den Atmega8 durch einen Atmega328p ausgetauscht, weil ich
> eine SD-Karte dranhängen will. Seit dem will das Display nicht mehr.
>
> Habe jetzt mal ein bisschen rumprobiert und gemerkt, dass ich durch
> verändern der Clock-Frequenz im Makefile das Display zum funktionieren
> bringen kann. Meine Beobachtung ist:
> * Wenn das CKDIV8 Bit in den Fuses aktiviert ist, gehts überhaupt
> nichts.
> * Wenn das CKDIV8 Bit deaktiviert ist und ich die CLK auf 2MHz stelle
> (obwohl intern eigentlich 8Mhz anliegen) geht das Display (in der Tat
> kommen die Pulse dann aber auch 4x zu "schnell"
> * Wenn ich die CLK auf 1MHz stelle, kommt nur Kauderwelsch auf das
> Display

Hmm, könnte das bitte mal etwas systematischer sein? Es kommt immer auf 
das Verhältnis zwischen realem Takt und dem Code per Vorgaben 
präsentierten Takt an, wie lang Software-Delays tatsächlich werden.

Die zwei letzteren Test sprechen dafür, dass schaltungsmäßig 
grundsätzlich erstmal alles in Ordnung ist. Bei um das vierfache zu 
schnellem Zugriff funktioniert noch alles, bei um das achtfache zu 
schnellem Zugriff nicht mehr. Das wäre normales Verhalten, irgendwann 
ist halt Schluss, dann wird das Timing zu schnell für das Display oder 
das Schieberegister.

Was überhaupt nicht dazu passt, ist der erste Test. Du hast aber nicht 
angegeben, wie der Takt für den Code für diesem Test eingestellt war. 
Deswegen ist es unmöglich, das Testergebnis sinnvoll einzuordnen. 
Sprich: du hast eine Nullinformation geliefert. Genauso nützlich zur 
Fehleranalyse wie das Schwarze unter den Fingernägeln...

von Georg T. (microschorsch)


Lesenswert?

c-hater schrieb:

>
> Was überhaupt nicht dazu passt, ist der erste Test. Du hast aber nicht
> angegeben, wie der Takt für den Code für diesem Test eingestellt war.

sorry, ich dachte ich war deutlich genung, :-)
es habe es unter keinen Umständen geschafft, dass es läuft. Egal bei 
welcher Einstellung

Geirg

von S. Landolt (Gast)


Lesenswert?

Handelt es sich um das Hardware-SPI oder ist es softwaremäßig gelöst?
Wie werden die Zeiten für das LCD erzeugt, per Programmschleife oder 
Timer?

von c-hater (Gast)


Lesenswert?

Georg T. schrieb:

> sorry, ich dachte ich war deutlich genung, :-)

Nein, warst du nicht.

> es habe es unter keinen Umständen geschafft, dass es läuft. Egal bei
> welcher Einstellung

Du warst immer noch nicht deutlich genug.

Es kann doch nicht so schwer sein, zu erkennen, dass "egal bei welcher 
Einstellung" immer noch nur eine Nullinformation ist, oder?

Mindestens ist nötig: geringste und höchste verwendete Einstellung. Am 
besten aber ist: jede getestete Einstellung.

Überlasse es einfach den Erwachsenen, festzustellen, was von den Angaben 
irrelevant ist. Dir jedenfalls fehlen ganz offensichtlich die 
Kenntnisse, das selber einzuschätzen. Und damit bist du auch gleich das 
Schlimmste, was nach der Theorie der Informatik als Informationsfilter 
auftreten kann: ein quasi zufallsgesteuerter...

Also versuche garnicht erst, Filter scheinbar unwichtiger Details zu 
sein. Jedenfalls wenn dir an der Lösung deines Problems gelegen ist...

von Georg T. (microschorsch)


Lesenswert?

S. Landolt schrieb:
> Handelt es sich um das Hardware-SPI oder ist es softwaremäßig gelöst?
> Wie werden die Zeiten für das LCD erzeugt, per Programmschleife oder
> Timer?

Hallo,

ich hab eine ganz einfache debugging-routine in die main-loop 
programmiert
1
 for (;;) {
2
  lcd_string("A");
3
  _delay_ms(1000);
4
  lcd_string("B");
5
  _delay_ms(1000);
6
}

das ist vielleicht ein bisschen primitiv, aber man kann ganz gut 
erkennen, ob die Zeichen sekundenweise oder deutlich schneller 
erscheinen - und ob sie überhaupt erscheien.

Es handelt sich um Hardware-SPI, hier ist mein code dazu:
1
void SPI_masterInit (void) {
2
  DDRB = _BV(PB0) | _BV(PB2) | _BV(PB3) | _BV(PB5);    // setze SCK,MOSI,PB0 (SS) als Ausgang
3
  DDRB &= ~_BV(PB4);              // setze MISO als Eingang
4
  PORTB = _BV(PB5) | _BV(PB2) | _BV(PB0);        // SCK und PB0 high (ist mit SS am Slave verbunden)
5
  SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);  //Aktivierung des SPI, Master, Taktrate fck/16
6
}
7
8
unsigned char SPI_sendToLCD (unsigned char data) {
9
  PORTB &= ~_BV(PB2);            //SS am Slave Low --> Beginn der ‹bertragung
10
  SPDR = data;                //Schreiben der Daten
11
  while (!(SPSR & (1<<SPIF)));
12
  PORTB |= _BV(PB2);              //SS High --> Ende der ‹bertragung
13
  return SPDR;
14
}

die üblichen lcd-routinen musste ich natürlich auch ein bisschen 
aufbohen, ist aber nichts dramatisches:
1
void lcd_data(unsigned char temp1){
2
   unsigned char temp2 = temp1;
3
 
4
   LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
5
   SPI_sendToLCD(LCD_PORT);
6
 
7
   temp1 = temp1 >> 4;
8
   temp1 = temp1 & 0x0F;
9
   LCD_PORT &= 0xF0;
10
   SPI_sendToLCD(LCD_PORT);
11
12
   LCD_PORT |= temp1;               // setzen
13
   SPI_sendToLCD(LCD_PORT);
14
15
   lcd_enable();
16
 
17
   temp2 = temp2 & 0x0F;
18
   LCD_PORT &= 0xF0;
19
   SPI_sendToLCD(LCD_PORT);
20
   LCD_PORT |= temp2;               // setzen
21
   SPI_sendToLCD(LCD_PORT);
22
   lcd_enable();
23
   
24
   _delay_us(46);
25
}

wie gesagt, hatte mit dem mega8 ja immer funktioniert.

PS: Kann man jemand diesen c-hater abstellen? Auf solche Rückmeldungen 
kann ich gerne verzichten :-)

von S. Landolt (Gast)


Lesenswert?

> ich musste natürlich ein paar Register (TIMSK usw) anpassen
Vielleicht ist dabei ein Fehler passiert, irgendein Konflikt MOSI<->OC2A 
oder /SS<->OC1B. Mehr fällt mir leider nicht mehr ein.

von Georg T. (microschorsch)


Lesenswert?

Hallo,

einige Zeit ist vergangen... manchmal ist es besser ein Thema ein paar 
Tage liegenzulassen....

konnte zumindest die Ursache für das Problem entdecken. Am Anfang meiner 
main-routine habe ich ein neues Zeichen (für °C) definiert, dort steht:
1
    lcd_command(0b01000000);
2
    lcd_data(0x12);
3
    lcd_data(0x15);
4
    lcd_data(0x04);
5
    lcd_data(0x04);
6
    lcd_data(0x04);
7
    lcd_data(0x05);
8
    lcd_data(0x02);
9
    lcd_data(0x00);


die routine lcd_command macht folgendes:
1
void lcd_command(unsigned char temp1) {
2
   unsigned char temp2 = temp1;
3
 
4
   LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
5
   SPI_sendToLCD(LCD_PORT);
6
 
7
   temp1 = temp1 >> 4;              // oberes Nibble holen
8
   temp1 = temp1 & 0x0F;            // maskieren
9
   LCD_PORT &= 0xF0;
10
   SPI_sendToLCD(LCD_PORT);
11
   LCD_PORT |= temp1;               // setzen
12
   SPI_sendToLCD(LCD_PORT);
13
   lcd_enable();
14
 
15
   temp2 = temp2 & 0x0F;            // unteres Nibble holen und maskieren
16
   LCD_PORT &= 0xF0;
17
   SPI_sendToLCD(LCD_PORT);
18
   LCD_PORT |= temp2;               // setzen
19
   SPI_sendToLCD(LCD_PORT);
20
   lcd_enable();
21
   
22
   _delay_us(46);
23
}

lcd_data steht schon weiter oben.
Irre ist, sobald ich diese paar Zeilen auskommentiere läuft das Display 
mit den richtigen Frequenzen im Makefile. Bin mir noch nicht sicher, was 
die darunterliegende Ursache ist. Wie gesagt auf nem mega8 liefs 
problemlos

Gruß Schorsch

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.