Arduino Mega 2560 R3 Grundlagen in Assembler Programmieren benötige Hilfe

Stony

User
Bin dran... grad noch ne dll wieder hin gebastelt und jetzt weint des scheiß teil wegen Fehler 0x00007b Gott mich bricht so ein Windows Rechner echt voll....
Wenigstens der Mac zum hier schreiben läuft einfach wie er soll:) naja wir werden sehen. Wenn es noch länger dauert und das Bier weiter so schmeckt wird es eng mit Zielgerichtetem Arbeiten :D
 

Stony

User
Also ich hab jetzt alle Tipps zu dem Fehler durch aber es geht nix!!! Beim Ausführen kommt "Die Anwendung konnte nicht korrekt gestartet werden (0xc000007b)." Alles was ich dazu gefunden habe hat nix gebracht... Jemand ne Idee?
 
Hi,

mit der ini läuft der Timer, das werden aber keine Servoimpulse, aber ne Basis zum Spielen.

ldi temp,0b10000011
sts TCCR2A,temp

ldi temp,0b00000100
sts TCCR2B,temp

ldi temp,128
sts OCR2A,temp
 

Stony

User
Wie gesagt das is ne Übung aus der schule die ich in erster Linie angepasst habe da wir dort einen Atmega8 nutzen.
Ich wäre ja schon froh wenn irgendwas laufen würde aber gut...
 

Stony

User
Also ich geb es jetzt auf mit dem avrdude ich bekomme meinen Fehler nicht weg... Jetzt warte ich mal auf die Lieferung von AVR und dann geht es hoffentlich...
 
H,

das sieht nach Servoimpuls aus. 16bit Timer sonst geht es garnicht. Hier aber nur mit 122Hz, das ist nicht gut für Analogservos. Und du hast nur 128-255 also 128Schritte. Das geht besser wenn man die Timerhardware und Interupts richtig nutzt... So, jetzt musst Du liefern...

INIT: ldi temp,LOW(RAMEND)
out SPL,temp
ldi temp,HIGH(RAMEND)
out SPH,temp

sbi DDRB,5
ldi temp,0b10000111
sts TCCR1A,temp

ldi temp,0b00000011
sts TCCR1B,temp

loop: ldi temp,196 ; 128-255
sts OCR1AL,temp
rjmp loop
 

Stony

User
Würde ich ja gerne nur bekommen ich den Fehler von Windows nicht weg. Habe heute 3h diese Reparatur Installation mit windows CD gemacht um dann am ende Festzustellen das nicht mal das geht! ich bin bedient...
 

wkrug

User
Mit dem AVR Studio 6.x geht der AVR ISP MK II Programmer direkt per ISP zu Programmieren ohne AVR Dude.

Ob das mit einem kompatiblen, oder dem Diamex Teil geht weiß ich leider nicht.

Üblicherweise werden die Controller mit interner Taktquelle 8MHz und dem Teiler /8 ausgeliefert.
Das bedeutet der Controller läuft mit 1MHz.
Die maximale Programierfrequenz darf aber nur 25% der Prozessorfrequenz betragen.

Das bedeutet die Programmierfrequenz muß anfangs auf 250kHz zurück gestellt werden.

Ich überprüf das immer mit dem Auslesen der Controllerkennung.
Wenn das fehlerfrei funktioniert, lässt sich der Chip üblicherweise auch Programmieren.

Solche Servoimpuls Geschichten mach ich üblicherweise mit Comparematch Interrupts.

Ein 16 Bit Timer wird mit einem Prescaler von 8 eingestellt.
Das zugehörige Comparematch Register auf die gewünschte Pausenlänge.
Wird der Comparematch dann ausgelöst wird zum aktuellen Stand des Comparematch Registers die gewünschte Impulslänge dazuaddiert und wieder ins Comparematch Register geschrieben.
Nun noch den gewünschten Servoimpulspin nach high schalten.

Beim nächsten Comparematch Interrupt zum aktuellen Comparematch Wert die gewünschte Pause dazuaddieren - Wieder ins Comparematch zurückschreiben und den Servoimpulspin wieder nach low schalten.

Dadurch läuft die Servoimpulsgenerierung komplett im Comparematch Interrupt ab.
Im Hauptprogramm braucht man also nur die Werte für gewünschte Servoipulslänge in einem Speicherplatz ( evtl. Register ) abzulegen, wo ihn sich die Interruptroutine dann abholt.
Beim setzen dieses Wertes, sollte man die Interrupts mit CLI abschalten, weil ein Interrupt ja just genau dann auftreten könnte während man den ersten Wert geschrieben hat, aber den 2ten noch nicht.

Ein weiterer Vorteil dieser Methode ist, das man die Servoimpulsgenerierung bis zu 10 Ausgängen erweitern kann.
Nutzt man beide Comparematch Interrupts gingen auch 20, oder 10 Servos mit verkürzter Pausenzeit von 10ms.
Analogservos laufen aber üblicherweise mit einer Impulspause von 20ms.


Man müsste das Ganze auch rein in Hardware laufen lassen können, wenn man den Timer nach erreichen eines Zyklus mittels CTC ( Clear Timer at Comparematch ) zurücksetzt.
Mit einem 16Bit Timer und zwei Comparematch Registern OCR1A / OCR1B könnte das auch rein in Hardware laufen.
OCR1A bestimmt die Zykluslänge ( 22ms ), OCR1B die Impulslänge ( 1-2ms ). Ich bin mir jetzt allerdings nicht sicher, ob der CTC nur auf ein Comparematch reagiert, oder auf beide.

Bei einem Controllertakt von 8MHz und einem Prescaler von 8 hat man eine Auflösung von 1µs des Timers. Ein Wert von 1000 entspricht also 1ms.
Bei 16MHz natürlich nur 0,5ms.
Ein Weiteres ist, den Prescaler richtig zu wählen.
8MHz und ein Prescaler von 1 würden bei einer Zykluszeit von 22ms einen Wert von 176000 ergeben.
Da der Timer aber bei 65635 überläuft wäre das kontraproduktiv.
Zu hohe Prescaler Werte verschlechtern aber die Auflösung des Servoimpulses.

Beim schreiben der 16 Bit Timer Register musst Du auch aufpassen. Das muss in einer bestimmten Reihenfolge geschehen - siehe Datenblatt.

Noch was - Je nach Größe des Speicherplatzes kann man in der Interrupt Vektortabelle nicht mehr den Befehl rjmp verwenden, sondern muß auf den Befehl jmp ausweichen - Auch das steht im Datenblatt des entsprechenden Controllers bei Interrupt Vectors.

Um diese ganzen Feinheiten brauchst Du dich bei "C" nicht mehr zu kümmern, das macht der Compiler.
Darum und weil es den Code gegenüber Assembler nicht viel langsamer macht ist "C" so beliebt.
 

Stony

User
Hallo na so weit wenn ich schon wäre:) Was mich ganz zuversichtlich stimmt das meiste was du geschrieben hast versteh ich sogar:) C hab ich hingeschmissen... habe es aber damit probiert dann geht alles wie es soll und es ist super einfach. Leider gehen wir in der Schule einen anderen weg so das ich mich da nicht drücken kann. Leider is die ganze PC Geschichte für mich schon ein Buch mit Sieben siegeln. (darum benutze ich eigentlich nur mac Produkte) Die sind von Idolen für Idioten. Also genau das richtige für mich. Ich hoffe das ich mit der ISP Geschichte dann zum Ziel kommen. Ich habe mir das mit dem Servo nur überlegt um irgendeinen Anreiz zu haben mich damit zu beschäftigen. Werde mir das dann nochmal anschauen. Das von mir vergewaltigte Programm war für ne LED wie man damit halt so anfängt:)
 
Hi,

Wkrug hat in allen Punkten Recht. Ich benutze übrigens einen China-MKII. Problem des ISP ist, dass ein Anfänger mit hoher Sicherheit einen Prozessor beim Setzen der Fuse killt. Beim Arduino Mega muss zumindest Bootrst gelöscht werden. Passiert hier eine Fehler wird das teuer...

Die Arduino-Variante ist meiner Meinung nach für Einsteiger sicherer. ASM lernen zu wollen weil C zu schwierig ist halte ich für fraglich. Aber da muss jeder seine eigenen Erfahrungen machen. Achso, evtl ist .Net beschädigt. einfach mal neu installieren.

Viel Spaß.
 

Stony

User
Ich habe mich jetzt unabhängig von meinem vorhaben mal mit den Aufgaben Beschäftigt die wir zur Vorbereitung bekommen haben. Selbst da komme ich an meine grenzen obwohl ich der Meinung war das zu verstehen... Könnte mir da ggf. jemand auf die Sprünge helfen. Ich hock seit heute morgen um 8.30 an 2 Aufgaben und bin am Verzweifeln.... Irgendwie steh ich mir da grad selber im weg glaub ich.

Zur Aufgabenstellung:

Der Timer/Counter0 ist für CTC mit Interrupt bei Compare Match einzustellen. Wenn der dritte Zählschritt erstmalig erreicht worden ist, ist der Zähler auszuschalten.

(Ich denke jetzt wird euch klar warum ich mich so anstelle wenn schon das ein Problem darstellt)

Mein Problem ist das ich zwar das Register zurückgesetzt bekomme jedoch nirgendwo eine abzweig finde um das alles zu beenden.
Da in der Aufgabe nicht steht was der Zählschritt sein soll habe ich mir das einfach so zurecht gebastelt da kann ich alles gut überwachen.


Was ich dazu auf "Papier" gebracht haben...

.include "m32def.inc"

.DEF temp = r16

.CSEG

.ORG 0x0000 //Reset
rjmp INIT
.ORG 0x0002 //EXT_INT0
reti
.ORG 0x0004 //EXT_INT1
reti
.ORG 0x0006 //EXT_INT2
reti
.ORG 0x0008 //TC2_CTC
reti
.ORG 0x000A //TC2_Overflow
reti
.ORG 0x000C //TC1_Capture Event
reti
.ORG 0x000E //TC1_CTC_A
reti
.ORG 0x0010 //TC1_CTC_B
reti
.ORG 0x0012 //TC1_Overflow
reti
.ORG 0x0014 //TC0_CTC
rjmp AUS
.ORG 0x0016 //TC0_Overflow
reti
.ORG 0x0018 //Serielle Übertragung fertig
reti
.ORG 0x001A //USART_Rx fertig
reti
.ORG 0x001C //USART_Datenregister leer
reti
.ORG 0x001E //USART_Tx fertig
reti
.ORG 0x0020 //ADC-Wandlung fertig
reti
.ORG 0x0022 //EPROM bereit
reti
.ORG 0x0024 //Analog Comparator
reti
.ORG 0x0026 //TWI
reti
.ORG 0x0028 //Programmspeicher voll
reti



INIT:
ldi temp,LOW(RAMEND)
out SPL,temp
ldi temp,HIGH(RAMEND)
out SPH,temp

//Eingang soll PB0 sein, durch Pegel von z.B. Lichtschranke, keine Pull-up!
cbi DDRB,0 //PB0 = Eingang
ldi temp,0b00001110
out TCCR0,temp //CTC-Modus = EIN
ldi temp, 2 // dann wird 3. fallende Flanke Zaehler

// auf Null stellen
out OCR0,temp //Vorwahlwert in vorgesehenes Register
ldi temp,0b00000010
out TIMSK,temp //Interrupt bei Erreichen des Vorwahlwertes

sei //globales Freischalten aller Interrupts = Controller beachtet Interrupts


loop:
rjmp loop



AUS:
ldi temp,0b00000000
out TCCR0,temp


.EXIT
 

Stony

User
Also mein Ursprungs Programm habe ich jetzt übertragen bekommen (über ISP) jedoch kommen mir so meine Zweifel ob das geklappt hat. Kann ich den Kerl irgendwie Löschen? Ich habe dummerweise nicht Probiert ob da was drauf war oder nicht. Ich habe mit ner LED an PIN 10 (https://www.arduinoforum.de/attachment.php?aid=1310) ein Blinken das aber nix mit dem PWM zu tun hat. Dann habe ich mich versteckt beim nachschauen ist mir aufgefallen das an PIN 11-12-13 ebenfalls was ankommt mit einer anderen Frequenz bei 12 und 13. bin etwas Ratlos... PS Sorry wegen der Verwirrung aber ich habe zwischenzeitlich halt was anderes gemacht :)
Hoffe ihr habt trotzdem noch Bock mir ein wenig zu helfen.
 

Stony

User
Nochmal etwas gebastelt. Jetzt habe ich ein Dauerleuchten an PIN4 = PG5 aber warum versteh ich grad ned.

Hier mal zum Update

.include "m2560def.inc"

.DEF temp = r16

.CSEG

.ORG 0x0000 //Reset
rjmp INIT
.ORG 0x0002 //EXT_INT0
reti
.ORG 0x0004 //EXT_INT1
reti
.ORG 0x0006 //EXT_INT2
reti
.ORG 0x0008 //TC2_CTC
reti
.ORG 0x000A //TC2_Overflow
reti
.ORG 0x000C //TC1_Capture Event
reti
.ORG 0x000E //TC1_CTC_A
reti
.ORG 0x0010 //TC1_CTC_B
reti
.ORG 0x0012 //TC1_Overflow
reti
.ORG 0x0014 //TC0_CTC
reti
.ORG 0x0016 //TC0_Overflow
reti
.ORG 0x0018 //Serielle Übertragung fertig
reti
.ORG 0x001A //USART_Rx fertig
reti
.ORG 0x001C //USART_Datenregister leer
reti
.ORG 0x001E //USART_Tx fertig
reti
.ORG 0x0020 //ADC-Wandlung fertig
reti
.ORG 0x0022 //EPROM bereit
reti
.ORG 0x0024 //Analog Comparator
reti
.ORG 0x0026 //TWI
reti
.ORG 0x0028 //Programmspeicher voll
reti



INIT: ldi temp,LOW(RAMEND)
out SPL,temp
ldi temp,HIGH(RAMEND)
out SPH,temp

sbi DDRG,5 //Ausgang für PWM = OC2/ bei Atmega8 = PB3/ Atmega 2560 PB4

ldi temp,0b00001100
//Bits 0 bis 2 = Taktteiler 256
//Bits 3 und 6 = Fast PWM
//Bits 4 und 5 = nichtinvertierend
out TCCR0B,temp

loop: ldi temp,64
out PB5,temp //Vorwahl für 25% Pin PB4 auf High
rcall W1S
ldi temp,128
out PB5,temp
rcall W1S
ldi temp,192
out PB5,temp
rcall W1S
ldi temp,255
out PB5,temp
rcall W1S
ldi temp,0
out PB5,temp
rcall W1S
rjmp loop

.include "LIB/Zeitasm.asm"

.EXIT
 
Ansicht hell / dunkel umschalten
Oben Unten