Forum: Mikrocontroller und Digitale Elektronik Benötige Bitte eine Erklärung über dieses ASM Code


von Christof (Gast)


Lesenswert?

Hi,

und zwar machen wir gerade in unserer Schule ein bisschen Assembler mit 
einem ATmega32. Ich habe vieles dazu bereits verstanden, nur hätte ich 
eine Frage und zwar für was ist dieser Bereich zuständig?

So wie ich das sehe werden in den Speicher Bereiche definiert, aber vor 
was diese gut sind ist mir nicht ersichtlich.

gruß

Christof


Bereich:
1
####################################
2
3
 .ORG  0x0000               
4
 rjmp  start   ;springe zu start             
5
 .ORG  0x0002
6
 rjmp  zaehlen ;springe zu zaehlen
7
 .ORG  0x0004
8
 rjmp  null    ;springe zu null
9
10
####################################
11
12
ASM_Code:
13
14
15
16
 .include    "m32def.inc"
17
18
19
 .DSEG              ; definiert den Start eines Datensegmentes
20
21
 zahl:  .BYTE 1          ; Reservierung von einen Byte 
22
23
 .CSEG               ; Datensegment definierung schließen
24
25
26
 .ORG  0x0000               
27
 rjmp  start                
28
 .ORG  0x0002
29
 rjmp  zaehlen
30
 .ORG  0x0004
31
 rjmp  null
32
33
 start:
34
 ldi  r16,LOW(RAMEND)   ; ldi = Lade Register mit Wert;  LOW-Byte der obersten RAM-Adresse 
35
 out  SPL,r16        ; kopiere Register r16 in Stack-Pointer-Register LOW = SPL
36
 ldi  r16,HIGH(RAMEND)  ; HIGH-Byte der obersten RAM-Adresse
37
 out  SPH,r16        ; kopiere Register r16 Stack-Pointer-Register HIGH = SPH
38
39
ldi    r16,0b00001011    ; Lade 00001011 in das Register r16  
40
out    MCUCR,r16      ; --> Eine steigende Flanke am INT0 Pin löst Interrupt aus (Seite66)
41
ldi    r16,0b11000000    ; Lade 11000000 in das Register r16  
42
out    gicr,r16      ; -->  Externer Interrupt 1 Freigabe für INT1 und INT0 (Seite 69)
43
44
cbi    DDRD,2        ; Bit in I/O-Register löschen (auf 0 setzen), PORT D / PIN 2  
45
cbi    DDRD,3        ; Bit in I/O-Register löschen (auf 0 setzen), PORT D / PIN 3  
46
sbi    PORTD,2        ; Bit in I/O-Register setzen  (auf 1 setzen), PORT D / PIN 2  
47
sbi    PORTD,3        ; Bit in I/O-Register setzen  (auf 1 setzen), PORT D / PIN 3  
48
49
ldi    r16, 0xFF         ; Lade 11111111 in das Register r16
50
out    DDRA,r16          ; kopiere register 16 nach PORT DDRA ??richtig??
51
52
ldi    r20,0        ; Lade 00000000 in das Register r20
53
54
sei              ; interrupt aktivieren
55
56
los:    rjmp  los     ; Springe in der Schleife los hin und her
57
58
zaehlen:
59
push  r20              ; Speichere register R20 in den Stack 
60
in    r20,SREG      ; Status Register in R20 kopieren
61
push  r20           ; Speichere register R20 in den Stack 
62
lds    r20,ZAHL          ; Lade Register r20 mit Byte (zahl) aus Datenspeicher
63
inc    r20               ; R20 Inkrementierung 
64
out    PORTA,r20         ; kopiere Register R20 in den PORT A
65
sts    ZAHL,r20      ; Speichere Register R20 in den Datenspeicher (ZAHL)
66
pop    r20          ; LADE vom Stapel(stack) in Register R20
67
out    SREG,r20          ; kopiere Register r20 in das Status Register
68
pop    r20          ; LADE vom Stapel in Register R20
69
reti                      ; Rücksprung von Interrupt - Routine  
70
71
null:
72
push  r20               ; Speichere register R20 in den Stack 
73
in    r20,SREG      ; Status Register in R20 kopieren
74
push  r20          ; Speichere register R20 in den Stack 
75
ldi    r20,0             ; Lade 0 in das Register R20
76
out    PORTA,r20      ; kopiere das Register R20 in den PORT A
77
sts    ZAHL,r20      ; Speichere Register R20 in den Datenspeicher (ZAHL)
78
pop    r20          ; LADE vom Stapel in Register R20
79
out    SREG, r20         ; kopiere Register R20 in das Status Register
80
pop    r20          ; Lade vom Stapel in Register R20 
81
reti                      ; Rücksprung von Interrupt - Routine

: Bearbeitet durch Moderator
von Cyblord -. (cyblord)


Lesenswert?

Christof schrieb:
> Hi,
>
> und zwar machen wir gerade in unserer Schule ein bisschen Assembler mit
> einem ATmega32. Ich habe vieles dazu bereits verstanden, nur hätte ich
> eine Frage und zwar für was ist dieser Bereich zuständig?
>
> So wie ich das sehe werden in den Speicher Bereiche definiert,
Wo glaubst du sowas zu sehen? Was genau meinst du damit?

Poste doch mal exakt den Codeteil den du nicht verstehst.

von Holger P. (Gast)


Lesenswert?

Du meinst was dieser Auszug bedeutet?

 .ORG  0x0000
 rjmp  start
 .ORG  0x0002
 rjmp  zaehlen
 .ORG  0x0004
 rjmp  null


Das sind die Interrupt Vektoren des ATmega32

0x0000 wird ausgelöst vom Power on Reset also der Punkt an dem Dein 
Programm anfängt

0x0002 Ist der externe Interrupt 0. Wir also ausgelöst wen der Interrupt 
zustande kommt. Ich nehme an Ihr habt einen Puls an diesem Pin den Ihr 
zählen wollt.

0x0004 Ist der externe Interrupt 1. Wir also ausgelöst wen der Interrupt 
zustande kommt. Auch hier nehme ich an das ihr ein Taster dran habt der 
das Zählen zurück setzen soll.

ODER?

von Christof (Gast)


Lesenswert?

Cyblord ---- schrieb:
> Poste doch mal exakt den Codeteil den du nicht verstehst.

Es geht um den Bereich den Holger erklärt hat.

Holger P. schrieb:
> Das sind die Interrupt Vektoren des ATmega32
>
> 0x0000 wird ausgelöst vom Power on Reset also der Punkt an dem Dein
> Programm anfängt
>
> 0x0002 Ist der externe Interrupt 0. Wir also ausgelöst wen der Interrupt
> zustande kommt. Ich nehme an Ihr habt einen Puls an diesem Pin den Ihr
> zählen wollt.
>
> 0x0004 Ist der externe Interrupt 1. Wir also ausgelöst wen der Interrupt
> zustande kommt. Auch hier nehme ich an das ihr ein Taster dran habt der
> das Zählen zurück setzen soll.
>
> ODER?

Danke Holger für die Ausführliche Erklärung :-)
Genau an Interrupt 0 kommt ein Puls der gezählt werden soll. Das ganze 
soll über einen Taster der an Interrupt 1 angeschlossen ist wieder auf 
Null gesetzt werden.

von Holger P. (Gast)


Lesenswert?

Und somit wird beim Start des Programmes zu start: gesprungen.

Bei Irq 0 zu zaehlen:
und
Bei Irq 1 zu null:


da in den Vektoren ein rjmp steht


mit dem reti am ende der Routinen wird wieder dahin zurückgesprungen wo 
es vor dem Aufruf war.


In Deinem Fall in der Endlosschleife:

los:    rjmp  los     ; Springe in der Schleife los hin und her

von Karl H. (kbuchegg)


Lesenswert?

Der springende Punkt ist, dass der Prozessor bei Auftreten von 
bestimmten Ereignissen (die einzeln freigegeben werden können) seine 
Arbeit unterbricht und an genau definierte Adressen im Code springt um 
dann dort weiter zu machen.
Genau so kommen die .ORG zu Stande. Sie teilen dem Assembler mit, den 
nachfolgenden Code an genau die beim .ORG angegebene Adresse zu legen.

: Bearbeitet durch User
von Christof (Gast)


Lesenswert?

Danke an euch allen, jetzt habe ich das ganze richtig Verstanden

von Peter D. (peda)


Lesenswert?

Christof schrieb:
> .ORG  0x0000
>  rjmp  start
>  .ORG  0x0002
>  rjmp  zaehlen
>  .ORG  0x0004
>  rjmp  null

Wobei das in der Praxis niemand so schreibt.

Die Lage der Vektoren ist nämlich nicht in Stein gemeißelt, sondern für 
jeden AVR-Typ unterschiedlich!
Daher schreibt man nicht die Adresse als feste Nummer, sondern nimmt die 
Namen aus dem Include-File bzw. Datenblatt des Target.

Nebenbei erkennt man aus dem Namen gleich die Funktion des Vektors.
1
.org 0x001e   ; hä, wasn das ?
Aber:
1
.org UTXCaddr ; USART, Tx Complete

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.