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