Problem mit Tonerzeugung mit dem ATmega8

OP #2858236
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
#2858271
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.

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