Hallo,
ich versuche mich gerade im Simulator an einem ATMega4809, da ich plane,
den Arduino Nano Every für ein Projekt zu verwenden.
Mit den ATMega-Controllern bin ich ganz gut vertraut, aber beim 4809er
schaffe ich es nicht, den externen Interrupt korrekt zu programmieren.
; --- main.asm ---
1
#define Value R16
2
#define Status R17
3
#define HighByte R18
4
#define LowByte R19
5
6
.cseg
7
.org 0x0000 rjmp reset
8
.org 0x000C rjmp setPointAcquisition_Triggered
9
10
reset:
11
ldi HighByte, HIGH(RAMEND)
12
out CPU_SPH, HighByte
13
ldi LowByte, LOW(RAMEND)
14
out CPU_SPL, LowByte
15
16
rcall setPointAcquisition_Initialize
17
18
sei
19
20
main:
21
jmp main
22
23
.include "m4809def.inc"
24
.include "setPointAcquisition.asm"
; --- setPointAcquisition.asm ---
1
.include "m4809def.inc"
2
3
.equ SetPointInputPort = PORTA_PIN0CTRL
4
.equ SetPointInputPin = 0x1
5
6
setPointAcquisition_Initialize:
7
lds Value, SetPointInputPort
8
sbr Value, SetPointInputPin
9
sts SetPointInputPort, Value
10
11
ret
12
13
setPointAcquisition_Triggered:
14
push Value
15
lds Status, CPU_SREG_offset
16
17
sts CPU_SREG_offset, Status
18
pop Value
19
20
reti
Ich möchte PortA0 als externen Interrupt programmieren, um einen
Sollwert zu erfassen (PWM Signal). Wenn ich im Simulator das
entsprechende Pin0 auf HIGH setze, springt der Programmzähler korrekt in
die ISR hinein und der Controller arbeitet diese ab. Nach dem der
Programmzähler die ISR verlassen hat, springt er sofort wieder hinein -
obwohl ich nur auf die Flanken triggere.
Gibt es bei diesem Controller irgendwelche Besonderheiten, was den
externen Interrupt betrifft?
MfG Torsten
Hallo,
du musst das Interrupt Flag zurücksetzen. Das machen die neuen
Controller zu 99,9% nicht mehr automatisch. Also ohne Manual lesen
pauschal selbst zurücksetzen.
Hallo,
habe das mal übersetzt in direkte Register... das funktioniert mit
echten Every Board. Kabelbrücke zwischen PB0 und PD3, dann takten beide
Ausgänge syncron mit "both edges". Solltest du in Assembler übersetzen
können. :-)
1
#include<avr/interrupt.h>
2
#include<util/delay.h>
3
4
// PB0 - Arduino Pin 9
5
// PE2 - Arduino Pin 13
6
// PD3 - Arduino Pin 14
7
8
#define F_CPU 3333333UL
9
10
intmain(void)
11
{
12
VPORTB.DIR&=PIN0_bm;// Input
13
PORTB_PIN0CTRL=0;//
14
PORTB_PIN0CTRL|=PORT_PULLUPEN_bm;//
15
PORTB_PIN0CTRL|=0x01;// Interrupt enabled with sense on both edges
Hallo,
danke dafür, werde es heute Abend mal im Simulator testen.
Noch eine Frage. Lässt sich der Nano Every mit AVR Studio direkt
flashen? Ich arbeite generell nicht mit der Arduino IDE.
MfG Torsten
Veit D. schrieb:> VPORTE.INTFLAGS = PIN0_bm
Besser bei PORTB.
Veit D. schrieb:> VPORTE.IN = PIN2_bm; // toggle Led 13
Das geht zwar so ist aber Obsfucation. Dafür gibt es OUTTGL.
Torsten N. schrieb:> Lässt sich der Nano Every mit AVR Studio direkt> flashen?
Nein, du kannst aber mit AVR Dude arbeiten, dass funktioniert, ist aber
nicht komfortabel. Alternativ, die UPDI Schnittstelle auf dem Board
anlöten/kontaktieren und den Mega4809 direkt ansprechen.
AVR Dude installieren und der Path-Variable zufügen, schauen an welchem
COM-Port sich der Every anmeldet und dann noch den Pfad zum Hex-File
anpassen. Fuses nach bedarf, in diesem Code wird der interne OSC von
16MHz auf 20MHz geschraubt. Achtung, der COM-Port muss 3x geändert
werden, ich habe mich noch nicht damit beschäftigt, eine Art #define
dafür zu machen.
> das habe ich schon versucht, ohne Erolg ... 'cbr ...'
Wie wäre es mit 'ori Value, 0x01'?
Denn: 'Pin interrupt flag n is cleared by writing a ‘1’ to it'.
Korrektur:
'andi Value, ~0x01' ist wohl besser; oder, wenn es dieses (aus meiner
Sicht unglückliche) 'cbr' sein muss: 'cbr Value, ~0x01'.
Wilhelm M. schrieb:> Veit D. schrieb:>> VPORTE.INTFLAGS = PIN0_bm>> Besser bei PORTB.>> Veit D. schrieb:>> VPORTE.IN = PIN2_bm; // toggle Led 13>> Das geht zwar so ist aber Obsfucation. Dafür gibt es OUTTGL.
Kann man machen, VPORTx ist jedoch einen Takt schneller.
Veit D. schrieb:> Hallo,>> @ Torsten, Ingo> Wenn die Kommandozeile für einen passt, kann man diese oder mehrere in> AS/MS eintragen.> Beitrag "Re: UPDI Programmer bauen - alias "El Tangas""> Vorher kompilieren, logisch. :-) :-)
Die neuere, bessere Variante heißt: pymcuprog
https://pypi.org/project/pymcuprog
Wie vorher braucht man für UPDI auch nur einen USB/seriell-Umsetzer
(z.B. CP2102) und eine Diode oder Widerstand.
Veit D. schrieb:> Wilhelm M. schrieb:>> Veit D. schrieb:>>> VPORTE.INTFLAGS = PIN0_bm>>>> Besser bei PORTB.>>>> Veit D. schrieb:>>> VPORTE.IN = PIN2_bm; // toggle Led 13>>>> Das geht zwar so ist aber Obsfucation. Dafür gibt es OUTTGL.>> Kann man machen, VPORTx ist jedoch einen Takt schneller.
Dann nimmt der C-Programmierer eben:
1
#define VPORTE_OUTTGL VPORTE_IN
(und der C++-Programmierer macht es sich beliebig hübsch - und sicher!)
Korrektur der Korrektur:
Die Zeile in der ISR: entweder 'andi Value, 0x01' oder eben 'cbr
Value, ~0x01'.
Was mir sonst auffiel:
- statt '.org 0x000C' hätte ich '.org PORTA_PORT_vect' geschrieben
- das Setzen des Stackpointers ist unnötig: 'Reset: Top of stack'
- die Zuordnung von HighByte und LowByte entspricht nicht dem
AVR-Üblichen, passt evtl. später nicht bei z.B. 'movw'.
S. L. schrieb:>> Es reicht ein:>> sts PORTA_INFLAGS, 0x01>> ?
Ja sorry, dazu ist der AVR zu doof.
Also statt
lds Value, PORTA_INTFLAGS
cbr Value, 0x01
sts PORTA_INTFLAGS, Value
einfach
ldi Value,0x01
out PORTA_INTFLAGS,Value
Die Sequenz des ganz oben lädt alle Flags, löscht dann das 0-te und
schreibt zurück. Damit werden alle gesetzten Flags resettet außer dem
eigentlich gewünschten.
S. L. schrieb:> Nee, 'out' stimmt auch nicht.> ldi Value,0x01> sts PORTA_INFLAGS,Value
Doch, da VPORTA_INTFLAGS die Adresse 0x03 hat.
Ups, sehe gerade, dass ich oben statt VPORTA_INFLAGS PORTA_INTFLAGS
geschrieben habe. Asche auf mein Haupt.
Also nun:
Hallo,
wegen Interrupt Flag zurücksetzen. Nichts von Hand irgendwie
manipulieren. Einfach an die gewünschte Bitposition sturr "1"
reinschreiben. Mehr muss nicht beachtet oder gemacht werden.
1
Bits 7:0 – INT[7:0] Pin Interrupt Flag
2
Pin interrupt flag n is cleared by writing a ‘1’ to it.
3
Pin interrupt flag n is set when the change or state of pin n (Pxn) matches the pin's Input/Sense Configuration (ISC)
4
in PORTx.PINnCTRL.
5
Writing a ‘0’ to bit n in this bit field has no effect.
6
Writing a ‘1’ to bit n in this bit field will clear Pin interrupt flag n.
Wilhelm M. schrieb:> Veit D. schrieb:>> Hallo,>>>> @ Torsten, Ingo>> Wenn die Kommandozeile für einen passt, kann man diese oder mehrere in>> AS/MS eintragen.>> Beitrag "Re: UPDI Programmer bauen - alias "El Tangas"">> Vorher kompilieren, logisch. :-) :-)>> Die neuere, bessere Variante heißt: pymcuprog>> https://pypi.org/project/pymcuprog>> Wie vorher braucht man für UPDI auch nur einen USB/seriell-Umsetzer> (z.B. CP2102) und eine Diode oder Widerstand.
Alles richtig. Es ging mir zu zeigen das man in AS einen eigenen
Menüeintrag erstellen kann um die Kommandozeile zu hinterlegen. Für
fertige Arduino xyz Boards wird nur ein USB Kabel benötigt. Beim Every
ist der UPDI Übersetzer auf dem Board. Wie bei den MC Curiosity Boards.
Veit D. schrieb:> Hallo,>> wegen Interrupt Flag zurücksetzen. Nichts von Hand irgendwie> manipulieren. Einfach an die gewünschte Bitposition sturr "1"> reinschreiben. Mehr muss nicht beachtet oder gemacht werden.>
1
> Bits 7:0 – INT[7:0] Pin Interrupt Flag
2
> Pin interrupt flag n is cleared by writing a ‘1’ to it.
3
> Pin interrupt flag n is set when the change or state of pin n (Pxn)
4
> matches the pin's Input/Sense Configuration (ISC)
5
> in PORTx.PINnCTRL.
6
> Writing a ‘0’ to bit n in this bit field has no effect.
7
> Writing a ‘1’ to bit n in this bit field will clear Pin interrupt flag
8
> n.
9
>
Willkommen im Club, oder "Man lernt nur durch Wiederholung". Steht alles
schon oben.
Die Frage ist, ob der TO das auch liest.
S. L. schrieb:>> das habe ich schon versucht, ohne Erolg ... 'cbr ...'>> Wie wäre es mit 'ori Value, 0x01'?> Denn: 'Pin interrupt flag n is cleared by writing a ‘1’ to it'.>> Korrektur:> 'andi Value, ~0x01' ist wohl besser; oder, wenn es dieses (aus meiner> Sicht unglückliche) 'cbr' sein muss: 'cbr Value, ~0x01'.
Hallo,
also wer lesen kann, ist klar im Vorteil. Man bin ich blöd, ich habe
eine '0' reingeschrieben.
Vielen Dank euch allen für eure Hilfe.
MfG Torsten
Torsten N. schrieb:> S. L. schrieb:>>> das habe ich schon versucht, ohne Erolg ... 'cbr ...'>>>> Wie wäre es mit 'ori Value, 0x01'?>> Denn: 'Pin interrupt flag n is cleared by writing a ‘1’ to it'.>>>> Korrektur:>> 'andi Value, ~0x01' ist wohl besser; oder, wenn es dieses (aus meiner>> Sicht unglückliche) 'cbr' sein muss: 'cbr Value, ~0x01'.>> Hallo,>> also wer lesen kann, ist klar im Vorteil. Man bin ich blöd, ich habe> eine '0' reingeschrieben.
Nicht nur das ... s.a.mein Beitrag oben.
Ja, war leider nicht ganz korrekt, weil damit evtl. weitere Flags
gelöscht werden; korrekt ist das direkte, einfache Setzen des Bits im
Register (also ohne vorheriges Lesen), wie von Wilhelm M. vorgestellt.
Nochmal zum 'cbr' (wie auch 'sbr'): das ist kein richtiger Befehl,
sondern genaugenommen ein Artefakt des Assemblers - erkennbar im 'AVR®
Instruction Set Manual', denn dort wird hierfür kein Maschinencode
gezeigt.
Und stiftet nur Verwirrung, falls man sich an 'sbi' oder 'cbi'
orientiert.
Hi
>Nochmal zum 'cbr' (wie auch 'sbr'): das ist kein richtiger Befehl,>sondern genaugenommen ein Artefakt des Assemblers ->erkennbar im 'AVR® Instruction Set Manual', denn dort wird hierfür kein >Maschinencode gezeigt.
Wieso kein Maschinencode. Bei mir steht da
16-bit Opcode: 1001 1000 AAAA Abbb
mit 0 ≤ A ≤ 31, 0 ≤ b ≤ 7
Ist für mich ein eindeutiger Code.
MfG Spess
an Spess53:
Da haben Sie sich wohl vertan, Ihre Angaben kann ich nicht
nachvollziehen.
'cbr' ist ein im Argument modifiziertes 'andi', aus dem Listfile:
1
000000 7a0a cbr r16,~0xAA
2
000001 7a0a andi r16,0xAA
Der Maschinencode fehlt für 'cbr' im 'AVR® Instruction Set Manual',
siehe Anhang.
'sbr' ist identisch zu 'ori', bringt folglich, nach meiner Meinung,
keinerlei Mehrwert.
Gi
>>Warum sich mit ASM quälen, wenn es C gibt.
Warum sich mit C quälen, wenn es Pascal gibt.
Es ist erstaunlich effektiv und viel einfacher.
MfG Spess
Spess53 .. schrieb:> Gi>>>>Warum sich mit ASM quälen, wenn es C gibt.>> Warum sich mit C quälen, wenn es Pascal gibt.>> Es ist erstaunlich effektiv und viel einfacher.>> MfG Spess
Welches Pascal für AVR denn genau? Luna-AVR ist klinisch tot.
MfG Helmut
an Uwe K.:
Finden Sie nicht auch, nach näherer Betrachtung, dass Ihr Beitrag zum
Thema etwas dürftig ausgefallen ist?
Und da gleich zu Beginn offensichtlich war, dass es hier um Assembler
geht, frage ich mich, weshalb Sie sich bis hier unten, durch dreißig
Beiträge, "gequält" haben.