LCD und atmega328p -> Timingprobleme??

OP #4489698
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
Gast #4489756
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.
OP #4489781
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
Gast #4489793
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...
Gast #4489909
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...
OP #4491494
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 :-)
OP #4512706
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

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