Forum: Mikrocontroller und Digitale Elektronik wieder mal USART+Interrup


von Andre F. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe mir vor einiger Zeit das Pollin AVR Board in der Version 2.0 
gekauft und habe dnan angefangen ein paar kleinigkeiten dait zu machen. 
Mein aktuelles Ziel ist es das ich ein Datenpacket (4Bytes) an den µC 
sende und dieser eine entsprechende aktion ausführt.

Das ganze hat mit pollen funktioniert, allerdings ist das Ziel das es 
über interrupts geht. Dazu habe ich mir den angehängten Code ausgedacht.

Dabei habe ich mir das wie folgt gedacht:
1) Es gibt einen lese und einen schreib index.
2) Ich warte im hauptprogramm darauf das der schreib index ungleich dem 
lese index ist. Ist dies der fall lese ich ein Byte aus einem globalen 
array und erhöhe den lesezeiger.
3) Im EMpfangsinterrupt des µC  speichere ich die empfangenen daten im 
array ab und erhöhe den schreib zeiger.

So kann ich wie in einem ringpuffer das array immer wieder durchgehen.

Zu Debug-Zwecken habe ich mir mal die positionen ausgeben lesen, doch 
die Zeiger verändern sich nicht. (Durch einen 
uart_putc('0'+schreib_index))

Allerdings wird die LED die ich im Interrupt Blinken lasse entsprechend 
an und aus geschaltet.

Kann mir villeicht jemand helfen. Irgend etwas muss ich ja grundlegend 
noch falsch machen? Ich habe mcih dazu auch slebst informaiert und 
google u.ä. angestrengt, aber leider nichts gefunden was mir die Frage 
beantworten könnte. Einen fertigen code möchte ich ungerne nutzen, da 
ich verstehen möchte warum meine heranngehensweise nicht geht.

Gruß,
Andre´

P.s.:
Ich benutze das Pollin AVR Bard 2.0 (ATMega32 16Mhz)
Einen Bootloader 
(http://hubbard.engr.scu.edu/embedded/avr/bootloader/index.html)
Einen USB RS232 Wandler (HugePine?)
Das AVR Studio 4.13 Build 528
WinAVR-20080512

von Peter D. (peda)


Lesenswert?

Siehe:

Beitrag "AVR-GCC: UART mit FIFO"

Fallgrube 2.

Da Deine Indexe 16-bittig sind, trifft auch Fallgrube 3 zu.


Peter

von Andre F. (Gast)


Lesenswert?

@Peter Dannegger

Hallo Peter,
viele Dank für deine Antwort. Wenn ich heute Zeit finde werde ich 
versuchen deine Hinweise umzusetzen.

Zwei frage habe ich aber noch, warum ist esschlimm wenn ich mit 16 Bit 
Zahlen arbeite?
Ich weis zwar das es theoretisch möglich wäre das eine Operation mit der 
Zahl nicht Atomar ist und somit theoretisch unterbrochen werden kann, 
aber warum stellt das ein problem dar? Werden Register nicht vorher 
gesichert bevor sie in anderen Routinen wieder verwendet werden?

Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe 
(puffer_schreiben++) weg optimiert?

Gruß Andre´

von Peter D. (peda)


Lesenswert?

Andre F. wrote:

> Zwei frage habe ich aber noch, warum ist esschlimm wenn ich mit 16 Bit
> Zahlen arbeite?

Warum soll es schlimm sein?
Es ist nur Verschwendung von Flash und SRAM.


> Ich weis zwar das es theoretisch möglich wäre das eine Operation mit der
> Zahl nicht Atomar ist und somit theoretisch unterbrochen werden kann,
> aber warum stellt das ein problem dar?

Nicht nur theoretisch, das passiert auch praktisch.
Und wenn ein Fehler nur einmal am Tag auftritt und die Software 
ausrastet, dann viel Spaß beim Debuggen.
Fehlervermeidung ist 1000-mal effektiver als Fehler debuggen.


> Werden Register nicht vorher
> gesichert bevor sie in anderen Routinen wieder verwendet werden?

Welche Register, es geht um Variablen.
Wenn z.B der Interrupt einen 2-Byte Wert von 0x01FF auf 0x0200 ändert 
und das genau zwischen den 2 Bytezugriffen des Main passiert, dann 
kriegt das Main einen völlig anderen Wert, wie 0x02FF oder 0x0100, je 
nach Lesereihenfolge.



> Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe
> (puffer_schreiben++) weg optimiert?

Woher weißt Du das, auf welche Codezeile bezieht sich das?


Peter

von Stefan E. (sternst)


Lesenswert?

@ Peter Dannegger:

>> Meine Zweite Frage wäre, aus welchem Grund werden die Zugriffe
>> (puffer_schreiben++) weg optimiert?
>
> Woher weißt Du das, auf welche Codezeile bezieht sich das?

Ich vermute, er bezieht sich auf diesen Satz:
> Fallgrube 2:
> Da hier Interrupts mit main-Funktionen kommunizieren, müßten die Indexe
> als volatile definiert werden, damit sie der AVR-GCC nicht wegoptimiert.
und hat als Beispiel eine Codezeile, wo auf den Index zugegriffen wird, 
rausgesucht.


@ Andre F.:

Es geht dabei nicht darum, dass Code wegoptimiert wird, sondern dass 
Speicherzugriffe wegoptimiert werden. Eine kritische Zeile in deinem 
Code ist z.B. diese:
1
while(puffer_schreiben==puffer_lesen) {}
puffer_schreiben wird nur einmal am Anfang der Schleife aus dem Speicher 
gelesen, und danach werden nur noch Registerinhalte verglichen. Mit 
"volatile" sagst du dem Compiler, dass sich der Inhalt von 
puffer_schreiben auch zwischendurch ändern kann, und er erzeugt dann 
Code, der den Wert in jedem Schleifendurchlauf neu aus dem Speicher 
liest.

von Andre F (Gast)


Lesenswert?

Hallo,
ersteinmal vielen Dank für eure Hilfe. Ihr habt mit beide sehr weiter 
gegholfen und ich glaube das ich das Problem jetzt auch verstanden habe.

Sollte ich diesbezüglich noch Probleme haben werde ich heute abend 
nochmal schreiben, aber ich denke das ist das jetzt auch alleien hin 
bekomme.

Danke nochmal

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.