Hallo zusammen.
Ich bin gerade dabei einen xmega16A4 zu programmieren. Nun bin ich
allerdings auf ein Problem gestoßen, für dass ihr (hoffentlich) eine
Lösung wisst.
Ich habe mal ein sehr abgespecktes Miniaturbeispiel angehängt. In diesem
Bsp möchte ich einfach "nur" in einer Timerinterrupt-Routine alle 6,25µs
(160kHz) eine Variable hoch zählen lassen. Funktioniert alles wies soll.
Bei Messung der Zeiten sehe ich aber, dass für Sicherung der
Rücksprungadresse genau soviel Zeit eingenommen wird, wie der
eigentliche Interrupt selbst (beim zurück laden das gleiche). Wenn ich
in meiner Interrupt-Routine nun noch mehr verarbeiten will, reicht meine
Zykluszeit von 6,25µ nicht aus, da jeweils 1µs zum Sichern (push) und
Rücksichern (pop) der Register "vergeudet" werden. Habe den
Assembler-Code für den Interrupt nochmal eingefügt.
Kann das irgendwie geschickter gelöst werden?
1 | ISR(TCC0_OVF_vect){
|
2 | 226: 1f 92 push r1
|
3 | 228: 0f 92 push r0
|
4 | 22a: 0f b6 in r0, 0x3f ; 63
|
5 | 22c: 0f 92 push r0
|
6 | 22e: 11 24 eor r1, r1
|
7 | 230: 8f 93 push r24
|
8 | 232: 9f 93 push r25
|
9 | 234: ef 93 push r30
|
10 | 236: ff 93 push r31
|
11 | PORTE.OUTSET = 0x01;
|
12 | 238: e0 e8 ldi r30, 0x80 ; 128
|
13 | 23a: f6 e0 ldi r31, 0x06 ; 6
|
14 | 23c: 81 e0 ldi r24, 0x01 ; 1
|
15 | 23e: 85 83 std Z+5, r24 ; 0x05
|
16 |
|
17 | // Zählt von 0 bis 31
|
18 | ui8_signal_counter++;
|
19 | 240: 90 91 02 20 lds r25, 0x2002
|
20 | 244: 9f 5f subi r25, 0xFF ; 255
|
21 | ui8_signal_counter &= 0x0F;
|
22 | 246: 9f 70 andi r25, 0x0F ; 15
|
23 | 248: 90 93 02 20 sts 0x2002, r25
|
24 |
|
25 | PORTE.OUTCLR = 0x01;
|
26 | 24c: 86 83 std Z+6, r24 ; 0x06
|
27 | }
|
28 | 24e: ff 91 pop r31
|
29 | 250: ef 91 pop r30
|
30 | 252: 9f 91 pop r25
|
31 | 254: 8f 91 pop r24
|
32 | 256: 0f 90 pop r0
|
33 | 258: 0f be out 0x3f, r0 ; 63
|
34 | 25a: 0f 90 pop r0
|
35 | 25c: 1f 90 pop r1
|
36 | 25e: 18 95 reti
|