Forum: Mikrocontroller und Digitale Elektronik Problem mit Tonerzeugung mit dem ATmega8


von Lukas K. (lukasxd)


Lesenswert?

Hallo, ich habe eine Frage in Bezug auf ein Programm, welches ich für 
meinen ATmega8 geschrieben habe.
Das Programm soll eigentlich nur verschiedene Töne Erzeugen. Dafür habe 
ich eine Zeitverbrater-Routine geschrieben. Nach dieser wird der Ausgang 
für den Lautsprecher von An auf Aus bzw. umgekehrt geschaltet. Wenn ich 
das ganze nun an die Spannungsquelle anschließe kommt auch ein Ton aus 
dem Lautsprecher.
Es ist aber immer der gleiche wobei er sich eigentlich ändern sollte, 
wenn man den wert von r16 ändert. Jedoch ändert sich nur etwas wenn ich 
nach "warte1" noch ein oder mehrere nops einfüge.
1
        ldi     r26,0x04        
2
3
loop:
4
ton1:
5
  ldi     r16,0xFF
6
  ldi     r17,0xFF
7
warte1:
8
        dec     r16
9
  brne    warte1
10
  add     r20,r26   ;nachdem PORTD2 der ausgang für den lautsprecher
11
  out     PORTD,r20 ;ist wird immer 4 addiert damit 
12
  dec     r17       ;sich dieser Port bei jedem durchlauf der 
13
  brne    warte1    ;"Schleife" ändert
14
15
        rjmp    loop



Kann mir jemand bitte erklären was ich da falsch mache ?
Vielen Dank
Lukas

von egonotto (Gast)


Lesenswert?

Lukas K. schrieb:
> dec     r17       ;sich dieser Port bei jedem durchlauf der

Setze doch danach r16 wieder.

MfG
egonotto

von Lukas K. (lukasxd)


Lesenswert?

Vielen Dank.
Endlich funktioniert es.
Komisch dass ich nicht selber darauf gekommen bin.
Danke nochmal.
Lukas

von Karl H. (kbuchegg)


Lesenswert?

kleiner Tip

wenn du die Reihenfolge, in der du am Anfang r16 und r17 setzt umgedreht 
hättest, wäre es dir vielleicht aufgefallen
1
  ldi     r17,0xFF
2
  ldi     r16,0x80
3
warte1:
4
  dec     r16
5
  brne    warte1
6
  dec     r17       ;sich dieser Port bei jedem durchlauf der 
7
  ...
8
  brne    warte1    ;"Schleife" ändert
und zwar deshalb, weil beide brne zur selben Stelle gehen.
das kann aber so nicht recht stimmen, denn wenn du 0xFF mal bis 0x80 
zählen willst, dann musst du das auch jedes mal machen
1
  ldi     r17,0xFF
2
warte0:
3
  ldi     r16,0x80
4
warte1:
5
  dec     r16
6
  brne    warte1
7
  dec     r17       ;sich dieser Port bei jedem durchlauf der 
8
  ...
9
  brne    warte0    ;"Schleife" ändert

Alternativ kannst du natürlich auch anstelle von r16 r17 kleinere setzen 
und so anstatt 0xFF mal nur 0xAB mal von 0x80 bis 0 herunterzählen
1
  ldi     r17,0xAB
2
warte0:
3
  ldi     r16,0x80
4
warte1:
5
  dec     r16
6
  brne    warte1
7
  dec     r17       ;sich dieser Port bei jedem durchlauf der 
8
  ...
9
  brne    warte0    ;"Schleife" ändert

Das allegemeinere Muster dahinter sieht so aus:
Klammere mal, wie die Schleifen ineinander geschachtelt sind
1
  ldi     r17,0xFF
2
warte0:               --------------+
3
  ldi     r16,0x80                  |
4
warte1:               ---------+    |
5
  dec     r16                  |    |
6
  brne    warte1      ---------+    |
7
  dec     r17                       |
8
  ...                               |
9
  brne    warte0      --------------+
solange diese Klammerschachtelung sich nicht überkreuzt, die Dinge also 
sauber ineinander geschachtelt sind, tun wir Menschen uns seltsamerweise 
leichter die Dinge zu überblicken.

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.