Hallo allerseits,
habe gerade folgendes Problem: In einer Interrupt-Routine (Timer) soll
ein 8bit-Wert aus einem Array an einen Port ausgegeben werden. Es gibt
eine globale Variable, die die aktuelle Position im Array markiert,
diese wird in der Timer-Routine inkrementiert. Stellt euch das ganze als
eine Art Spieluhr vor, das Array ist die Programmwalze.
Hier ist der C-Code, der auch funktioniert:
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
PortA = program[pos];
pos++;
if (pos > prog_len) pos = 0;
}
Das Problem ist nur, daß die maximal geforderte Taktfrequenz nicht
erreicht wird, weil der vom AVR-GCC erzeugte Code doch recht lang ist.
In Assembler wären das weniger als 10 Byte.
Allerdings möchte ich nicht das ganze Programm in Assembler schreiben,
weil es auch einige floating-point-Berechnungen in der Anwendung gibt.
Deshalb nun meine Frage: Kann ich eine ISR auch in Inline-Assembler
schreiben? Wenn ja, wie spreche ich das Array an? Wie finde ich die
Startadresse? Wie bekomme ich den Index in das Z-Register? Wie teile ich
"C" mit, welche Register ich verwurschtelt habe? Muß ich die selber auf
den Stack schieben oder macht der Compiler das selbst?
Ich habe zwar im Netz ein Tutorial gefunden, aber das ist so kryptisch,
daß ich nach einer Weile aufgegeben habe. Vielleicht kann mich einer mal
in die richtige Richtung stoßen, so daß es "klick" macht.
Danke!!!
Ok... Hat 3 Minuten gedauert, bis ich das verstanden habe, aber macht
Sinn! Ich probiere das nach Feierabend mal aus und melde mich dann
wieder!
Danke schonmal!
Der Hauptvorteil den ich mir verspreche liegt darin,
dass ich die Arrayindizierung aus der ISR raus kriege.
So gehts noch einen Tick schneller
Achte auf die Deklaration von 'last'. Da ist jetzt noch
ein const mit drinnen.
1
#include<avr/io.h>
2
#include<avr/signal.h>
3
4
#define prog_len 20
5
uint8_tprogram[prog_len];
6
7
uint8_t*pos;
8
uint8_t*constlast=program+prog_len;
9
10
SIGNAL(SIG_OUTPUT_COMPARE1A)
11
{
12
PORTA=*pos++;
13
if(pos>last)
14
pos=program;
15
}
16
17
intmain()
18
{
19
pos=program;
20
// last = pos + prog_len;
21
}
1
SIGNAL(SIG_OUTPUT_COMPARE1A)
2
{
3
8e:1f92pushr1
4
90:0f92pushr0
5
92:0fb6inr0,0x3f;63
6
94:0f92pushr0
7
96:1124eorr1,r1
8
98:8f93pushr24
9
9a:9f93pushr25
10
9c:ef93pushr30
11
9e:ff93pushr31
12
PORTA=*pos++;
13
a0:e0917600ldsr30,0x0076
14
a4:f0917700ldsr31,0x0077
15
a8:8191ldr24,Z+
16
aa:f0937700sts0x0077,r31
17
ae:e0937600sts0x0076,r30
18
b2:8bbbout0x1b,r24;27
19
if(pos>last)
20
b4:e657subir30,0x76;118
21
b6:f040sbcir31,0x00;0
22
b8:39f0breq.+14;0xc8<__vector_6+0x3a>
23
ba:30f0brcs.+12;0xc8<__vector_6+0x3a>
24
pos=program;
25
bc:82e6ldir24,0x62;98
26
be:90e0ldir25,0x00;0
27
c0:90937700sts0x0077,r25
28
c4:80937600sts0x0076,r24
29
c8:ff91popr31
30
ca:ef91popr30
31
cc:9f91popr25
32
ce:8f91popr24
33
d0:0f90popr0
34
d2:0fbeout0x3f,r0;63
35
d4:0f90popr0
36
d6:1f90popr1
37
d8:1895reti
Ein Register, R25, hätte er noch einsparen können, wenn ich
das richtig sehe. Aber sonst sehe ich nicht mehr viel
was überflüssig wäre.
Wie lauten eigentlich die Forumskürzel für Assemblercode?
Also das Äquivalent zu [ C ] [ /C ]
Martin Meyer wrote:
> Deshalb nun meine Frage: Kann ich eine ISR auch in Inline-Assembler> schreiben?
Ja, aber ich würde es dann eher gleich komplett in Assembler
schreiben.
Siehe auch http://avr-libc.nongnu.org/user-manual/group__asmdemo.html> Wenn ja, wie spreche ich das Array an?
Ist ein globaler Name.
> Wie finde ich die> Startadresse?
Der Name ist die Startadresse.
> Wie bekomme ich den Index in das Z-Register?
Mit MOV?
> Wie teile ich> "C" mit, welche Register ich verwurschtelt habe?
Als clobber list.
> Muß ich die selber auf> den Stack schieben oder macht der Compiler das selbst?
Um die clobbers kümmert sich der Compiler.
> Ich habe zwar im Netz ein Tutorial gefunden, aber das ist so kryptisch,> daß ich nach einer Weile aufgegeben habe.
Inline-Assembler ist auf Grund der vielen Möglichkeiten kryptisch.
Daher ja auch mein Rat, es wenn schon dann gleich separat als
Assemblerquelle zu schreiben.
Recht herzlichen Dank für alle Eure Hilfen!
Dieses Forum ist wirklich toll, besonders wenn man merkt, daß wirkliche
Profis sich die Zeit nehmen, einem Anfänger zu helfen.
Mit einer "anderen Formulierung" in C nach Karl-Heinz bin ich nun in der
Lage, die nötige Taktfrequenz auch ohne Assembler zu erreichen. Damit
kann ich mich dann mal in Ruhe beschäftigen, wenn ich Zeit habe ;)
Karl heinz Buchegger wrote:
> Wie lauten eigentlich die Forumskürzel für Assemblercode?> Also das Äquivalent zu [ C ] [ /C ]
[ avrasm ]
...
[ /avrasm ]