Hallo,
ich habe mir hier auf
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Interrupts
den Artikel über Interrupts durchgelesen und das Prinzip verstanden.
Jeodoch weiß ich nicht, was speziell
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
bewirkt. Könnt ihr mir helfen?
Danke!
eigentlich selbsterklärend :-)
Üblicherweise wird der Stackbeginn ans Ende des RAMs gesetzt, dieses
liegt aber bei den verschiedenen AVRs aufgrund unterschiedlicher
RAM-Grösse an anderen Adressen.
Also wird in der entsprechenden .def-Datei diese letzte RAM-Adresse
definiert und dann der SP mit diesem Wert initialisiert.
Da wird der Stackpointer initalisiert. Ohne Stack würde man anch einem
Interupt im Nirvana landen.
RAMEND ist die Adresse der letzten SRAM-Speicherzelle. Der Stack beginnt
man Ende des SRAMs und wächst dann Richtung Anfang. Man setzt daher den
Stackpointer zu Beginn auf die letzte Speicherzelle.
das läd die allerletzte speicheraddresse in den stackpointer (Stack
Pointer High + Stack Pointer Low SPL/SPH)
der stack ist der zwischenspeicher und wird von hinten her gefüllt.
damit es nicht mit deinen nutzdaten kollidiert die von vorne im speicher
gefüllt werden muss der stackpointer eben auf die letzte speicherstellt
= RAMEND zeigen.
RAMEND ist für jeden controller je nach speichergröße definiert
sollte man den stackpointer vergesseen zu definieren weiß der controller
nach einer subroutine (z.b. interrupts) nicht mehr wohin er
zurückspringen soll u. das programm spinnt.
gleich so viele Antworten, danke Euch!
Ich arbeite mit einem Grundgerüst. Da wird der Stack automatisch
aktiviert:
+----------------------------------------------------------------------
;| Title : myAVR Grundgerüst für ATmega8
;+----------------------------------------------------------------------
;| Funktion : ...
;| Schaltung : ...
;+----------------------------------------------------------------------
;| Prozessor : ATmega8
;| Takt : 3,6864 MHz
;| Sprache : Assembler
;| Datum : ...
;| Version : ...
;| Autor : ...
;+----------------------------------------------------------------------
.include "AVR.H"
;-----------------------------------------------------------------------
-
;Reset and Interrupt vector ;VNr. Beschreibung
rjmp main ;1 POWER ON RESET
reti ;2 Int0-Interrupt
reti ;3 Int1-Interrupt
reti ;4 TC2 Compare Match
reti ;5 TC2 Overflow
reti ;6 TC1 Capture
reti ;7 TC1 Compare Match A
reti ;8 TC1 Compare Match B
reti ;9 TC1 Overflow
reti ;10 TC0 Overflow
reti ;11 SPI, STC Serial Transfer Complete
reti ;12 UART Rx Complete
reti ;13 UART Data Register Empty
reti ;14 UART Tx Complete
reti ;15 ADC Conversion Complete
reti ;16 EEPROM Ready
reti ;17 Analog Comparator
reti ;18 TWI (I²C) Serial Interface
reti ;19 Store Program Memory Ready
;-----------------------------------------------------------------------
-
;Start, Power ON, Reset
main: ldi r16,lo8(RAMEND)
out SPL,r16
ldi r16,hi8(RAMEND)
out SPH,r16
;Hier Init-Code eintragen.
;-----------------------------------------------------------------------
-
mainloop: wdr
;Hier den Quellcode eintragen.
rjmp mainloop
;-----------------------------------------------------------------------
-
kann ich dann also, wenn ich mit Interrupts arbeite genau das was ich
eben zitiert habe weglassen, da der Stack ja in dem Grundgerüst schon
aktiviert wird?
Ja, klar
Du brauchst das ja nicht doppelt schreiben...
In deinem Grundgerüst stehen doch genau die selben Zeilen, die du am
Anfang zitiert hast...
MfG
Muecke
also so hab ich es jetzt zusammengefügt
;+----------------------------------------------------------------------
;| Title : myAVR Grundgerüst für ATmega8
;+----------------------------------------------------------------------
;| Funktion : ...
;| Schaltung : ...
;+----------------------------------------------------------------------
;| Prozessor : ATmega8
;| Takt : 3,6864 MHz
;| Sprache : Assembler
;| Datum : ...
;| Version : ...
;| Autor : ...
;+----------------------------------------------------------------------
.include "AVR.H"
.include "m8def.inc"
;-----------------------------------------------------------------------
-
;Reset and Interrupt vector ;VNr. Beschreibung
rjmp main ;1 POWER ON RESET
reti ;2 Int0-Interrupt
reti ;3 Int1-Interrupt
reti ;4 TC2 Compare Match
reti ;5 TC2 Overflow
reti ;6 TC1 Capture
reti ;7 TC1 Compare Match A
reti ;8 TC1 Compare Match B
reti ;9 TC1 Overflow
reti ;10 TC0 Overflow
reti ;11 SPI, STC Serial Transfer Complete
reti ;12 UART Rx Complete
reti ;13 UART Data Register Empty
reti ;14 UART Tx Complete
reti ;15 ADC Conversion Complete
reti ;16 EEPROM Ready
reti ;17 Analog Comparator
reti ;18 TWI (I²C) Serial Interface
reti ;19 Store Program Memory Ready
;-----------------------------------------------------------------------
-
;Start, Power ON, Reset
main: ldi r16,lo8(RAMEND)
out SPL,r16
ldi r16,hi8(RAMEND)
out SPH,r16
;Hier Init-Code eintragen.
;-----------------------------------------------------------------------
-
.def temp = r16
.org 0x000
rjmp main ; Reset Handler
.org INT0addr
rjmp int0_handler ; IRQ0 Handler
.org INT1addr
rjmp int1_handler ; IRQ1 Handler
main: ; hier beginnt das Hauptprogramm
ldi temp, 0x00
out DDRD, temp
ldi temp, 0xFF
out DDRB, temp
ldi temp, 0b00001010 ; INT0 und INT1 konfigurieren
out MCUCR, temp
ldi temp, 0b11000000 ; INT0 und INT1 aktivieren
out GICR, temp
sei ; Interrupts allgemein aktivieren
loop: rjmp loop ; eine leere Endlosschleife
int0_handler:
push temp ; Das SREG in temp sichern. Vorher
in temp, SREG ; muss natürlich temp gesichert werden
sbi PORTB, 0
out SREG, temp ; Die Register SREG und temp wieder
pop temp ; herstellen
reti
int1_handler:
push temp ; Das SREG in temp sichern. Vorher
in temp, SREG ; muss natürlich temp gesichert werden
cbi PORTB, 0
out SREG, temp ; Die Register SREG und temp wieder
pop temp ; herstellen
reti
;-----------------------------------------------------------------------
-
und ich bekomme jede Menge Fehler beim komilieren:
Assembler Meldungen:
m8_Grundgeruest.s:15 Can't open m8def.inc for reading: Datei nicht
gefunden.
m8_Grundgeruest.s:45 Fehler: unknown pseudo-op: `.def'
m8_Grundgeruest.s:55 Fehler: symbol `main' is already defined
m8_Grundgeruest.s:59 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
Erwarte Register ab: 15
m8_Grundgeruest.s:60 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:62 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
Erwarte Register ab: 15
m8_Grundgeruest.s:63 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:65 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
Erwarte Register ab: 15
m8_Grundgeruest.s:66 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:68 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
Erwarte Register ab: 15
m8_Grundgeruest.s:69 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:76 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:77 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:81 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:82 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:86 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:87 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:91 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
m8_Grundgeruest.s:92 Fehler: ein konstanter Wert wird erwartet:
Kontrollieren Sie bitte die Schreibweise dieser Zeile.
Ende.
was kann das sein
Jochen wrote:
> also so hab ich es jetzt zusammengefügt
Du vermischt 2 verschiedene Assembler.
Das kann nicht gut gehen.
Entweder du benutzt den Assmebler, der mit deinem
MyAVRBord mitgekommen ist oder du benutzt den Assembler
den man bei Atmel über das AVR-Studio bekommt.
Aber beides zusammen geht nicht ( = auch wenn beides
'Assembler' heist, so sind es doch verschiedene Sprachen)
Mit deinen ".org" befehlen sagst, du dem Assembler, dass er ab dieser
Speicherstelle anfangen soll in den Programmspeicher zu schreiben.
Standartmäßig fängt er bei 0x0000 an.
Wenn du dein Programm also wie folgt anfängst:
1
;Reset and Interrupt vector ;VNr. Beschreibung
2
rjmp main ;1 POWER ON RESET
3
reti ;2 Int0-Interrupt
4
reti ;3 Int1-Interrupt
5
reti ;4 TC2 Compare Match
6
reti ;5 TC2 Overflow
7
.
8
.
9
.
Brauchst du die .org direktiven nicht mehr zu machen... Das ist daselbe.
Schreib bei den Interruptvektoren die du brauchst, statt einem reti den
Sprungbefehl zu deinen ISR's rein. Und diese dann mit reti beenden. Die
.org's kannst du dann rausnehmen
ich hab jetzt
.def temp = r16
.org 0x000
rjmp main ; Reset Handler
.org INT0addr
rjmp int0_handler ; IRQ0 Handler
.org INT1addr
rjmp int1_handler ; IRQ1 Handler
main: ; hier beginnt das Hauptprogramm
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, 0x00
out DDRD, temp
ldi temp, 0xFF
out DDRB, temp
ldi temp, 0b00001010 ; INT0 und INT1 konfigurieren
out MCUCR, temp
ldi temp, 0b11000000 ; INT0 und INT1 aktivieren
out GICR, temp
sei ; Interrupts allgemein aktivieren
loop: rjmp loop ; eine leere Endlosschleife
int0_handler:
push temp ; Das SREG in temp sichern. Vorher
in temp, SREG ; muss natürlich temp gesichert werden
sbi PORTB, 0
out SREG, temp ; Die Register SREG und temp wieder
pop temp ; herstellen
reti
int1_handler:
push temp ; Das SREG in temp sichern. Vorher
in temp, SREG ; muss natürlich temp gesichert werden
cbi PORTB, 0
out SREG, temp ; Die Register SREG und temp wieder
pop temp ; herstellen
reti
in das AVR Studio geschrieben und erhalte noch die Meldungen
error: Use of undefined or forwar referenced symbol INT0addr in .org
error: Overlap in .cseg addr=0x conflicts with 0x0:0x1
error: Use of undefined or forwar referenced symbol INT0addr in .org
error: Overlap in .cseg addr=0x conflicts with 0x0:0x1
Assembly failed, 4 errors