Forum: Mikrocontroller und Digitale Elektronik AVR-ASM Anfänger


von Hansi (Gast)


Lesenswert?

Hallo zusammen,

bin ganz neu in der AVR-ASM-Programmierung und mein erstes kleines 
Programm läuft auf dem ATmega8 und macht sogar das, was es soll ;-).
Das Programm macht nix anderes als die ganze Zeit 5 LEDs nach der Reihe 
ein und wieder auszuschalten.

Jetzt ist das doch ein schöner Brocken Code...besonders mit der 
Programmierung zum Ausschalten der LEDs bin ich noch nicht ganz 
zufrieden (ist das Einschalten über Bitshifting in Ordnung?).

Kann mir jemand dazu einen Tipp geben? Auch allgemein zu dem Programm, 
ich möchte mir nämlich da nicht was "falsches" angewöhnen...Danke 
schonmal.

1
.NOLIST
2
.INCLUDE "m8def.inc"         ; Definitionsdatei für ATmega8
3
.LIST
4
Loop:
5
       ldi r16, LOW(RAMEND)    ;Initialisierung Stackpointer
6
       out SPL, r16
7
       ldi r16, HIGH(RAMEND)  
8
       out SPH, r16
9
schleife:
10
         ldi r16, 0x3F       ; lade 0x3F in r16
11
         out DDRB, r16       ; Inhalt von r16 in DDRB ausgeben
12
         ldi r16,0b00111111  ; Alle LEDs aus
13
14
            
15
ein:     lsr r16      ;LEDs werden der Reihe nach durch rechts-shift eingeschaltet
16
     out PORTB,r16    ;Ausgabe über PORTB
17
     BREQ aus      ;wenn Z-Flag (alle LEDs an) gesetzt, spring raus.
18
        rcall WARTEN    ;Warteschleife
19
     rjmp ein      
20
21
22
aus:
23
     ldi r16,0x01    ;Lade 0x01 in r16, letze LED aus
24
     out PORTB, r16;  
25
     rcall WARTEN;
26
27
     ldi r17,0x02    ;Lade 0x02 in r17
28
     MOV r16,r17    ;Kopiere r17 in r16
29
     out PORTB, r16;
30
     rcall WARTEN;
31
32
     ldi r17,0x04    ;Addiere zu r17 0x04
33
     ADD r16,r17;    ;Kopiere neuen Wert in r16 usw.
34
     out PORTB, r16;
35
     rcall WARTEN;
36
37
     ldi r17,0x08;
38
     ADD r16,r17;
39
     out PORTB, r16;
40
     rcall WARTEN;
41
     
42
     ldi r17,0x10;
43
     ADD r16,r17;
44
     out PORTB, r16;
45
     rcall WARTEN;
46
47
     ldi r17,0x20;
48
     ADD r16,r17;
49
     out PORTB, r16;
50
     rcall WARTEN;
51
52
     rjmp Loop;
53
          
54
; =============================
55
;    delay loop generator
56
;     wait 0,25 s at 4 MHz
57
;     1000000 cycles:
58
; -----------------------------
59
; delaying 999998 cycles:
60
WARTEN:
61
          ldi  R17, $09;
62
WGLOOP0:  ldi  R18, $BC;
63
WGLOOP1:  ldi  R19, $C4;
64
WGLOOP2:  dec  R19;
65
          brne WGLOOP2;
66
          dec  R18;
67
          brne WGLOOP1;
68
          dec  R17;
69
          brne WGLOOP0;
70
; -----------------------------
71
; delaying 1 cycle:
72
          nop
73
          ret
74
; =============================

von jaja (Gast)


Lesenswert?

Aus'm Gedächnis müsste das (der?) passende Mnemonic LSL sein: Logical 
Shift Left. Guck mal ins Instruction Set.

von jaja (Gast)


Lesenswert?

ldi r17,0x02    ;Lade 0x02 in r17
MOV r16,r17    ;Kopiere r17 in r16

Warum nicht direkt ldi r16? Und die Mnemonics entweder groß oder 
kleinschreiben, aber nicht beides gleichzeitig.

von Hansi (Gast)


Lesenswert?

LSL funktioniert leider nicht (zumindest bekomm ichs nicht hin). r16 ist 
ja 0, wenn ich da dann einen Linksshift mache, bleibts weiterhin 0.

Die Addition war eigentlich nur eine Rechenerleichterung für mich ;-)

von spess53 (Gast)


Lesenswert?

Hi

>        ldi r16, 0x3F       ; lade 0x3F in r16
>        out DDRB, r16       ; Inhalt von r16 in DDRB ausgeben
>        ldi r16,0b00111111  ; Alle LEDs aus

Hast du nun 5 oder 6 LEDs?


>ist das Einschalten über Bitshifting in Ordnung?

>ein:     lsr r16
>         out PORTB,r16    ;Ausgabe über PORTB
>         BREQ aus      ;

Das funktioniert nur, weil 'out' keine Flags beeinflußt. Glück gehabt. 
Außerdem shiftest du weiter als du must. Besser wäre
1
ein:     lsr r16 
2
         out PORTB,r16    ;Ausgabe über PORTB
3
         andi r16,0b00111111
4
         BREQ aus

Deine Aus-Routine lässt sich auch durch Schieben realisieren:

[avrasm]
aus:     clr r16       ; r16 = $00
aus10:   sec           ; Carry-Flag setzen
         rol r16       ; nach r16 schieben
         out PORTB,r16
         rcall WARTEN    ;Warteschleife
         cpi r16,0b00111111
         BREQ loop
         rjmp aus10
[avrasm]

MfG Spess

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

Alternativ
1
ldi r16,1
2
out PORTB,r16
3
add r16,r16
4
cpi r16,0b00111111
5
breq ...

spart das sec

Gruss und viel Spass beim austesten

von Hansi (Gast)


Lesenswert?

Danke für die Tipps...es funktioniert und ich kapier zum Glück auch, 
warum :-)

ich hab 5 LEDs, nur an PB1 bis PB5 angeschlossen. Hab ich vorhin 
vergessen, sorry.

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

Ups, ich meinte
1
ldi r16,1
2
out PORTB,r16
3
add r16,r16
4
inc r16
5
cpi r16,0b00111111
6
breq ...

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.