Eine kurze Frage an die AVR Assembler Experten

Gast #6732594
eine Frage an die AVR Assembler Experten

Ich hab mir von Pollin ein paar der Microcontroller MEGA 2560PRO Boards 
bestellt und bin grad am Testen. Ich programmiere in Assembler mit dem 
Microship Studio ehemals AVRStudio.
Ich wollte erst mal eine Blink LED über den Timer5 Interrupt blinken 
lassen. Das Ein/Ausschalten wird über den OCRA Compare Interrupt 
gesteuert.
Im Prinzip funktioniert alles aber...
Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne 
das ich den globalen Interrupt freigegeben habe (SEI) den OCRA Int hab 
ich freigegeben.
Irgend jemand eine Idee? Oder liegts daran daß das Board einen 
Bootloader hat und dort werden die INTs bereits enabled?

schon mal Danke für die Hilfe
#6732599
Ich würde als erstes mit einem fertigen Beispiel beginnen. Das Flashen 
ist die erste Hürde.

Und anschließen versuchen das Beispiel selbst zu bilden. Und dann erst 
mit neuem Code beginn, wobei man durchaus das Beispiel abwandeln kann.
Gast #6732620
Andreas G. schrieb:
> Hab ich nicht vergessen, nur nicht für nötig gehalten. Die Schaltung
> funktioniert und das Programm auch.

Na dann brauchst/willst du offenbar keine Hilfe.

Der Fehler ist übrigens in der Zeile mit dem Dingsbums und deine LED hat 
die falsche Farbe.
Gast #6732637
Stefan ⛄ F. schrieb:
> Na dann brauchst du keine Hilfe.

Full Ack.

Aber meine Glaskugel sagt dass der Interrupt zufällig durch
direktes Schreiben auf das entsprechende Register (SREG)
enabled wird. Richtig wäre es eine Read-Modify-Write Operation
zu verwenden die nur das betreffende Bit ändert das man ändern
will.
#6732650
Nein, die LED hängt an einem normalen Port. Hier mal der Ausschnitt 
welcher die LED anschaltet. Dann gibts noch einen Overflow Int, der 
schaltet sie dann wieder aus. Im Main gibts keinen SEI Befehl.
1
LED_Int_Service_T5_compare_match:
2
    PUSH  R16                ; int prefix
3
    IN    R16,    SREG
4
    PUSH  R16
5
    PUSH  R17
6
    LDS    R16,    LED_Status      ; OR PortK & LED_Status
7
    LDS    R17,    PortK
8
    OR    R17,    R16
9
    STS    PortK,    R17
10
    POP    R17                ; int suffix
11
    POP    R16
12
    OUT    SREG,    R16
13
    POP    R16
14
    RETI

Ich denke es ist so wie usbman oben schon geschrieben hat. Bootloader 
oder Init-Code. Wobei... Wenn mit dem Init-Code meiner gemeint sein 
sollte dann kanns auch nicht sein...
Naja, dachte nur jemand hatte den Effekt schon mal
(Firma: Da) #6732683
Stefan ⛄ F. schrieb:
> Zeige den ganzen Quelltext, nicht nur den Teil, der den Fehler nicht
> enthält.

An meinem Auto geht der rechte Blinker beim Benutzen doppelt so schnell, 
woran kann das liegen?

A:
Poste alle Karroserieteile und den Schaltplan des Kabelbaums...


Bei Assembler für AVR kann man, z.B. im Bootloder, einen Interrupt 
setzen der dann aktiv wird, wenn irgendeine Bedingung erfüllt wird. Dies 
ist wenn man schlampig programmiert und der Bootloader das Hauptprogramm 
anspringt.

Poste den Code des Bootloaders...
Gast #6732694
>Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne
>das ich den globalen Interrupt freigegeben habe (SEI)

Dann schreib doch ein Mini-Prüfprogramm, das nur das SREG einliest, das 
I-Bit ausmaskiert und eine LED einschaltet, wenn es gesetzt ist. Dann 
weißt Du, ob es im Bootloader passiert ist oder Du doch woanders suchen 
musst.
Gast #6732770
Andreas G. schrieb:

> Hab ich nicht vergessen, nur nicht für nötig gehalten. Die Schaltung
> funktioniert und das Programm auch. Nur sind nach dem Reset die
> Interrupts freigegeben. Das stört mich im Prinzip nicht ich hätte nur
> gern gewusst woran das liegt

Kann eigentlich nur an eine lausigen Bootloader liegen, der nicht 
ordentlich aufräumt, bevor er die Kontrolle an die Anwendung übergibt.

Allerdings: Wie sollte ein Bootloader eine normale Flashprozedur 
überleben? Da kann doch nur ein Vollidiot das Chip-Erase vor dem Flashen 
ausgeschaltet haben. Oder der Vollidiot hat in voller Absicht den 
Bootloader zum Flashen seiner Anwendung benutzt.

Wer käme denn für die Rolle dieses hypothetischen Vollidioten in Frage?
#6732771
Das war nur ein Test... .DSEG hat im Moment nur ein Byte. Port K ist ein 
normaler IO Port der leider ausserhalb des Bereiches liegt den man mit 
In/Out ansprechen kann. Ist wohl in den Ram Bereich gemappt. Daher LDS, 
STS.
Hab mir mal das I-Flag ausgeben lassen (danke für den Tipp) und ja das 
ist beim Startup gesetzt. Komisch das. Naja, wenn man es weis, ist es ja 
ok.
Gast #6732772
Andreas G. schrieb:

> Hab mir mal das I-Flag ausgeben lassen (danke für den Tipp) und ja das
> ist beim Startup gesetzt. Komisch das. Naja, wenn man es weis, ist es ja
> ok.

Nein, ist es nicht. Das hat nach Reset gelöscht zu sein. Ende der 
Ansage.
#6732775
@c-hater,
Naja, der Bootloader überlebt den Flash über USB. Muss er ja auch. Und 
ja, der Vollidiot hat den Bootloader zum flashen benutzt. Dann gehts 
auch entspannt mit USB. Die normalen 2560 Boards haben einen mega8USB 
für die Kommunikation drauf. Dieses nicht nur einen dummen USB/Seriell 
Wandler. Und ich hab keinen Bock jedesmal über SPI zu flashen. Keine 
Ahnung ob der Ponyprog den 2560 überhaupt kennt
#6732781
Andreas G. schrieb:
> Port K ist ein
> normaler IO Port der leider ausserhalb des Bereiches liegt den man mit
> In/Out ansprechen kann. Ist wohl in den Ram Bereich gemappt. Daher LDS,
> STS.

Hi,
ja, ja "Memory mapped". Der Begriff ist mir im Zusammenhang mit einigen
"Megas" noch in Erinnerung.
Da freute man sich über mehr Features damals, und dann lassen sich die 
Programme nicht 1:1 auf die "neueren" Targets portieren.

ciao
gustav
#6732795
Andreas G. schrieb:
> portieren ist einfach.

Hi,
klar, wenn man das vorher weiß, wie der "neue" AVR angesprochen werden 
will.
Komme deswegen drauf, weil es 'mal bei Einführung von "besseren" AVRµCs
heftige Diskussionen gab damals.
Und ob die Maxime heute noch Gültigkeit hat ?:
Lieber im cseg arbeiten, weil dseg bei den "alten" schon abweichende 
Zugriffszeiten hatte. Ganz zu schweigen dann vom noch "langsamerem" 
eseg.

ciao
gustav
Gast #6732833
Dazu muss man kein AVR-Assembler Guru sein, die Grundlagen der
Elektronik reichen, der Effekt ist sozusagen "der Grundzustand".

Nach dem Anlegen der Versorgungsspannung haben alle SRAM-zellen
und Register beliebige Werte und nur im Controller enthaltene 
zusätzliche Hardware setzt einige Zellen auf voreingestellte Werte, die 
im Datenblatt
aufgeführt werden. Ob das auch bei Reset passiert oder nur bei
Power-On ist harwareabhängig. Wenn im Datenblatt
dazu nichts steht, geht der vorsichtige Mensch davon aus, daß nur der
ProgramCounter auf seinen definierten Startwert gesetzt wird
und alles Andere undefiniert ist.

Ansonsten steht in den beschreibbaren Zellen, was eventuell vorher
gestartete Programme dort hinterlassen haben und nur Du kannst wissen,
was da vor dem Reset alles gelaufen ist.

Natürlich kann man immer von Anderen erwarten, daß sie die Arbeit für 
einen
selbst erledigen, aber warum sollten sie das tun? Deshalb die alte 
Regel:
If You want to have it done right, You have to do it Yourself.
Einfach "clear global interrupt" und "set stackpointer" als erste 
Befehle eintragen. Hilft zuverlässig gegen Überraschungen.

Mit freundlichen Grüßen an alle, die Automatiken für "normal" halten
und den Grundzustand gar nicht mehr kennen

Klaus
Moderator #6732949
Das I-Flag wird beim Reset immer gelöscht. Wäre dies nicht der Fall,
könnte ein Programm schon direkt nach dem Start unterbrochen werden,
noch bevor ein evtl. vorhandener CLI-Befehl ausgeführt wird. Deswegen
ist ein CLI am Programmstart nicht nur überflüssig, sondern auch
unsinnig.

kseege schrieb:
> Natürlich kann man immer von Anderen erwarten, daß sie die Arbeit für
> einen selbst erledigen, aber warum sollten sie das tun? Deshalb die
> alte Regel: If You want to have it done right, You have to do it
> Yourself.

Gerade beim ATmega2560 mit seinen ca. 180 I/O-Registern wäre es ziemlich
mühsam, wenn man diese alle beim Programmstart explizit initialisieren
müsste. Da vertraue ich lieber dem Datenblatt:

"During reset, all I/O Registers are set to their initial values"
Gast #6732967
Yalu X. schrieb:
> Deswegen
> ist ein CLI am Programmstart nicht nur überflüssig, sondern auch
> unsinnig.

Die Annahme ist hier ja, dass der Bootloader das I Bit stehen lässt.
Von da her, ist es evtl. schon sinnvoll, die Interrupts abzuschalten.
#6732968
Content B. schrieb:
> Stefan ⛄ F. schrieb:
>> Zeige den ganzen Quelltext, nicht nur den Teil, der den Fehler nicht
>> enthält.
>
> An meinem Auto geht der rechte Blinker beim Benutzen doppelt so schnell,
> woran kann das liegen?
>
> A:
> Poste alle Karroserieteile und den Schaltplan des Kabelbaums...

Bessere Analogie:

Bei meinem Auto geht der rechte Blinker nicht, woran liegt das? Anbei 
ein Foto vom Rücksitz.
Gast #6733288
Fischpudding schrieb:
> Ich hab mir von Pollin ein paar der Microcontroller MEGA 2560PRO Boards
> bestellt und bin grad am Testen.

Aha, spannend..

Fischpudding schrieb:
> Ich programmiere in Assembler mit dem
> Microship Studio ehemals AVRStudio.

löblich.

Fischpudding schrieb:
> Nun ist es so, daß der Interrupt aufgerufen und abgearbeitet wird ohne
> das ich den globalen Interrupt freigegeben habe (SEI) den OCRA Int hab
> ich freigegeben.
> Irgend jemand eine Idee?

Automagie?
Du sagtest, du bist am Testen..

Hast du keinen Debugger?
Gast #6733378
Ich bin erstaunt, dass einige sich an dem Bootloader fest gebissen 
haben. Man kann wohl davon ausgehen, dass es sich um den Arduino 
Bootloader handelt, mit dem die Mega2560 Board ausgeliefert werden.

Nach meinem Kenntnisstand übergibt er die Kontrolle an das Hauptprogramm 
mit gesperrten Interrupts, wie sich das gehört. Tatsächlich benutzt er 
selbst sogar keine Interrupts. Wer daran zweifelt möge bitte in den 
Quelltext schauen 
https://github.com/Optiboot/optiboot/tree/master/optiboot/bootloaders/optiboot

Deswegen bleibe ich dabei, dass unser Gast Fischpudding seinen gesamten 
Quelltext zeigen soll.
#6733399
So sieht das bei mir normalerweise aus, aber ich verwende auch keinen 
Bootloader:
1
.def  SavSrg  = r4    ; save status during Interrupt
2
...
3
; init stack
4
  ldi  Tmp,Low(RAMEND)
5
  out  SPL,Tmp  ;
6
  ldi  Tmp,High(RAMEND)
7
  out  SPH,Tmp  ;
8
...
9
Irq:         ; (4)   start IRQ = 4 clock cycles min.
10
  in  SavSrg,SREG  ; (1)   save status register
11
...
12
  out  SREG,SavSrg  ; (1)   restore status register
13
  reti      ; (4)
Beitrag #6733412 wurde von einem Moderator gelöscht.
Beitrag #6733414 wurde von einem Moderator gelöscht.
#6733581
Für den 2560 könnte es trotzdem interessant sein, wenn man externes SRAM 
benutzt
https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
Seite 27 "External Memory Interface"
aber der Assembler muss dazu wissen, wo "RAMEND" liegt, oder kann man 
das nur an das interne SRAM-Ende legen?

Der 6502 legte beim Interrupt-Aufruf immer auch das Flagregister auf den 
Stack.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 5 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.