Forum: Mikrocontroller und Digitale Elektronik ATMega8 hängt sich auf bei ADWI + BRNE


von Stefan (Gast)


Angehängte Dateien:

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

von spess53 (Gast)


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

von Zapp (Gast)


Lesenswert?

delay_hig &  delay_low sind beide zwischen R16 und R31. Ja ?

von Zapp (Gast)


Lesenswert?

Doch, gemaess 056E-AVR-11/05 werden die Flags gesetzt. Falls nicht, 
wuerde ein TST helfen.

von spess53 (Gast)


Lesenswert?

Hi

>delay_hig &  delay_low sind beide zwischen R16 und R31. Ja ?

Warum? Eher zwischen r24 und r31. Sonst gibt es eh eine Fehlermeldung.

Erst Denken, dann Posten.

MfG Spess

von Zapp (Gast)


Lesenswert?

Rd ist ueblicherweise R16..R31, soweit ich mich erinnere.
In der Tat, fuer diesen Befehl sind es R24..R31.

von spess53 (Gast)


Lesenswert?

Hi

>Rd ist ueblicherweise R16..R31, soweit ich mich erinnere.
>In der Tat, fuer diesen Befehl sind es R24..R31.

Es gibt halt einen kleinen Unterschied zwischen Wissen und Glauben.

MfG Spess

von Stefan (Gast)


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

von Hc Z. (mizch)


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.

von Stefan (Gast)


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?

von Hc Z. (mizch)


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.

von Stefan (Gast)


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.

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Etl. sind 6 LEDs ein bisschen viel Strom, die der Kleine liefern muss?

von Stefan (Gast)


Lesenswert?

Mmh, laut Datenblatt kann der Mega8 insgesamt 300mA, aber max 40mA pro 
Pin.
Mit den insgesamt 10 LEDs à 20mA käme ich dann gerade noch hin.

von Hc Z. (mizch)


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).

von Hc Z. (mizch)


Lesenswert?

Nachtrag:  der erste Punkt aus obiger Aufzählung trifft nicht zu.  Da 
habe ich mich durch die etwas verzwickte Logik foppen lassen.  Der 
Befehl „andi“ existiert übrigens, wodurch die einfacher würde.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Tasten entprellt man nicht mit Delays sondern im Timer-Interrupt. Sucht 
mal in der Codesammlung nach "bulletproof" und im Wiki nach 
Entprellung und Multitasking.

MfG

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Guck mal deine Massen an, wo die miteinander verbunden sind. Habe hier 
gerade ein ähnliches Problem.

von Stefan (Gast)


Lesenswert?

Ui, da hab ich ja einiges zu tun! Danke für die Antworten, melde mich 
bald wieder.

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.