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
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).
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
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
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...
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
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.
Hi PortC.5 ist PCINT13 und gehört daher zu PCIE1. MfG Spess
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
Hi spess53 schrieb: > Hi > > Hast recht. Aber hast du das JTAG abgeschaltet? > > MfG Spess ja, ist abgeschaltet
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
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
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ß
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.