Forum: Mikrocontroller und Digitale Elektronik erstes ASM Programm.wo ist der Fehler?


von blub² (Gast)


Lesenswert?

Hallo,

das ist mein erstes ASM Programm.

Leider funktioniert es nicht. Aber einen Fehler kann ich irgendwie nicht 
entdecken.

Eigentlich soll wenn Taste1 gedrückt LED1 leuchten und wenn Taste2 
gedrückt LED2 leuchten. Wenn keine Taste gedrückt dann sollen auch keine 
LED leuchten.
1
.DEVICE ATtiny2313
2
.INCLUDE "tn2313def.inc"
3
4
5
.EQU TAKT = 8000000
6
7
8
.CSEG
9
10
start:
11
  LDI R16, 0b0010100  ;lade wert in r16
12
  OUT DDRD, R16    ;pin2 und pin4 auf Eingang setzten
13
14
  LDI R18,0x00    ;setze vergleichsregister auf 00
15
16
loop:
17
  LDI R17, 0x00    ;setze R17 auf 0
18
  LDI R16, 0x00    ;setze R16 auf 0
19
  SBIC PIND,PIND2    ;prüfe ob PIN2 gesetzt
20
    LDI R17, 0xff  ;wenn JA dann setze R17 auf FF
21
  SBIC PIND,PIND4    ;prüfe ob PIN4 gesetzt
22
    LDI R16, 0xff  ;wenn JA dann setze R16 auf FF
23
24
25
  CP R17,R18      ;vergleiche R17 mit R18(00)
26
    BRNE weiter1  ;wenn ungleich 00 dann spring zu weiter1
27
  CP R16,R18      ;vergleiche R16 mit R18(00)
28
    BRNE weiter2  ;wenn ungleich 00 dann spring zu weiter2
29
30
  LDI R16,0b0000000  ;lade wert in r16
31
  OUT PORTD5,R16    ;lösche led an pin6 und lösche led an pin5
32
RJMP loop
33
34
;
35
;unterprogramme
36
;
37
weiter1:
38
  LDI r16,0b1000000
39
  OUT PORTD5,r16  ;setze led an pin6 und lösche led an pin5
40
RJMP loop
41
42
weiter2:
43
  LDI r16,0b0100000
44
  OUT PORTD5,r16  ;setze led an pin5 und lösche led an pin6
45
RJMP loop

Vielleicht seht ihr ja was was mir nicht auffällt als Anfänger?

von Peter (Gast)


Lesenswert?

> Vielleicht seht ihr ja was was mir nicht auffällt als Anfänger?
auf anhieb nicht, aber warum geht du nicht einfach mit dem Simulator 
durch - im Einzelschritt modus.

Es könnte ja auch an der Hardware liegen - inverierte eingänge oder 
ausgänge?

von blub² (Gast)


Lesenswert?

Also ich hab den Simulator drüber laufen lassen.

Dort wurden jedenfalls schonmal keine Fehler festgestellt.

Allerdings weiß ich nicht wo ich mir die Ausund eingänge anzeigen lassen 
kann...? Sorry, bin echt noch voll der Anfänger. :(

von Peter (Gast)


Lesenswert?

bei den IO-Port, dort gibt es doch die gleiche bezeichung PORTA, DDRA, 
PINA

von Anton (Gast)


Lesenswert?

>  LDI R16, 0b0010100  ;lade wert in r16
>  OUT DDRD, R16    ;pin2 und pin4 auf Eingang setzten

Das setzt aber PB2 und PB4 auf Ausgang!

von Anton (Gast)


Lesenswert?

meinte natürlich PD2 und PD4 :-)

von Dummi (Gast)


Lesenswert?

PORTD5 durch PORTD ersetzen.

Und warum haben deine Binärkonstanten nur 7 Bit?

Deine internen Pullups sin ausgeschaltet.

mfg.

von blub² (Gast)


Lesenswert?

Danke Anton, das hab ich im Buch dann wohl genau falschrum gelesen.
1
.DEVICE ATtiny2313
2
.INCLUDE "tn2313def.inc"
3
4
5
.EQU TAKT = 8000000
6
7
8
.CSEG
9
10
start:
11
  LDI R16, 0b1101011  ;lade wert in r16
12
  OUT DDRD, R16    ;pin2 und pin4 auf Eingang setzten
13
14
  LDI R18,0x00    ;setze vergleichsregister auf 00
15
16
loop:
17
  LDI R17, 0x00    ;setze R17 auf 0
18
  LDI R16, 0x00    ;setze R16 auf 0
19
  SBIC PIND,PIND2    ;prüfe ob PIN2 gesetzt
20
    LDI R17, 0xff  ;wenn JA dann setze R17 auf FF
21
  SBIC PIND,PIND4    ;prüfe ob PIN5 gesetzt
22
    LDI R16, 0xff  ;wenn JA dann setze R16 auf FF
23
24
25
  CP R17,R18      ;vergleiche R17 mit R18(00)
26
    BRNE weiter1  ;wenn ungleich 00 dann spring zu weiter1
27
  CP R16,R18      ;vergleiche R16 mit R18(00)
28
    BRNE weiter2  ;wenn ungleich 00 dann spring zu weiter2
29
30
  LDI R16,0b0000000  ;lade wert in r16
31
  OUT PORTD,R16    ;lösche led an pin6 und lösche led an pin5
32
RJMP loop
33
34
;
35
;unterprogramme
36
;
37
weiter1:
38
  LDI r16,0b1000000
39
  OUT PORTD,r16  ;setze led an pin6 und lösche led an pin5
40
RJMP loop
41
42
weiter2:
43
  LDI r16,0b0100000
44
  OUT PORTD,r16  ;setze led an pin5 und lösche led an pin6
45
RJMP loop

So klappt es jetzt wie es soll.

>Und warum haben deine Binärkonstanten nur 7 Bit?
Das 8. Bit ist in AVR Studio eingegraut. daher dachte ich brauch ich es 
auch nicht zu setzten.

>Deine internen Pullups sin ausgeschaltet.
Woran siehst du das? Bzw. wie schalt ich sie ein?

von Dummi (Gast)


Lesenswert?

Die Pullups werden auch über den PORT gesetzt.
Du must natürlich keine 8 Bit hinschreiben aber es macht es für mich und 
andere leichter lesbar.
zb. bei 0b1000000 denk ich spontan das oberste Bit ist gesetzt.
Sehe sozusagen 0b10000000

von Thomas (kosmos)


Lesenswert?

Stackpointer initialisiert?
1
stackinit:      ;Stackpointer initialisieren
2
ldi temp, RAMEND
3
out SP, temp

von Peter (Gast)


Lesenswert?

@Thomas O.
> Stackpointer initialisiert?
braucht er hier ja nicht, es wird ja kein (r)call verwendet und auch 
keine ISR

von blub² (Gast)


Lesenswert?

>Die Pullups werden auch über den PORT gesetzt.
Wie jetzt, das versteh ich nicht.

Ich dachte mit

LDI R16, 0xFF
OUT PORTD,R16

setz ich die Ausgänge auf HIGH?


>Du must natürlich keine 8 Bit hinschreiben aber es macht es für mich und
>andere leichter lesbar.

Okay, merk ich mir.

von Gerhard (Gast)


Lesenswert?

1
LDI R16, 0b0010100  ;lade wert in r16

Der Kommentar ist ja klassisch... Ich lach mir 'nen Ast. Geht aber noch 
besser:
1
LDI R16, 0b0010100 ; Lade Immediate in Register R16, und zwar folgende
2
                   ; 7 Bits: 0b0010100



Oder die C-Variante:
1
i++; // increase i by one

von blub² (Gast)


Lesenswert?

Ja danke... omfg

von blub² (Gast)


Lesenswert?

Ah jetzt hab ich das geblickt.

Also allen PIN's die auf Eingang geschaltet sind muß per PORTx der 
Pull-Up zugeschaltet werden.

So, da hab ich aber ein Problem:

Meine Ein- und Ausgänge liegen ja auf einem Port. Wie schalte ich nun 
die Wiederstände für die Eingangspin's ein, aber lasse die andren 
Ausgangspin's in ruhe?

von Thomas (kosmos)


Lesenswert?

1
ldi temp, 0b11110000
2
out DDRA, temp        ;Pin 7-4 = Ausgang ; Pin 3-0 Eingang
3
4
ldi temp, 0b00001111
5
out porta, temp       ;Pullups für die Eingänge 3-0 aktiviert

um alle Pullups auszuschalten kann man auch das PUD-Bit im SFIO-Register 
setzen

von Thomas (kosmos)


Lesenswert?

wenn du die Ausgangspins in Ruhe lassen willst musst du erstmal 
feststellen wie die stehen und dann mit einer OR-Verknüpfung die Pins 
auswählen die die ändern willst.

  11110000
  00001111
= 11111111

von blub² (Gast)


Lesenswert?

Okay, dass das so geht hab ich mir schon gedacht.

Muß ich dann jedesmal wenn ich eine LED über OUT PORTD schalte auch 
wieder die Wiederstände mitschalten?
1
weiter1:
2
  LDI r16,0b1000000
3
  OUT PORTD,r16  ;setze led an pin6 und lösche led an pin5
4
RJMP loop
5
6
weiter2:
7
  LDI r16,0b0100000
8
  OUT PORTD,r16  ;setze led an pin5 und lösche led an pin6
9
RJMP loop


Da schalt ich ja jetzt nur die LED und würde ja die Wiederstände wieder 
auf 0 setzten. Muß ich dann das so schreiben?

  LDI r16,0b11010100
  OUT PORTD,r16  ;setze led an pin5 und lösche led an pin6

von Thomas (kosmos)


Angehängte Dateien:

Lesenswert?

schau dir mal die Befehle
cbi, cbr, sbi und sbr an.

von Karl H. (kbuchegg)


Lesenswert?


von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter schrieb:
>> Stackpointer initialisiert?
> braucht er hier nicht, es wird kein (r)call verwendet und auch keine ISR
Noch nicht   :-o
Die Anlagen dafür sind aber da:
1
;
2
;unterprogramme
3
;
Wenn blub² mal herausgefunden hat, dass Unterprogramme mit call 
aufgerufen werden, dann gibts das nächste Problem.

@ blub²
Lass die Kommentare weg. Diese sind überflüssig:
1
  CP R16,R18         ; vergleiche R16 mit R18(00)
2
  BRNE weiter2       ; wenn ungleich 00 dann spring zu weiter2
3
  LDI R16,0b0000000  ; lade wert in r16
Das steht kompakter im Befehl selbst.

Und der hier falsch:
1
OUT PORTD,r16  ;setze led an pin6 und lösche led an pin5
Der Befehl macht nicht das, was im Kommentar steht  :-/

von blub² (Gast)


Lesenswert?

@Thomas O.

Danke für super Hilfe und Datei. Die hab ich noch garnicht entdeckt 
gehabt.

So, jetzt hab ich das ein bissel umgeschrieben.

Gemäß Simulation sollte das auch alles klappen. Aber wenn ich es dann im 
µC laufen lasse passiert folgendes:

Taste 1 gedrückt: beide LED leuchten
Taste 2 gedrückt beide LED leuchten

Das versteh ich jetzt nicht so richtig. Wo liegt der Fehler?
1
.DEVICE ATtiny2313
2
.INCLUDE "tn2313def.inc"
3
4
5
.EQU TAKT = 8000000
6
7
8
.CSEG
9
10
start:
11
12
  LDI R16, 0b011100011
13
  OUT DDRD, R16
14
  LDI R16, 0b000011100
15
  OUT PORTD, R16
16
  
17
  LDI R18,0x00
18
19
loop:
20
  LDI R16, 0x00
21
  LDI R17, 0x00
22
23
  SBIC PIND,PIND2
24
    LDI R16, 0xff
25
  SBIC PIND,PIND4
26
    LDI R17, 0xff
27
28
  CP R16,R18
29
    BRNE weiter1
30
  CBI PORTD,6
31
back1:
32
  CP R17,R18
33
    BRNE weiter2
34
  CBI PORTD,5
35
back2:
36
RJMP loop
37
38
;
39
;unterprogramme
40
;
41
42
weiter1:
43
  SBI PORTD,6
44
RJMP back1
45
46
weiter2:
47
  SBI PORTD,5
48
RJMP back2

von Otto (Gast)


Lesenswert?

jetz haben die Binärkonstanten 9 Bit

von blub² (Gast)


Lesenswert?

Ups :(

Bei den ganzen nullen und einsen...

von blub² (Gast)


Lesenswert?

Ändert aber nix. Es leuchten trotzdem beide LED wenn ich eine Taste 
drücke.

Es gibt noch eine 3. Taste die im Programm nicht verwendet wird, aber 
trotzdem die LED's einschaltet????

von Otto (Gast)


Lesenswert?

Was passiert denn, wenn Du es so machst:

     CBI PORTD,6
     CBI PORTD,6

  SBIS PIND,PIND2
     SBI PORTD,6

  SBIS PIND,PIND4
     SBI PORTD,5

RJMP loop

von blub² (Gast)


Lesenswert?

1
start:
2
3
  LDI R16, 0b1100011
4
  OUT DDRD, R16
5
  LDI R16, 0b0011100
6
  OUT PORTD, R16
7
  
8
  LDI R18,0x00
9
10
11
loop:
12
13
14
     CBI PORTD,5
15
     CBI PORTD,6
16
17
  SBIC PIND,PIND2
18
     SBI PORTD,6
19
20
  SBIC PIND,PIND4
21
     SBI PORTD,5
22
23
RJMP loop

1. schlecht weil led's ständig an und aus geschaltet werden, wenn taste 
gedrückt (theoretisch)

2. funktioniert auch nicht, weil wieder beide led'S leuchten (praktisch) 
:(

von Thomas (kosmos)


Lesenswert?

man muss den Pin abfragen wenn er high ist, die LED einschalten 
ansonsten verzweigen und die LED ausschalten, wenn man die nicht 
auschaltet ist ja klar das die anbleibt. Ich jage den Code mal kurz 
durch den Simulator

von blub² (Gast)


Lesenswert?

1
.DEVICE ATtiny2313
2
.INCLUDE "tn2313def.inc"
3
4
5
.EQU TAKT = 8000000
6
7
8
.CSEG
9
10
start:
11
12
  LDI R16, 0b011100011
13
  OUT DDRD, R16
14
  LDI R16, 0b000011100
15
  OUT PORTD, R16
16
  
17
  LDI R18,0x00
18
19
loop:
20
  LDI R16, 0x00
21
  LDI R17, 0x00
22
23
  SBIC PIND,PIND2 ;taster gedrückt?
24
    LDI R16, 0xff ;wenn ja
25
  SBIC PIND,PIND4
26
    LDI R17, 0xff
27
28
  CP R16,R18 
29
    BRNE weiter1
30
  CBI PORTD,6 ; hier led aus
31
back1:
32
  CP R17,R18
33
    BRNE weiter2
34
  CBI PORTD,5
35
back2:
36
RJMP loop
37
38
;
39
;unterprogramme
40
;
41
42
weiter1:
43
  SBI PORTD,6
44
RJMP back1
45
46
weiter2:
47
  SBI PORTD,5
48
RJMP back2

von Otto (Gast)


Lesenswert?

> 1. schlecht weil led's ständig an und aus geschaltet werden, wenn taste
> gedrückt (theoretisch)

Ist doch erst einmal Wurst....

Entweder hängen die Taster oder die LED nicht an den richtigen Ports

von Thomas (kosmos)


Lesenswert?

1
.DEVICE ATtiny2313
2
.INCLUDE "tn2313def.inc"
3
.def  temp=r16
4
.EQU TAKT = 8000000
5
6
.CSEG
7
8
stackinit:      ;Stackpointer initialisieren
9
ldi temp, RAMEND
10
out SPL, temp
11
12
portinit:
13
  ldi r16, 0b011100011
14
  out ddrd, r16
15
  ldi r16, 0b000011100
16
  out portd, r16
17
  
18
Abfrage:
19
  SBIC PIND,PIND2
20
    RJMP PortD5an
21
  CBI PORTD,5
22
  
23
Abfrage2:
24
  SBIC PIND,PIND4
25
    RJMP PortD6an
26
  CBI PORTD,6
27
28
RJMP Abfrage
29
30
PortD5an:
31
SBI PORTD,5
32
rjmp Abfrage2
33
34
PortD6an:
35
SBI PORTD,6
36
rjmp Abfrage

von Otto (Gast)


Lesenswert?

wieder 9bit Binärkonstanten......

von blub² (Gast)


Lesenswert?

@Thomas O.

Danke. Nur leider funzt das auch nicht. Ich drücke eine Taste und beide 
LED gehen an. :(

Ich hau das Ding gleich in die Tonne. :'(

Gestern abend hatte ich das noch per Unterprogramm gemacht. Incl. 
Statckinit und da hat es geklappt. und mit den SBI CBI Befehlen funzt 
das nicht. Ich kapier nicht warum. Der Simulator zeigt doch an das es 
klappen sollte...

von blub² (Gast)


Lesenswert?

Sooooo, manchmal sieht man echt den Wald vor Bäumen nicht.

Man,man,man. Logisch, wenn man einen externen Pullup hat, braucht, bzw. 
sollte, man nicht noch den internen einschalten. OMFG

Also, Programm funzt. Danke euch, besonderst Thomas, dass ihr euch mit 
mir den Kopf zerbrochen habt.

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.