Forum: Mikrocontroller und Digitale Elektronik Pin Change Interrupt bei offenem Eingang


von brat (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

An einem ATMega 644P schaltet an PINC.5 ein Schalter gegen Masse.
In der Testroutine wird der Schalter im Pin-Change-Interrupt abgefragt.
Hier erhalte ich bei geschlossenem Schalter trotz aktiviertem internen 
PullUps Einsprünge in die ISR.
im Anhang das Testprogramm:

Ich bin momentan etwas ratlos - JTAG ist disabled, die Ausgabe in der 
ISR sieht so aus:

000000000000000Z
000000000000000000Z
00000000000000000Z
000000000000000000000Z
00000000000000000000000000Z
0000000000000000000000Z
000000000000000000000Z
000000000000000000000000000Z

Wie kann es hier zu Pin-Change-Interrupts kommen? Wenn der Eingang offen 
wäre, müsste in der Ausgabe ja auch mal eine 1 auftauchen...


viele Dank im Vorraus

brat

von Klaus W. (mfgkw)


Lesenswert?

brat schrieb:
> Schalter gegen Masse ... bei geschlossenem Schalter

Das erklärt zwanglos die Nullen, eine 1 würde ich da auch nicht 
erwarten.

> Wie kann es hier zu Pin-Change-Interrupts

Laut Datenblatt vom mega644 (und dem Kommentar) liegt an PC5 der 
PCINT21.
Ich habe von BASIC keine Ahnung, aber es sieht mir eher danach aus, daß 
du auf den falschen Interrupt reagierst (PCINT2)?

Der PCINT2 wiederum würde aber bei PA2 zu finden sein.
Wenn der auch offen ist, kann er ja herumdriften und vielleicht zufällig 
zuschlagen (oder du hast etwas daran beschaltet).

von brat (Gast)


Lesenswert?

Hallo Klaus,

ja, die "0" sind richtig - aber ein Change kann ja dann nur zu einer "1" 
hin erfolgen - darum, wenn wirklich am Pin Changes auftreten, habe ich 
dann auch mal ne 1 erwartet.


Ja, PC.5 entspricht PCint21

laut Datenblatt:

PCICR – Pin Change Interrupt Control Register

Bit 2 – PCIE2: Pin Change Interrupt Enable 2
When the PCIE2 bit is set (one) and the I-bit in the Status Register 
(SREG) is set (one), pin change interrupt 2 is enabled. Any change on 
any enabled PCINT23:16 pin will cause an interrupt.
The corresponding interrupt of Pin Change Interrupt Request is executed 
from the PCI2 Interrupt Vector. PCINT23:16 pins are enabled individually 
by the PCMSK2 Register.


PCMSK2 – Pin Change Mask Register 2

Bit 7:0 – PCINT23:16: Pin Change Enable Mask 23..16
Each PCINT23:16-bit selects whether pin change interrupt is enabled on 
the corresponding I/O pin. If PCINT23:16 is set and the PCIE2 bit in 
PCICR is set, pin change interrupt is enabled on the corresponding I/O 
pin. If PCINT23:16 is cleared, pin change interrupt on the corresponding
I/O pin is disabled.


In der "M644pdef.dat" habe ich gesucht und ich denke die PCINT1 ... 
PCINT4 sind die richtigen Interrupts. Die anderen heißen nur INTx. Von 
daher hoffe ich, auf den richtigen Interrupt zu reagieren.
Ein Test an C.0 = PCint16 funktionierte tadellos.

Nichtsdestotrotz habe ich mal PA.2 als Eingang konfiguriert - da ängt 
nur ein Summer. Der Fehler bleibt.

danke

von brat (Gast)


Lesenswert?

Um der Sache mit einem eventuell falschen Interrupt-Vector aus dem Weg 
zu gehen, gibt es denn in Bascom eine Anweisung, die dem

On Pcint2 Isr_pcint2

gleichkommt, wobei man aber die direkte Programm-Adresse des 
Interrupt-Vectors ($000C) angeben kann?


On $000C ... funktioniert leider nicht

von Justus S. (jussa)


Lesenswert?

brat schrieb:
> In der "M644pdef.dat" habe ich gesucht und ich denke die PCINT1 ...
> PCINT4 sind die richtigen Interrupts.

das wäre aber etwas komisch...es gibt vier PCINT-Bereiche, 0-7 (=PORTA), 
8-15 (=PORTB), 16-23 (=PORTC) und 24-31 (=PORTD), die eigentlich von 
0..3 nummeriert sein sollten. Wenn sie aber von 1..4 nummeriert sind, 
müsste die passende ISR die PCINT3 sein...

von brat (Gast)


Angehängte Dateien:

Lesenswert?

Justus Skorps schrieb:
> brat schrieb:
>> In der "M644pdef.dat" habe ich gesucht und ich denke die PCINT1 ...
>> PCINT4 sind die richtigen Interrupts.
>
> das wäre aber etwas komisch...es gibt vier PCINT-Bereiche, 0-7 (=PORTA),
> 8-15 (=PORTB), 16-23 (=PORTC) und 24-31 (=PORTD), die eigentlich von
> 0..3 nummeriert sein sollten. Wenn sie aber von 1..4 nummeriert sind,
> müsste die passende ISR die PCINT3 sein...


stimmt, du hast recht - es heißt PCINT0 ... PCINT3
hier der wahrscheinlich richtige Auszug aus der def-Datei.

[INTS]
INT0=$002  ;External Interrupt0 Vector Address
INT1=$004  ;External Interrupt1 Vector Address
INT2=$006  ;External Interrupt1 Vector Address
PCINT0=$008     ;Pin Change Interrupt Request 0
PCINT1=$00A     ;Pin Change Interrupt Request 1
PCINT2=$00C     ;Pin Change Interrupt Request 2
PCINT3=$00E     ;Pin Change Interrupt Request 3
WDT=$010        ;Watchdog Time-out Interrupt
OC2A =$012  ;Timer2 compare match A Vector Address
OC2B =$014  ;Timer2 compare match B Vector Address
OVF2=$016  ;Timer2 overflow Vector Address
ICP1=$018  ;Timer1 Input Capture Vector Address
OC1A=$01A  ;Timer1 Output Compare A Interrupt Vector Address
OC1B=$01C  ;Timer1 Output Compare B Interrupt Vector Address
OVF1=$01E  ;Overflow1 Interrupt Vector Address
OC0A =$020  ;Timer0 compare match Vector Address
OC0B =$022  ;Timer0 compare match Vector Address
OVF0=$024  ;Overflow0 Interrupt Vector Address
SPI =$026  ;SPI Interrupt Vector Address
URXC=$028  ;UART Receive Complete Interrupt Vector Address
UDRE=$02A  ;UART Data Register Empty Interrupt Vector Address
UTXC=$02C  ;UART Transmit Complete Interrupt Vector Address
ACI =$02E  ;Analog Comparator Interrupt Vector Address
ADCC=$030  ;ADC Conversion Complete Interrupt Vector Address
ERDY=$032  ;EEPROM Write Complete Interrupt Vector Address
TWI=$034       ;2wire serial int
SPMR=$036  ; Store Program Memory Ready Interrupt Vector Address
URXC1=$038  ;UART 1 Receive Complete Interrupt Vector Address
UDRE1=$03A  ;UART 1 Data Register Empty Interrupt Vector Address
UTXC1=$03C  ;UART 1 Transmit Complete Interrupt Vector Address


[INTLIST]
count=30
INTname1=INT0,$002,EIMSK.INT0,EIFR.INTF0
INTname2=INT1,$004,EIMSK.INT1,EIFR.INTF1
INTname3=INT2,$006,EIMSK.INT2,EIFR.INTF2
INTname4=PCINT0,$008,PCICR.PCIE0,PCIFR.PCIF0
INTname5=PCINT1,$00A,PCICR.PCIE1,PCIFR.PCIF1
INTname6=PCINT2,$00C,PCICR.PCIE2,PCIFR.PCIF2
INTname7=PCINT3,$00E,PCICR.PCIE3,PCIFR.PCIF3
INTname8=WDT@WATCHDOG,$010,WDTCSR.WDIE,WDTCSR.WDIF
INTname9=OC2A@COMPARE2A,$012,TIMSK2.OCIE2A,TIFR2.OCF2A
INTname10=OC2B@COMPARE2B,$014,TIMSK2.OCIE2B,TIFR2.OCF2B
INTname11=OVF2@TIMER2,$016,TIMSK2.TOIE2,TIFR2.TOV2
INTname12=ICP1@CAPTURE1,$018,TIMSK1.ICIE1,TIFR1.ICF1
INTname13=OC1A@COMPARE1A,$01A,TIMSK1.OCIE1A,TIFR1.OCF1A
INTname14=OC1B@COMPARE1B,$01C,TIMSK1.OCIE1B,TIFR1.OCF1B
INTname15=OVF1@TIMER1,$01E,TIMSK1.TOIE1,TIFR1.TOV1
INTname16=OC0A@COMPARE0A,$020,TIMSK0.OCIE0A,TIFR0.OCF0A
INTname17=OC0B@COMPARE0B,$022,TIMSK0.OCIE0B,TIFR0.OCF0B
INTname18=OVF0@TIMER0,$024,TIMSK0.TOIE0,TIFR0.TOV0
INTname19=SPI,$026,SPCR0.SPIE0,SPSR0.SPIF0
INTname20=URXC@SERIAL,$028,UCSR0B.RXCIE0,UCSR0A.RXC0
INTname21=UDRE,$02A,UCSR0B.UDRIE0,UCSR0A.UDRE0
INTname22=UTXC,$02C,UCSR0B.TXCIE0,UCSR0A.TXC0
INTname23=ACI,$02E,ACSR.ACIE,ACSR.ACI
INTname24=ADCC@ADC,$030,ADCSR.ADIE,ADCSR.ADIF
INTname25=ERDY,$032,EECR.EERIE
INTname26=TWI,$034,TWCR.TWIE,TWCR.TWINT
INTname27=SPMR,$036,SPMCSR.SPMIE
INTname28=URXC1@SERIAL1,$038,UCSR1B.RXCIE1,UCSR1A.RXC1
INTname29=UDRE1,$03A,UCSR1B.UDRIE1,UCSR1A.UDRE1
INTname30=UTXC1,$03C,UCSR1B.TXCIE1,UCSR1A.TXC1


die Adresse des Interrupt-Vektors ist ebenfalls zu erkennen.
Das alles bestätigt mich eigentlich, dass es softwaretechnisch i. O. 
ist.

Hardwaretechnisch weiß ich nicht, wie etwas floaten soll.

Im Anhang nochmal das Programm, mit einer leichten Veränderung.
Die Ausgabe sieht nun so aus:

000001
0000000000000000000000001
001
0000000000000000000000000001
00000000000000000000000000000000000000000000001
000000000000000000000000000000001
000000000000000000000000000000000000000000000000000000000000000000000000 
00001
000000000000000000000000000001
000000000000001
0000000000000001
000000000000000000000000000000000000000000000000000000000000000000000001
00000000000001
01
0000000000000000000000000001
00000000000000000000000000000000000000000001

von brat (Gast)


Lesenswert?

Zu der Ausgabe:

Pro Sekunde kommen vielleicht 5-10 Zeichen, daher stimmt wohl in den 
meißten Durchläufen der Pegel (bzw. es gibt kein Change)

die 1 am jeweiligen Ende heißt, dass die Main-Loop einen High-Pegel 
festgestellt hat, im Interrupt wird der Pegel immer auf 0 erkannt.

von spess53 (Gast)


Lesenswert?

Hi

PortC.5 ist PCINT13 und gehört daher zu PCIE1.

MfG Spess

von brat (Gast)


Lesenswert?

Hi Spess,

spess53 schrieb:
> Hi
>
> PortC.5 ist PCINT13 und gehört daher zu PCIE1.
>
> MfG Spess


unter PCINT13 finde ich im Datenblatt den PORTB.5


Gruß
brat

von spess53 (Gast)


Lesenswert?

Hi

Hast recht. Aber hast du das JTAG abgeschaltet?

MfG Spess

von brat (Gast)


Lesenswert?

Hi

spess53 schrieb:
> Hi
>
> Hast recht. Aber hast du das JTAG abgeschaltet?
>
> MfG Spess

ja, ist abgeschaltet

von brat (Gast)


Lesenswert?

Hallo,

vielleicht ist es ja doch ein Problem des ATMegas...


$regfile = "M644pdef.dat"
$crystal = 12288000
$hwstack = 128
$swstack = 128
$framesize = 128
$baud = 57600

Schalter Alias Pinc.5 : Config Schalter = Input : Portc.5 = 1

Print "Neustart"

Do
   If Schalter = 1 Then Print "1";
Loop
End


selbst dieses Programm bringt sporadisch "1"er ins Terminal.
Widerstand im eingebauten Zustand zwischen PC.5 und GND = 1R5

von Peter D. (peda)


Lesenswert?

brat schrieb:
> In der Testroutine wird der Schalter im Pin-Change-Interrupt abgefragt.

Das ist mit Abstand die schlechteste Methode, einen Schalter einzulesen.
Sie ist sehr störempfindlich, wie Du ja prima sehen kannst.

Der beste Weg ist Abfragen und Entprellung im Timerinterrupt.


Peter

von brat (Gast)


Lesenswert?

Hallo Peter,

Peter Dannegger schrieb:
> brat schrieb:
>> In der Testroutine wird der Schalter im Pin-Change-Interrupt abgefragt.
>
> Das ist mit Abstand die schlechteste Methode, einen Schalter einzulesen.
> Sie ist sehr störempfindlich, wie Du ja prima sehen kannst.
>
> Der beste Weg ist Abfragen und Entprellung im Timerinterrupt.
>
>
> Peter

damit hast du natürlich recht - in den Momenten wo geschalten wird, 
bekomm ich viel zu viele Interrupte.
Mein Problem ist allerdings, dass ich Interrupte bekomme, wenn der 
Schalter ruht, oder das ich selbst beim schnellen Polling alle paar 
Sekunden einen falschen Wert einlese.
In diesem Fall besteht kein Problem mit Prellen, sondern der 
Glaubwürdigkeit des Registers.

Morgen kann ich mal die Hardware tauschen - dann hoffe ich, hat es sich 
erledigt


Gruß

von Peter D. (peda)


Lesenswert?

Wie lang ist denn die Leitung zum Schalter?
Diese Leitung ist eine Antenne und der interne 50k ist zu hochohmig, um 
die empfangenen Wechselspannungen genügend stark zu bedämpfen.

Eine Entprellung macht ja gleichzeitig auch eine Störunterdrückung.
In meiner Praxis hat sich eine 4-fach Abtastung mit der Entprellzeit 
(5..50ms) als genügend störfest bewährt.


Peter

von brat (Gast)


Lesenswert?

Hallo Peter,

Peter Dannegger schrieb:
> Wie lang ist denn die Leitung zum Schalter?

ca. 40cm - bestehend aus 2 Leitungen (Schalter -> Platine 1 und Platine 
1 -> Platine 2 mit µC) dazwischen Pfosten-Buchse/Stecker sowie 
Platinensteckverbinder.
Diese Leitung führt auch an DC/DC Wandlern vorbei.

> Diese Leitung ist eine Antenne und der interne 50k ist zu hochohmig, um
> die empfangenen Wechselspannungen genügend stark zu bedämpfen.

Auch dies kann ich nachvollziehen, jedoch funktioniert gerade dieser Weg 
(Signal mit internem PullUp festlegen und pollen) offenbar fehlerfrei.

Probleme bereitet der andere Pfad (Signal mit Schalter auf GND-Potential 
ziehen und pollen)

Der gemessene Widerstand zu GND beträgt 1,5 Ohm

>
> Eine Entprellung macht ja gleichzeitig auch eine Störunterdrückung.
> In meiner Praxis hat sich eine 4-fach Abtastung mit der Entprellzeit
> (5..50ms) als genügend störfest bewährt.
>
>
> Peter

von Peter D. (peda)


Lesenswert?

brat schrieb:
> Probleme bereitet der andere Pfad (Signal mit Schalter auf GND-Potential
> ziehen und pollen)
> Der gemessene Widerstand zu GND beträgt 1,5 Ohm

Das sollte niederohmig genug sein.

Und Du bist sicher, nur den Pullup eingeschaltet zu haben und nicht den 
Pin als Ausgang?
Wie ist denn die Stromaufnahme des AVR?


Peter

von brat (Gast)


Lesenswert?

Hallo,

Die Tests mit zweitem ATMega 644 und STK500 zeigten, dass der ATMega an 
sich wohl nicht schuld ist.
Das Nachmessen der Verbindungen C.5 gegen Masse zeigte wieder unter 2 
Ohm.

Durch die Leitungslöserei und das Zusammenstecken und den Ein- und 
Ausbau des ATMega verringerte sich die Fehlerhäufigkeit.

Aktuell tritt bei maximal schnellen Polling bei 12 Mhz etwa minütlich 
ein Fehler auf. Zufrieden keinen Fehler finden zu können bin ich zwar 
nicht, aber diese Fehler werde ich dann herausfiltern.

Dennoch besten Dank

brat

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.