Hallo, habe seit einigen Tagen ein Testboard und einen Atmega 8, damit versuche ich nun ein Lcd Display anzusteuern. Ich nutze dafür die SPI Schnittstelle des DIP 204-4 von Electronic Assembly und habe im Assembler auch funktionierende Routinen dafür erstellt. Im angehängten File zeigt sich nun mein Problem: Das Display gibt eine Zahl aus, die wird in einer Schleife jede Sekunde um 1 verringert und wieder ausgegeben. Im Simulator funktioniert auch alles 1a, nur in der Wirklichkeit bleibt der Atmega 8 nach 1 bis 10 Sekunden stehen - wie er gerade Lust hat. D.h. mal bleibt 255 stehen und nichts tut sich mehr, ein anderes Mal läuft er 10 Sekunden bis 245 und quittiert dann den Dienst.. Herausgefunden habe ich schon, das es an der Lcd Ansteuerung liegen muss. In einfacheren Anwendungen (z.B. Blinken einer Led)läuft er Stunden ohne Probleme. Wäre nett wenn ihr mal in das angehängte .asm File reinschauen könntet, vielleicht findet ihr ja auf Anhieb einige Fehler. Und bitte nicht über den Code aufregen, programmiere erst seit 2 Wochen : ) Grüße Fabian
Vielleicht läuft dir der Stack über, in "lcd_senden_cmd" zb. push(t) du zu Beginn 3mal, aber nur 2 werden per pop wieder ausgelesen. Vielleicht ist es ja sowas einfachen ;-) Werner
@Werner: Erst lesen, dann antworten ;-) die Antwort wollte ich auch schon schreiben aber er popt mitten in der Routine nocheinmal und dann passts wieder. grüsse leo9
Hallo Fabian, auch wenn Dein Code nicht grade sehr schwere Kost ist, wäre es schön (bitte ich Dich), wend Du ein paar Komentare dazu zu schreiben würdest. Die "Helfer" haben es dann sehr viel einfacher, und Anfänger wie ich, können auch noch etwas Lernen. Danke. Grüße Quark
Hallo, Danke erstmal für eure Antworten! Werde den Code mal kommentieren, allerdings komme ich erst in ein paar Tagen dazu. Zum Stack: Kann er wegen den pushs schon überlaufen, dann müsste er doch immer zur gleichen Zeit stehen bleiben oder ? Grüße Fabian
Fabian, kannst du dich noch an dein damaliges Projekt erinnern? Ich habe jetz ein ähnliches Problem und habe diesen Thread gefunden. Ich steuere 2 DDS-ICs (AD9833) über SPI mit einem ATMEGA88. Grundlegende Treiber-Funktionen wurden schon programmiert und erfolgreich ausprobiert. Jetz wollte ich, dass die Phase eines DDS-ICs langsam "wegschwimmt". Dazu der folgende Code: [c] ... while(1){ for(uint16_t phi=0; phi<4096; phi++){ phase(DDS1, phi); // schreibe phi ins Phasenregister des DDS1 _delay_ms(1); } } [c] Das funktioniert wunderbar und die eine Welle auf dem Oszilloskop ändert langsam gegenüber der anderen die Phase. Das geht so 1~1.5 Sekunden lang gut, danach hört der uc auf, die Daten über SPI auszugeben. Kein Watchdog. Keine Ahnung. ?
Ich habe inzwischen weiter rumexperimentiert. Zur besseren Kontrolle habe ich noch ein Pin togglen lassen:
1 | ...
|
2 | while(1){ |
3 | for(uint16_t phi=0; phi<4096; phi++){ |
4 | phase(DDS1, phi); // schreibe phi ins Phasenregister des DDS1 |
5 | _delay_ms(1); |
6 | PORTD ^= (1<<PD2); |
7 | }
|
8 | }
|
Die Beobachtungen: 1. Die Zeit bis der uC stehen bleibt hängt (u.a.?) von der Betriebsspannung ab. @3V ~ 0.9-1.5s; @4V ~3-4s; @5V ~8-11s (is immer unterschiedlich). 2. Der Pin wird ungefähr einmal die Sekunde für ~400us auf Low gezogen. Und jetz Achtung: das sogar nach dem Stehenbleiben des uC! Was gibt es im uC mit Sekundentakt? PS: Die Fragen sind nicht nur an Fabian gerichtet :)
Uups. Die Sache mit dem Sekundentakt kommt von dem noch angestecktem AVRISP-MKII. peinlich Sonst bleibt alles in Kraft. Ausserdem noch eine Anmerkung: wenn ich die Zeile mit phase... auskommentiere, also kein SPI benutze, dann läuft der uC und läuft, und läuft.
Wäre es dann vielleicht theoretisch möglich, dass der Fehler in der 'phase'-funktion liegt?
Hi 1. Du solltest deinen Programmtext erstmal halbwegs lesbar formatieren. 2. Wer ist eigentlich auf die kuriose Idee gekommen, leicht achvollziehbare Registernamen wie 'r16'... mit Bezeichnungen wie 'tmpxxx' oder tempxxx zu versehen. Zum einen erhöht sich der Schreibaufwand, und die Lesbarkeit des Programmes wird für andere nur erschwert. MfG Spess
Habe auch ATMEL angefragt. Die wissen es auch nicht und raten mir, einen Emulator zuzulegen. Hier der auf das nötigste reduzierte Code (nur eine Datei), der die gleichen Symptome zeigt:
1 | #define SPI_PORT PORTB
|
2 | #define SPI_DDR DDRB
|
3 | #define SCK PORT5
|
4 | #define MISO PORT4
|
5 | #define MOSI PORT3
|
6 | #include <avr/io.h> |
7 | |
8 | void main(void){ |
9 | DDRD = 0xff; |
10 | PORTD = 0xff; |
11 | |
12 | SPI_DDR |= (1 << MOSI) | (1 << SCK); // Setup port pin directions |
13 | SPI_DDR &= ~(1 << MISO); |
14 | SPI_PORT |= (1 << MISO) | (1<<SCK) | (1<<MOSI); |
15 | SPCR = (1 << SPE) | (1 << MSTR) | (1<<CPOL); // Enable SPI as Master |
16 | while (1) { |
17 | SPDR = 100; // 100 just for example |
18 | while(!(SPSR & (1 << SPIF))); // Wait for previous transmission to complete |
19 | }
|
20 | }
|
Kann das einer Bitte an einem anderen ATMEGA ausprobieren? Habe jetzt keine ausser dem 88 hier. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.