ATMega8 hängt sich auf bei ADWI + BRNE

Gast #1737041
Lesenswert?

Hi,

ich habe einen Mega8 an dem ich an PORTD 8 LEDs und an PC3 und PC4 
jeweils eine LED angeschlossen habe. An PB0 ist ein Taster 
angeschlossen.

Wird nun der Taster gedrückt sollen die LEDs an PD0 - PD3 einen Wert von 
0x00 - 0x0F anzeigen.

Den Taster möchte ich debouncen mit 25ms Verzögerung.

Hier der Code zum delay (kpl. Code als Anhang):

delay_25_ms:
  ldi    delay_low,  low(__25_MS__)
  ldi    delay_hig,  high(__25_MS__)
delay_25_ms_loop:
  adiw  delay_hig:delay_low, 1
  brne  delay_25_ms_loop
  ret

Jetzt das Problem:

Die Routine funktioniert nur, wenn ich zwischen adiw und brne noch 
irgendeine Routine über rcall aufrufe. Ein paar NOPs funktionieren 
allerdings nicht. Im Simulator von AVR Studio4 funktioniert die 
Geschichte einwandfrei.

Hat jemand eine Idee woran es liegt?

Danke schon ma und schönen Gruß
Stefan
Angehängte Dateien:
Gast #1737048
Lesenswert?

Hi

> adiw  delay_hig:delay_low, 1
>  brne  delay_25_ms_loop

'adiw' setzt kein Z-Flag. Und auch kein anderes.
1
 adiw  delay_hig:delay_low, 1
2
 push delay_hig
3
 or delay_hig,delay_low
4
 pop delay_hig
5
 brne  delay_25_ms_loop

sollte funktionieren.

MfG Spess
Gast #1737079
Lesenswert?

spess53 schrieb:
> 'adiw' setzt kein Z-Flag. Und auch kein anderes.
>  adiw  delay_hig:delay_low, 1
>  push delay_hig
>  or delay_hig,delay_low
>  pop delay_hig
>  brne  delay_25_ms_loop

Hi, hab im Simulator mal gekuckt. 'adiw' setzt bei Überlauf Z- und 
C-Flag. Daher auch mein Plan hochzählen bis Überlauf (jeweil 4 Takte) 
und dann 'ret'.

Bin ein noob, das hier verstehe ich leider nicht.

>  push delay_hig
>  or delay_hig,delay_low
>  pop delay_hig

Könnte mir das jemand erklären?

Danke schön
#1737085
Lesenswert?

Stefan schrieb:
>>  push delay_hig
>>  or delay_hig,delay_low
>>  pop delay_hig
>
> Könnte mir das jemand erklären?

Z-Flag gemäß delay_high:low setzen.  Das ist aber überflüssig, da adiw 
das Z-Flag setzt.  Du solltest lieber erläutern, was „Die Routine 
funktioniert nur, ...“ genau bedeutet und woran sich das bemisst.

EDIT:  Du könntest beispielsweise angeben, welche Verzögerung Du 
tatsächlich erreichst oder ob Du „funktioniert nicht“ an etwas anderem 
festmachst und wie _25_MS_ definiert ist.
Gast #1737094
Lesenswert?

aha, schon ma danke

Hc Zimmerer schrieb:
> Du solltest lieber erläutern, was „Die Routine
> funktioniert nur, ...“ genau bedeutet und woran sich das bemisst.

Also wenn ich den folgenden Code aufrufe passiert nix,
d.h. der Taster reagiert nicht und die LEDs werden nicht wie gewünscht 
angeschaltet:

delay_25_ms:
  ldi    delay_low,  low(_25_MS_)
  ldi    delay_hig,  high(_25_MS_)
delay_25_ms_loop:
  adiw  delay_hig:delay_low, 1
  brne  delay_25_ms_loop
  ret

Füge ich hingegen hinter adiw z.B. 'rcall display_prog' ein, kann ich 
die LEDs schalten.

delay_25_ms:
...
delay_25_ms_loop:
  adiw  delay_hig:delay_low, 1    ;2 Takte
  rcall display_prog  <=== diesen cmd einfügen
...

display_prog:
  push    temp1
  in    temp1,  PIND
  or    prog,  temp1
  out    PORTD,  prog
  pop    temp1
  ret

Kann es evtl. sein, dass der uC kaputt ist?
#1737098
Lesenswert?

Nach der Bezeichnung der Routine handelt es sich um eine 
25-ms-Verzögerungsschleife.  Ob es wirklich eine ist, hängt von der 
__25_MS__-Konstanten (nach der ich gefragt, was Du aber nicht 
beantwortet hast) ab und von der Taktfrequenz.  Ob Dir damit gedient 
ist, wenn sie 25 ms macht und ob Dein Programm dann läuft, weißt nur Du.

Warum irgendwelche Taster und LEDs irgendwas machen oder nicht machen, 
kann Dir anhand der paar Schnipsel, die Du gebracht hast, keiner sagen. 
Die tauchen dort nämlich nicht mal auf.  Aber bei mir ist für heute 
Abend eh Schluss.
Gast #1737101
Lesenswert?

Hc Zimmerer schrieb:
> Aber bei mir ist für heute
> Abend eh Schluss.

;-) sollte ich wohl auch mal machen
Danke schon ma für die Antworten

Hc Zimmerer schrieb:
> Ob es wirklich eine ist, hängt von der
> __25_MS__-Konstanten (nach der ich gefragt, was Du aber nicht
> beantwortet hast)

Sorry hatte vor deinem edit gepostet und daher die Frage nicht gesehen.

Und genau, ich brauch 25 ms Verzögerung.
Die will ich erreichen indem ich von 59286 bis Überlauf zähle.
Bei 1MHz bräuchte ich rund 25000 Takte.
Also 6250 * (2 Takte für adwi + 2 Takte für brne).

> kann Dir anhand der paar Schnipsel, die Du gebracht hast ...

Der angehängte Code im ersten Post ist das ganze Programm, länger isses 
nicht.
#1737226
Lesenswert?

Was mir aufgefallen ist:

- Der Kommentar zu get_key_PB0 besagt, dass der Taster aktiv low ist. 
Die Routine gibt jedoch TRUE (1) zurück, wenn eine 1 von PB0 eingelesen 
wird. Später prüfst Du auch auf Rückgabewert 1.

- Du wartest nirgends, bis der Taster losgelassen wird.  Bei gedrückten 
Taster werden also alle „Programme“ mit Höchstspeed durchlaufen.

- Du setzst die LEDs gemäß dem „Programm“, löschst sie aber nirgends. 
Somit dürften innerhalb kürzester Zeit alle 4 LEDs leuchten 
(LED-Anschluss aktiv high angenommen).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren