wollte mal fragen ob es eine Möglichkeit gibt Assembler Code Stücke in der IDE zuverwenden. Zur Zeit gelingt mir das nicht. Auch in Atmel Studio und dem Micro Plugin gehts nicht. Klappt nur wenn man in Atmel Studio ein neues Projekt als Assembler startet. Jetzt frage ich mich gerade, kann man C und Assembler überhaupt im gleichen Code mischen?
wenn ich nicht die falschen Codezeilen herausgefischt habe, soll das
.org OC1Aaddr
in isr_SREG,SREG
in isr_tmp,outPORT
subi isr_tmp,incrmnt ; synchr. pos. Flanke
out outPORT,isr_tmp
out SREG,isr_SREG
reti
den bisherigen Interrupt Handler ersetzen
ISR(TIMER1_COMPA_vect) { // Timer 1 Interrupt
// erzeugt ein Rechtecksignal an mehreren Pins eines Port
byte temp = OUTPORT;
temp += INCRMNT;
OUTPORT = temp;
}
das compilieren scheitert aber schon am dem Punkt von .org OC1Aaddr,
die Semikolons stören dann auch usw.
Es handelt sich zwar immer noch um den Timer Thread, aber nicht direkt um den Timer, dass ist geklärt. Der Assemblercode spart paar CPU Takte, was sich massiv auf die max. Taktfrequenz auswirkt.
ich habe den Interrupt Handler "ausgelagert" in eine .h Datei und binde diese mit #include "Assembler.h" ein.
enthält:
// das soll ISR(TIMER1_COMPA_vect) { ersetzen
.org OC1Aaddr
in isr_SREG,SREG
in isr_tmp,outPORT
subi isr_tmp,incrmnt ; synchr. pos. Flanke
out outPORT,isr_tmp
out SREG,isr_SREG
reti
Fehlermeldung beim compilieren:
In file included from Timer1_Frequenzgenerator_010_asm.ino:22:
Assembler.h:2: error: expected unqualified-id before '.' token
Assembler.h:5: error: expected constructor, destructor, or type conversion before '.' token
Der gleiche Fehler wie vorher. Ist der Code falsch?
Die Arduino IDE ist doch sowieso viel zu schwach. Wenn Du eh schon an Assembler ran gehst, dann nimm doch AVR Studio oder ein make oder sconstruct File. Dann geht das problemlos. Man kann die Arduino Libraries auch ohne IDE einbinden.
mit inline Assembler komme ich nicht klar. Immer wieder wird der punkt angemeckert.
Egal ob .org oder .def
Ich versuche es jetzt mal im Atmel Studio.
Oder ich verwechsel noch grundlegende Dinge. So einfach wie ich dachte ist das nicht.
um meinen Nebel etwas zu lichten. Egal ob IDE oder Amtel Studio. Ich benötige immer die .h und .s Datei? Richtig?
Das rot markierte ist doch das gleiche wie ISR(TIMER1_COMPA_vect) {
oder nicht? Nicht das ich einen kompletten Irrtum unterliege.
.org OC1Aaddr
in isr_SREG,SREG
in isr_tmp,outPORT
subi isr_tmp,incrmnt ; synchr. pos. Flanke
out outPORT,isr_tmp
Wenn OC1Aaddr ein Ort in der Interrupttabelle ist, dann darf darauf kein Code folgen, außer einem rjmp zu deiner ISR.
Auch scheint mir dein ganzes Verfahren nur brauchbar, wenn ALLES in Assembler geschrieben wird. Denn Arduino kümmert sich selber um den Aufbau der Tabelle.
alles in Assembler möchte ich nun nicht, da müßte man komplett umdenken und lebt nur noch in Bits und Bytes.
Hatte mal gelesen das es durchaus überlich wäre sein Programm in C zu schreiben und nur wenn es wirklich zeitkritisch wird den Teil in Assembler. Das wäre bei mir nun der Fall.
Oder findest Du Assembler einfacher als C? Ganz ehrlich.
Habe übrigens rausgefunden wo man das alles nachschauen kann, wenn man Atmel Studio installiert hat.
Auf meinem Rechner der Pfad:
C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR Assembler\Native\2.1.1175\avrassembler
supported-devices.xml mit Notepad++ öffnen, kann man nachschauen wie die Definitionsdatei für seinen µC lautet.
Im Ordner include stehen dann alle Definitionsdateien, passende auch mit Notepad++ öffnen und dann sieht man alle Adressen mit zugehörigen Namen des µC.
Was bedeutet Zeitkritisch? Wurde von Jurs glaube ich bereits angedeutet, wenn es wirklich kritisch wird, solltest du auf avr-gcc umdenken ohne die Arduino-komfort-Routinen. Komfort braucht seine Zeit.
ich muß doch nicht den gesamten Code ändern nur weil ich einen Interrupt Handler in Assembler habe möchte.
Inline Assembler würde ich gern bevorzugen, habs aber noch nicht hinbekommen. Vielleicht hat ja jemand eine Idee. Hab den restlichen Tag heute meine Leiterplatte gelötet bis jetzt.
Ich zeig nochmal den gesamten Code wovon ich nur den Interrupt Handler benötige.
[color=#557799].include[/color] [color=#bb4444][b]"m2560def.inc"[/b][/color]
[color=#557799].equ[/color] outDDR = DDRC [color=#888888]; Ausgabe auf PORT C [/color]
[color=#888888]; ================================[/color]
[color=#557799].equ[/color] outPORT = PORTC
[color=#557799].equ[/color] outMASK = [color=#0000dd][b]0b11100000[/b][/color] [color=#888888]; ==> incrmnt[/color]
[color=#557799].equ[/color] incrmnt = [color=#0000dd][b]0b00100000[/b][/color] [color=#888888]; ==> C5: f, C6: f/2, C7: f/4[/color]
[color=#557799].equ[/color] OCR1 = [color=#0000dd][b]50[/b][/color] [color=#888888]; ==> f = f_CPU/100, Beispiel fuer c[/color]
[color=#888888]; asm erlaubt 14, bei f_CPU= 16 MHz also f= 571429 Hz[/color]
[color=#557799].def[/color] isr_SREG = [color=#003388][b]r2[/b][/color]
[color=#557799].def[/color] isr_tmp = [color=#003388][b]r16[/b][/color]
[color=#557799].def[/color] tmp0 = [color=#003388][b]r17[/b][/color]
[color=#557799].org[/color] [color=#0000dd][b]0[/b][/color]
rjmp reset
[color=#557799].org[/color] OC1Aaddr
[color=#888888]; optimierte Routine[/color]
in isr_SREG,SREG
in isr_tmp,outPORT
subi isr_tmp,incrmnt [color=#888888]; synchr. pos. Flanke[/color]
out outPORT,isr_tmp
out SREG,isr_SREG
reti
[color=#997700][b]reset:[/b][/color]
ldi tmp0,outMASK
out outDDR,tmp0
ldi tmp0,high(OCR1-[color=#0000dd][b]1[/b][/color])
sts OCR1AH,tmp0
ldi tmp0,low(OCR1-[color=#0000dd][b]1[/b][/color])
sts OCR1AL,tmp0
ldi tmp0,([color=#0000dd][b]1[/b][/color]<<CS10)+([color=#0000dd][b]1[/b][/color]<<WGM12) [color=#888888]; f_CPU/1, CTC auf OCR1A[/color]
sts TCCR1B,tmp0
ldi tmp0,([color=#0000dd][b]1[/b][/color]<<OCIE1A)
sts TIMSK1,tmp0
sei
[color=#997700][b]main_loop:[/b][/color]
rjmp main_loop
Doc_Arduino:
Inline Assembler würde ich gern bevorzugen, habs aber noch nicht hinbekommen.
Schreib die ISR wie in C/C++ und mach dann darin inline Assembler. Der Compiler macht dann vielleicht ein paar mal push/pop. Sieht man dann beim Disassemblieren.