www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [Butterfly] LCD-Laufschrift bleibt stehen


Autor: 2lazy2login (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab den GCC-Port der Butterfly-Software verwendet und hab ein sehr
merkwürdiges Problem, das ich mir überhaupt nicht erklären kann.

Und zwar nutze ich die Minimal-Version mit der Laufschrift und
LCD_puts(...) funktioniert auch wunderbar und die Laufschrift läuft
auch wie sie soll, aber wenn ich jetzt in eine Schleife wie

while (...)
{
}

reinkomme, quasi auf irgendwas warte, dann bleibt die Laufschrift
stehen und die läuft dann erst weiter, wenn die Schleife verlassen
wurde.
Das wundert mich sehr, da ja die Laufschrift über den
LCD-Frame-Interrupt realisiert wird und aus meinen bisherigen Erfahrung
mit Interrupts werde ich daraus nicht ganz schlau. Es werden jedenfalls
keine Interrupts gesperrt, die den LCD-Frame-Int verhindern könnten.

Hat da jemand ähnliche Erfahrungen gemacht?

Mfg
Thomas

Autor: 2lazy2login (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und meine bisherigen Erfahrungen hatten Recht ...

Der GCC hat - aus einem mir unbekannten Grund - in eine Funktion die
von der Main-Loop aufgerufen wird und die die empfangenen
RS232-Kommandos dekodiert ein cli in den Assemblercode gebaut.

Weiß jemand, warum er das gemacht hat?

Bsp:
void Usart_Clear(void)
{
  while (UCSRA & (1<<RXC))
  {
    volatile char dummy = UDR;
  }
}

wird zu:
00000c48 <Usart_Clear>:
 c48:  cf 93         push  r28
 c4a:  df 93         push  r29
 c4c:  cd b7         in  r28, 0x3d  ; 61
 c4e:  de b7         in  r29, 0x3e  ; 62
 c50:  21 97         sbiw  r28, 0x01  ; 1
 c52:  0f b6         in  r0, 0x3f  ; 63
 c54:  f8 94         cli
 c56:  de bf         out  0x3e, r29  ; 62
 c58:  0f be         out  0x3f, r0  ; 63
 c5a:  cd bf         out  0x3d, r28  ; 61
 c5c:  80 91 c0 00   lds  r24, 0x00C0
 c60:  87 ff         sbrs  r24, 7
 c62:  07 c0         rjmp  .+14       ; 0xc72 <Usart_Clear+0x2a>
 c64:  80 91 c6 00   lds  r24, 0x00C6
 c68:  89 83         std  Y+1, r24  ; 0x01
 c6a:  80 91 c0 00   lds  r24, 0x00C0
 c6e:  88 23         and  r24, r24
 c70:  cc f3         brlt  .-14       ; 0xc64 <Usart_Clear+0x1c>
 c72:  21 96         adiw  r28, 0x01  ; 1
 c74:  0f b6         in  r0, 0x3f  ; 63
 c76:  f8 94         cli
 c78:  de bf         out  0x3e, r29  ; 62
 c7a:  0f be         out  0x3f, r0  ; 63
 c7c:  cd bf         out  0x3d, r28  ; 61
 c7e:  df 91         pop  r29
 c80:  cf 91         pop  r28
 c82:  08 95         ret

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sieht nur so aus:

c52:  0f b6         in  r0, 0x3f  ; 63
c54:  f8 94         cli
c56:  de bf         out  0x3e, r29  ; 62
c58:  0f be         out  0x3f, r0  ; 63
c5a:  cd bf         out  0x3d, r28  ;

in Zeile c52 wird das Status Register gesichert, indem sich auch
das Interrupt Status Register befindet.
In Zeile c54 wird der Interrupt kurzzeitig abgeschaltet um
in Zeile c58, durch Rückspeicherung des gesicherten Wertes
des Status Registers wieder aktiviert zu werden.

Der Grund ist einfach: Während der Stackpointer in den Zeilen
c56 und c5a manipuliert wird, sollte tunlichst kein Interrupt
auftreten. Die Speicherung der Return-Adresse geht sonst schief.

Autor: 2lazy2login (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja richtig!

0x3f ist das SREG und das wird einfach nur gesichert und dann wieder
hergestellt, also sind die Interrupts auch nicht gesperrt.

Aber was ist dann mit meiner Laufschrift (siehe erstes Posting)?
Btw: Da hängt über asynchronen Betriebsmodus ein 32khz Quartz extern
dran ... ich hab so das Gefühl, irgendetwas würde damit nicht stimmen,
weil das eigentlich eins der wenigen Features ist, die ich noch nicht
verwendet habe und somit auch noch keine Erfahrung damit habe.

Aber trotzdem weiß ich nicht, wo mein Problem dann ist :-(

verzweifel

Autor: 2lazy2login (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem gefunden, aber verstehen kann ich es nicht - ist wohl ein
weiterer Punkt für dieses unverschämte ATMEGA169 Errate ...

Wenn USART Receive-Interrupt aktiviert ist - und bei mir war die
Behandlungsroutine leer, was nur in einem
SIGNAL(SIG_USART_RECV) 
{
}
SIGNAL(SIG_USART_RECV) 
{
 b48:  1f 92         push  r1
 b4a:  0f 92         push  r0
 b4c:  0f b6         in  r0, 0x3f  ; 63
 b4e:  0f 92         push  r0
 b50:  11 24         eor  r1, r1
 b52:  0f 90         pop  r0
 b54:  0f be         out  0x3f, r0  ; 63
 b56:  0f 90         pop  r0
 b58:  1f 90         pop  r1
 b5a:  18 95         reti
resultiert und keine Auswirkungen haben dürfte, dann bleibt nach dem
Interrupt das LCD einfach stehen.

Aber wieso und warum und weshalb und überhaupt - keine Ahnung ...

Autor: 2lazy2login (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahja - und was ja sogar noch seltsamer ist ...
Mit dem aktivierten Interrupt dauerte eine
_delay_ms(10) schleife 10 mal so lange,
ohne aktivierten Interrupt dauert sie genau so lang wie sie dauern soll
... Ich glaub mein MEGA169 hat einen Schuss ...

Autor: Martin Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"und keine Auswirkungen haben dürfte"

der Code selbst nicht, aber das ist nicht alles. Wenn man den
RX-Interrupt aktiviert, sollte man auch die UART-Hardware entsprechend
"bedienen". Zumindest Data- und Status-Register in der ISR auslesen
mal versucht? Habe den Butterfly fuer einige Einzelanfertigungen
genutzt, auch mit UART-Interruptbetrieb - bisher keine Problemberichte
von den Nutzern.

(Man kann seinen richtigen Namen in diesem Forum sogar ganz "lazy"
ohne Login angeben)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber wieso und warum und weshalb und überhaupt - keine Ahnung ...

Lass mich raten:
Du schickst ein Zeichen per USART zum Butterfly.
Daraufhin tritt der Receive-Interrupt auf.
Dein entsprechender Handler kümmert sich aber nicht
um das empfangene Zeichen: Es wird nicht abgeholt.
Tja. Und jetzt nimmt das Verhängnis seinen Lauf:
Dadurch dass du UDR nie ausliest, wird auch die Interrupt
Anforderung nicht gelöscht. Sobald der Prozessor aus dem
Receive Interrupt raus ist, geht er auch schon wieder in
den Interrupt hinein, weil ja das Interrupt Flag nie gelöscht
wurde.

Dein Mega168 will dir quasi mit allem Nachdruck sagen, dass da ein
Zeichen in der UART auf Bearbeitung wartet. Das macht er so
nachdrücklich, dass er sich quasi nur noch mit dieser Interrupt
Routine beschäftigt.

Mach einfach mal:

SIGNAL(SIG_USART_RECV)
{
  char c = UDR;
}

und dein Mega168 sollte dich wieder mitspielen lassen.

Autor: Pototschnig (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na eben dann ohne lazy^^

>>>
Dadurch dass du UDR nie ausliest, wird auch die Interrupt
Anforderung nicht gelöscht.
<<<

Ihr habt echt recht - das ist das Problem!
Das UDR wird bei mir zwar nicht im ISR gelesen, sondern außerhalb.
Vorher hatte ich auch immer in der ISR das UDR ausgelesen und in einen
Ringpuffer gespeichert. Das Ganze ist aber - wie so oft - für
Fehlersuchzwecke ausgeklammert worden und schwupps hat man neue
Probleme. Das Fehlerbild passt auch zu meiner Situation, weil eben in
meiner Endlosschleife das UDR eben nicht abgefragt worden ist.

Und wenn der AVR jetzt wirklich ständig durch die ISR iteriert, dann
würde das genau die Probleme verursachen die ich beschrieben habe ...

Vielen Dank für die Erkenntnis!

Da werde ich in Zukunft aufpassen, dass mir so ein Blödsinn nicht noch
einmal passiert :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.