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,
das habe ich schon versucht, ohne Erolg:
1 | setPointAcquisition_Triggered:
| 2 | push Value
| 3 | lds Status, CPU_SREG_offset
| 4 |
| 5 | lds Value, PORTA_INTFLAGS
| 6 | cbr Value, 0x01
| 7 | sts PORTA_INTFLAGS, Value
| 8 |
| 9 | sts CPU_SREG_offset, Status
| 10 | pop Value
| 11 |
| 12 | reti
|
MfG Torsten
Hallo,
ist der Pin außen beschalten? Mit internen Pullup probiert?
Ansonsten musst du warten bis die Assemblerprofis hier aufschlagen.
Hallo,
keine Hardware, zur Zeit bin ich nur im Simulator unterwegs.
MfG Torsten
Hi
.include "m4809def.inc"
Wozu ist das zweimal drin?
MfG Spess
G' Morgen,
es sind eigentlich zwei Dateien.
MfG Torsten
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 | int main (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
| 16 | VPORTE.INTFLAGS = PIN0_bm; // delete Interrupt Flag
| 17 | VPORTE.DIR |= PIN2_bm; // Led 13
| 18 | VPORTD.DIR |= PIN3_bm; // Takt 14
| 19 | sei();
| 20 |
| 21 | while(1)
| 22 | {
| 23 | VPORTD.IN = PIN3_bm; // toggle Taktpin 14
| 24 | _delay_ms (100);
| 25 | }
| 26 | }
| 27 |
| 28 | ISR (PORTB_PORT_vect)
| 29 | {
| 30 | VPORTE.IN = PIN2_bm; // toggle Led 13
| 31 | VPORTB.INTFLAGS = PIN0_bm; // delete Flag
| 32 | }
|
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. 1 | @echo off
| 2 | setlocal
| 3 |
| 4 |
| 5 | c:\windows\system32\mode.com com22: baud=1200 dtr=on
| 6 | c:\windows\system32\mode.com com22: dtr=off
| 7 |
| 8 | avrdude -C "C:\Users\Admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf" -v -patmega4809 -cjtag2updi -PCOM22 -b115200 -e -D -Uflash:w:C:\Users\Admin\Desktop\3V1_PSR.hex:i -Ufuse0:w:0x00:m -Ufuse1:w:0xC4:m -Ufuse2:w:0x02:m -Ufuse5:w:0xC9:m -Ufuse6:w:0x07:m -Ufuse7:w:0x00:m -Ufuse8:w:0x00:m {upload.extra_files}
| 9 |
| 10 | PAUSE
|
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.
Danke Ingo :-)
MfG Torsten
> 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.
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. :-) :-)
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'.
Torsten N. schrieb:
> lds Value, PORTA_INTFLAGS
> cbr Value, 0x01
> sts PORTA_INTFLAGS, Value
Es reicht ein:
> Es reicht ein:
> sts PORTA_INFLAGS, 0x01
?
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.
Nee, 'out' stimmt auch nicht.
1 | ldi Value,0x01
| 2 | sts PORTA_INFLAGS,Value
|
Würde auch das Sichern von SREG ersparen.
Oder vielleicht möchte Torsten etwas Schreibarbeit vermeiden mit: 1 | puti PORTA_INFLAGS,0x01
| 2 |
| 3 | .macro put
| 4 | .if @0 < $40
| 5 | out @0,@1
| 6 | .else
| 7 | sts @0,@1
| 8 | .endif
| 9 | .endmacro
| 10 |
| 11 | .macro puti
| 12 | ldi tmp0,@1
| 13 | put @0,tmp0
| 14 | .endmacro
|
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:
1 | ldi Value,0x01
| 2 | out VPORTA_INTFLAGS,Value
|
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.
Hallo,
der TO bekommt das schon, da bin ich mir sicher. Die Frage ist eher ob
sein Simulator das alles korrekt umsetzen kann.
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.
Warum sich mit ASM quälen, wenn es C gibt.
Es ist erstaunlich effektiv und viel einfacher.
Ist natürlich Geschmackssache....
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.
Hi
>Welches Pascal für AVR denn genau? Luna-AVR ist klinisch tot.
Lazarus
MfG Spess
Spess53 .. schrieb:
> Lazarus
Gibt es aber meines Wissens nur für Linux. Windows User sthen aussen
vor.
Oder?
Ciao
Hi
>Gibt es aber meines Wissens nur für Linux. Windows User sthen aussen vor.
https://www.lazarusforum.de/viewtopic.php?t=12660
MfG Spess
Spess53 .. schrieb:
> https://www.lazarusforum.de/viewtopic.php?t=12660
in diesem Thread geht es um unterstützte AVR Varianten. Von einer Windos
portierung von Lazarus habe ich da nichts lesen können.
Werde hute Abend mal stöbern.
Ciao
S. L. schrieb:
> an Uwe K.:
>
> Finden Sie nicht auch, nach näherer Betrachtung, dass Ihr Beitrag zum
> Thema etwas dürftig ausgefallen ist?
Ähh. Nein.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|