-
Timer!
Hallo!
Also ich hab hier nen code geschrieben und weiß nicht mehr weiter!
Dass problem: Ich will, dass es bei der erstn IRQ auf "one" springt und bei der zweiten IRQ auf "two". Dass schaff ich ja! aber wie springt er gleichzeitig zuerst auf "one" dann auf "two"?
Ich weiß nicht wie ich es richtig beschreiben soll bitte helft mir!
Der CODE:
Code:
.include <m8535def.inc>
;
; PA0 = ADC0
; PA1 = ADC1
; PA2 = ADC2
; PA3 = ADC3
; PA4 = ADC4
; PA5 = ADC5
; PA6 = ADC6
; PA7 = ADC7
;
; PB0 = T0/XCK
; PB1 = T1
; PB2 = AIN0/INT2
; PB3 = AIN1/OC0
; PB4 = SS (SPI Slave select input)
; PB5 = MOSI
; PB6 = MISO
; PB7 = SCK
;
; PC0 = SCL
; PC1 = SDA
; PC2 = I/O
; PC3 = I/O
; PC4 = I/O
; PC5 = I/O
; PC6 = TOSC1
; PC7 = TOSC2
;
; PD0 = RXD
; PD1 = TXD
; PD2 = INT0
; PD3 = INT1
; PD4 = OC1B
; PD5 = OC1A
; PD6 = ICP1
; PD7 = OC2
.org 0x0000
rjmp Reset
.org OC0addr
rjmp OCR
Reset:
;Stackpointer initialisieren
ldi R16, HIGH(RAMEND)
out SPH, R16
ldi R16, LOW(RAMEND)
out SPL, R16
;Timer_Counter_0 initialisieren
ldi R16, (1<<CS00) | (1<<WGM01)
out TCCR0, R16
ldi R16, 25
out OCR0, R16
ldi R16, (1<<OCIE0)
out TIMSK, R16
sei
clr R16
loop:
rjmp loop
OCR:
inc R16
cpi R16, 1
breq one
reti
one:
reti
two:
reti
Code tags ! (Picnick)
MFG
Exodus
-
Die Wörter "gleichzeitig" und "zuerst" beissen sich irgendwie.
was soll er denn z.B. beim 3. oder 4. Interrupt machen ?
-
Ja ich weiß etwas komisch geschrieben! Hm.. So ok der programmablauf:
Beim ersten Interrupt soll er zu one springen
beim zweiten soll er zu one dann zu two springen
Bei two is dann die doppelte Zeit
Ich will damit bezwecken, dass ich mehrere anwendungen hintereinanderlaufen lassen will! also z.b.: PA0-PA7 soll schneller laufen als PB0-PB7! PA = one, PB = two
so ungefähr verstanden??
MFG
Exodus
-
Ok jetzt hab ich die genauere beschreibung glaub ich! :-)
1.) Stack wird eingestellt
2.) Timer wird auf 25ms eingestellt
3.) Bei Interrupt von Timer soll er bei 25ms nach one springen
4.) Bei interrupt Nr.2 von Timer soller bei 50ms nach one springen und dann zu two. Damit will ich bezwecken dass, was in one steht immer bei 25ms geschehen soll und dass bei two soll erst immer nach 50 ms geschehen!
Ich glaub dass war eine bessere Beschreibung als vorher!
Ahja 25ms ist nur ein herausgegriffener wert! Je nachdem wie man den Timer einstellt!
MFG
Exodus
-
Ich glaub ich hab irgendeinen Denkfehler oder?
-
Also, wenn er bei jedem Interrupt "one" machen soll, aber nur bei jedem zweiten auch "two"
Code:
OCR:
inc R16
sbrs R16, 0 // wenn das Bit 0 gesetzt ist ,
rcall two // überspringt er das da
rjmp one // das aber immer
one:
reti
two:
reti
ist eine Möglichkeit
so nimmt er "two" nur bei geraden zahlen
-
Ok so gehts! So jetz muss ich noch probieren, wenn ich three four five usw. habe! Hast du irgendeine lösung?
MFG
Exodus
-
Nun, ganz allgemein isses einfacher, für jeden "task" einen eigenen Zähler zu haben. sagen wir mal,
R16 für "one"
R15 für "two"
R14 für "three"
.... usw..
Also: der Timer tickert in der kleinsten Einheit
Code:
OCR:
ck_1: Prüfung f. routine-1
dec r16 eins abziehen
brne ck_2 is null ? nö, zum nächsten check
ldi r16, Zähler-1 is null, also Zähler wieder nachladen
rcall routine-1 routine aufrufen
ck_2: Prüfung f. routine-2
dec r15 eins abziehen
brne ck_3 is null ? nö, zum nächsten check
ldi r15, Zähler-2 is null, also Zähler wieder nachladen
rcall routine-2 routine aufrufen
ck_3: .... usw...
Das ist sozusagen die "Panik"-Lösung, denn irgendwann gehen dir die Register aus, und sie dürften auch nicht ausserhalb verändert werden.
Aber für ein paar routinen kann man das schon noch so machen.
-
wie meinst dürften nicht ausserhalb verändert werden?
MFG
Michi
-
Im restlichen programm dürfen die Zählerregister natürlich nicht verwurstet werden.