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
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.
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
hab gerade auch nochmal andere settings probiert, alles größer als 2Mhz geht nicht Schorsch
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.
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.
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
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...
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
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?
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...
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 :-)
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.