Forum: Mikrocontroller und Digitale Elektronik ATMega4809 externer Interrupt


von Torsten N. (torstenm1979)


Lesenswert?

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

von Veit D. (devil-elec)


Lesenswert?

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.

: Bearbeitet durch User
von Torsten N. (torstenm1979)


Lesenswert?

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

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ist der Pin außen beschalten? Mit internen Pullup probiert?
Ansonsten musst du warten bis die Assemblerprofis hier aufschlagen.

von Torsten N. (torstenm1979)


Lesenswert?

Hallo,

keine Hardware, zur Zeit bin ich nur im Simulator unterwegs.

MfG Torsten

von Spess53 .. (hardygroeger)


Lesenswert?

Hi

.include "m4809def.inc"

Wozu ist das zweimal drin?

MfG Spess

von Torsten N. (torstenm1979)


Lesenswert?

G' Morgen,

es sind eigentlich zwei Dateien.

MfG Torsten

von Veit D. (devil-elec)


Lesenswert?

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
}

: Bearbeitet durch User
von Torsten N. (torstenm1979)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Ingo L. (corrtexx)


Lesenswert?

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.

von Torsten N. (torstenm1979)


Lesenswert?

Danke Ingo :-)

MfG Torsten

von S. L. (sldt)


Lesenswert?

> 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'.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

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.

von Veit D. (devil-elec)


Lesenswert?

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.  :-)  :-)

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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!)

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

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'.

von Wilhelm M. (wimalopaan)


Lesenswert?

Torsten N. schrieb:
> lds    Value, PORTA_INTFLAGS
>   cbr    Value, 0x01
>   sts    PORTA_INTFLAGS, Value

Es reicht ein:
1
sts PORTA_INFLAGS, 0x01

von S. L. (sldt)


Lesenswert?

> Es reicht ein:
> sts PORTA_INFLAGS, 0x01

?

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

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.

von Veit D. (devil-elec)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

der TO bekommt das schon, da bin ich mir sicher. Die Frage ist eher ob 
sein Simulator das alles korrekt umsetzen kann.

von Torsten N. (torstenm1979)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von S. L. (sldt)


Lesenswert?

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.

von Spess53 .. (hardygroeger)


Lesenswert?

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

von S. L. (sldt)


Angehängte Dateien:

Lesenswert?

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.

von Uwe K. (ukhl)


Lesenswert?

Warum sich mit ASM quälen, wenn es C gibt.

Es ist erstaunlich effektiv und viel einfacher.

Ist natürlich Geschmackssache....

von Spess53 .. (hardygroeger)


Lesenswert?

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

von Helmut H. (quacksalber)


Lesenswert?

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

von S. L. (sldt)


Lesenswert?

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.

von Spess53 .. (hardygroeger)


Lesenswert?

Hi

>Welches Pascal für AVR denn genau? Luna-AVR ist klinisch tot.

Lazarus

MfG Spess

von Günther K. (avr-guenther)


Lesenswert?

Spess53 .. schrieb:
> Lazarus

Gibt es aber meines Wissens nur für Linux. Windows User sthen aussen 
vor.

Oder?

Ciao

von Spess53 .. (hardygroeger)


Lesenswert?

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

von Günther K. (avr-guenther)


Lesenswert?

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

von Uwe K. (ukhl)


Lesenswert?

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.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.