Forum: Mikrocontroller und Digitale Elektronik Atmega8 bleibt nicht in der Schleife?


von Matthias (Gast)


Lesenswert?

Hallo Leute,

Kurze dringende Frage, sonst drehe ich durch ;-)

Mein Programm für meinen Gefrierschrankeiswürfelauswurf funktioniert bis 
jetzt perfekt, bis auf diese eine Schleife:

Eis:

      ldi R19,1      // Bit 0 von R19 bedeutet Licht ein!
//      rcall Wait
//      rcall Wait

      sbic PIND,4
      ret
    Eisloop:


; =============================
;   Warteschleifen-Generator
;     2000000 Zyklen:
; -----------------------------
; warte 1999998 Zyklen:
          ldi  R23, $12
WGLOOP0:  ldi  R24, $BC
WGLOOP1:  ldi  R25, $C4
WGLOOP2:  dec  R25
          brne WGLOOP2
          dec  R24
          brne WGLOOP1
          dec  R23
          brne WGLOOP0
; -----------------------------
; warte 2 Zyklen:
          nop
          nop
; =============================



//      sbis PIND,4
      sbi PORTC,1
      sbis PIND,4
      brne Eisloop



      ldi R19,0
ret



Ich verstehe einfach nicht, warum alles funktioniert, wenn die 
Warteschleife nicht drin ist, dann bleibt er schön in der 
Eisloop-Schleife.

sobalt ich die Warteschleife einbinde funktioniert es nicht mehr... er 
läuft einfach wieder aus dem unterprogramm raus, obwohl mein Taster an 
PIND gedrückt ist...

Kann mir das jemand erklären ?

DANKE schonmal im Vorraus!
Gruß Matthias

von Stefan E. (sternst)


Lesenswert?

Matthias schrieb:
> Ich verstehe einfach nicht, warum alles funktioniert, wenn die
> Warteschleife nicht drin ist, dann bleibt er schön in der
> Eisloop-Schleife.
>
> sobalt ich die Warteschleife einbinde funktioniert es nicht mehr... er
> läuft einfach wieder aus dem unterprogramm raus, obwohl mein Taster an
> PIND gedrückt ist...
>
> Kann mir das jemand erklären ?

Weil du ein brne benutzt hast, wo wohl eigentlich ein rjmp stehen 
sollte.

von Matthias (Gast)


Lesenswert?

Danke für die schnelle Antwort, aber irgendwie gehts immer nochnicht..
Ich habe alle relevanten brne ausgetauscht...
Ich rufe jetz, so wie es eigentlich von anfang an geplant war ein 
Wait-Programm auf, aber sobald ich dieses aufrufe funktioniert nichts 
mehr...

Ich kopier jetzt einfach mal den ganzen Quelltext hier rein, hoffe ihr 
könnt mir helfen!

DANKE!




// Gaggenau Gefrierschranksteuerung V1.0


.include "m8def.inc"           //Definitionsdatei für den Prozessortyp 
einbinden

         LDI   r16,LOW(RAMEND)  //Initialisierung Stackpointer
       OUT   SPL,r16       //Ist notwendig um Unterprogramme nutzen zu 
können!!
         LDI   r16,HIGH(RAMEND)
         OUT   SPH,r16


         ldi r16, 0
         out DDRD, r16        // Port D als Eingang initialisieren
      ldi r16, 0xFF
     out DDRC, r16      // Port B als Ausgang initialisieren
     ldi r16, 3
     out PORTD, r16      // interne Pullup-Wiederstände aktivieren

mainloop:
cbi PORTC, 0
cbi PORTC, 1
cbi PORTC, 2


sbis PIND,5    // skip if Bit cleared
rcall Wasser
sbis PIND,4
rcall Eis
sbis PIND,3
rcall Crushed
//sbic PIND, 2
//rcall Rotate
sbis PIND, 1
rjmp Lock    // kann nur mit wait funktionieren... genauso wie licht und 
Rotate
//sbic PIND, 0
//rcall Light

rjmp mainloop


lockloop:

  sbis PIND, 1
//  rcall wait1
  sbis PIND, 1
  brne Unlock
  brne lockloop


//---------------------Lock-------------------/
Lock:

//  rcall wait1
  sbis PIND, 1
  sbi PORTC, 4
  sbis PIND, 1
  brne lockloop
  brne mainloop

//---------------------Unlock-------------------/
Unlock:
  cbi PORTC, 4
  brne mainloop





// Unterprogramm Wasser 
--------------------------------------------------------------

Wasser:


      ldi R19,1      // Bit 0 von R19 bedeutet Licht ein!
      sbis PIND,5
//      rcall Wait
      sbis PIND,5
      rcall Wait          //<----------- Sobalad irgendein Wait drin ist 
geht nichts mehr...

      sbic PIND,5
      ret
    wasserloop:

//      rcall Wait
      sbis PIND,5
      sbi PORTC,0
      sbis PIND,5
      rjmp wasserloop


      ldi R19,0
ret

// Unterprogramm Eis 
--------------------------------------------------------------

Eis:

      ldi R19,1      // Bit 0 von R19 bedeutet Licht ein!
//      rcall Wait
//      rcall Wait

      sbic PIND,4
      ret
    Eisloop:


//      rcall Wait
      sbis PIND,4
      sbi PORTC,1
      sbis PIND,4
      rjmp Eisloop



      ldi R19,0
ret

// Unterprogramm Crushed 
--------------------------------------------------------------

Crushed:

      ldi R19,1      // Bit 0 von R19 bedeutet Licht ein!
//      rcall wait
//      rcall wait

      sbic PIND,3
      ret
    crushedloop:

//      rcall wait
      sbis PIND,3
      sbi PORTC,2
      sbis PIND,3
      brne crushedloop


      ldi R19,0      ldi R19, 0
ret


// Unterprogramm Rotate 
--------------------------------------------------------------

Rotate:



//      rcall wait1
//      rcall wait1

      sbic PIND,2
      ret

      sbi PORTC,3

ret


// Unterprogramm Wait 
--------------------------------------------------------------------

Wait:

; =============================
;   Warteschleifen-Generator
;     2000000 Zyklen:
; -----------------------------
; warte 1999998 Zyklen:
          ldi  R23, $12
WGLOOP0:  ldi  R24, $BC
WGLOOP1:  ldi  R25, $C4
WGLOOP2:  dec  R25
          rjmp WGLOOP2
          dec  R24
          rjmp WGLOOP1
          dec  R23
          rjmp WGLOOP0
; -----------------------------
; warte 2 Zyklen:
          nop
          nop
; =============================


ret

von Werner (Gast)


Lesenswert?

Matthias schrieb:
> Ich habe alle relevanten brne ausgetauscht...

Der Unterschied zwischen brne und rjmp ist dir klar?

von Purzel H. (hacky)


Lesenswert?

Debuggen ... beginnt mit dem Simulator des AVR Studios. Da kann man 
jeden Befehl einzeln ausfuehren. Nennt sich Single-Step

von gaast (Gast)


Lesenswert?

Matthias schrieb:
> Ich habe alle relevanten brne ausgetauscht...

Nein, hast du nicht. Du hast durch blindes Austauschen ohne 
nachzudenken, was du willst und was der Befehl macht, eine erstklassige 
Endlosschleife gebaut. Du gehst also zurück an den Anfang und denkst 
ganz genau nach, welches brne du durch ein rjmp ersetzen willst, und 
warum.

von Matthias (Gast)


Lesenswert?

Hallo,

Also Danke nochmal!!

Daran lags ;-)

Ich dachte irgendwie, dass brne das gleiche bewirkt wie jmp, da es das 
beim Atmega8 ja nicht gibt....

naja, jetz kenn ich mich aus ;-)

Dankeschön!

gruß Matthias

von Herr M. (herrmueller)


Lesenswert?

Matthias schrieb:
> Ich dachte irgendwie, dass brne das gleiche bewirkt wie jmp, da es das
>
> beim Atmega8 ja nicht gibt....

Der Sprungbefehl bei den 'Kleinen' heisst RJMP, und den gibt es bei 
allen.

herrmueller

von Matthias (Gast)


Lesenswert?

schon klar, aber ich habe bisher nur mit nem Siemens Controller in der 
FH gearbeitet, und der konnte mit jmp umgehen, soweit ich mich entsinnen 
kann...

von Oliver (Gast)


Lesenswert?

Matthias schrieb:
> aber ich habe bisher nur mit nem Siemens Controller in der
> FH gearbeitet, und der konnte mit jmp umgehen, soweit ich mich entsinnen
> kann...

ja nee, is klar ;)

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Matthias schrieb:
> schon klar, aber ich habe bisher nur mit nem Siemens Controller in der
> FH gearbeitet, und der konnte mit jmp umgehen, soweit ich mich entsinnen
> kann...

2 Dinge

a) jeder Prozessor, jede Prozessorfamilie ist auf Assemblerebene anders,
   kann andere Befehle, hat andere Register, andere Möglichkeiten.
   Hier haben wir Atmel, dort Siemens. Das sind 2 verschiedene Firmen.
   Noch unterschiedlicher geht gar nicht.
   (OK, ein µC aus einem Alienraumschiff wäre noch schlimmer)

b) Wenn du Assembler programmierst, haben für dich 2 Dokumente
   Bibel-Charakter:
   Das eine ist das Datenblatt
   Das andere ist die Instruction-Set Beschreibung.

Ersteres gibts in PDF Form. Letzters gibt es auch in PDF Form, aber da 
man sie so häufig braucht, ist sie auch im AVR-Studio in der Hilfe 
integriert. Dort sind ALLE Befehle enthalten, die dein µC kennt. Wenn du 
dich nicht durch die Hilfe bis zur Instruction Set Beschreibung 
durchklicken willst, stell den Cursor auf irgendeinen anderen Befehl und 
drück F1. Dann kommt die Hilfe für diesen Befehl hoch und in der linken 
Index-Spalte der Hilfe sind alle Assembler-Befehle auswählbar.

von gaast (Gast)


Lesenswert?

Matthias schrieb:
> Ich dachte irgendwie, dass brne das gleiche bewirkt wie jmp

Wie kommst du zu dieser Annahme? Meinst du nicht, dass es sinnvoll wäre, 
sich mal den Befehlssatz des Prozessors zu Gemüte zu führen, den man 
programmieren will? Einfach irgendwas zu schreiben klappt nämlich recht 
selten.

Matthias schrieb:
> schon klar, aber ich habe bisher nur mit nem Siemens Controller in der
> FH gearbeitet, und der konnte mit jmp umgehen, soweit ich mich entsinnen
> kann...

Dir ist klar, dass jede Prozessorarchitektur ihren eigenen Befehlssatz 
hat, auch wenn sie sich durchaus ähneln?

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.