Forum: Mikrocontroller und Digitale Elektronik PCINTs funktionieren anders als INTs


von Alois (Gast)


Lesenswert?

Einen wunderschönen Guten Morgen!

Ich hätte hier mal ein klitzekleines Problemchen.

An einem Verbr.motor nutze ich für die Drehzahl sowie die 
Winkelbestimmung den INT0 eines ATMega88. Um zu bestimmten Zeitpunkten 
die Kolbenpositionen bestimmen zu können werden der INT1 sowie drei 
weitere PCINTs die mit Hallsensoren verbunden sind genutzt.
Jetzt habe ich das Problem, dass gerade die 3 Zylinder die mit den 
PCINTs verbunden sind bei bestimmten Drehzahlen einfach Sprünge 
aufweisen, d.h. ohne erkennbaren Grund 12° Kurbelwinkel zuviel anzeigen. 
Der Zylinder der mit INT1 verbunden ist macht das nicht.
Ich bin mir momentan nicht ganz sicher ob das an den Interrupts liegt 
oder doch ein anderes Problem sein kann.
Ich lasse für die PCINTs nur ein gewisses Zeitfenster zu, so dass nur im 
Falle einer fallenden Flanke in der ISR etwas berechnet wird.
Weiterhin habe ich auch schon versucht, direkt in der betreffenden ISR 
das entsprechende Bit im PCICR-Register und im PCIFR zu löschen und es 
nach einer gewissen Zeit in der Mainschleife zu setzen, hat aber auch 
nicht funktioniert (ich dachte, dass die PCINTs vielleicht mehrfach 
direkt nacheinander aufgerufen werden).


Hat hier vielleicht irgendjemand Rat?

Hier nochmal der Code:
1
ISR (INT0_vect)  {              // KURBELWELLENTRIGGERRAD
2
  t_zak = TCNT1;              // TimerCounter einlesen (16Bit-->gcc uebernimmt High-Low Byte)
3
  TCNT1 = 0;
4
  phi++;
5
  if ( t_zak_old > 21844 ) t_zak_old = 21844;
6
  if ( t_zak > 32768 ) t_zak = 32786;
7
  if ( (2 * t_zak) > (3 * t_zak_old) )  {
8
     phi=1;
9
  }
10
  t_zak_old = t_zak;       
11
}
12
13
////////////////////////////////////////////////////////////////////////////
14
ISR (INT1_vect)  {              // ZYLINDER 1, PD3
15
  if ( (phi < 46) & (phi > 39) ) {
16
    t_eps[0] = TCNT1;
17
    t_eps_old[0] = t_zak_old;
18
    phi_eps[0] = phi;          // Zuweisen des Kurbelwinkels seit KW_Sensor_Nullstellung
19
    t_eps_millisek[0] = T2_millisek;
20
    t_eps_sek[0] = T2_sek;
21
    flag_ch_eps[0] = 1;
22
  }
23
24
  //EIMSK &= ~(1<<INT1);          // Ausschalten des ExternalInterrupt INT1
25
}
26
27
////////////////////////////////////////////////////////////////////////////
28
ISR (PCINT0_vect)  {            // ZYLINDER 2, PB0
29
  if ( (phi < 16) & (phi > 9 ) ) {
30
    t_eps[1] = TCNT1;
31
    t_eps_old[1] = t_zak_old;
32
    phi_eps[1] = phi;
33
    t_eps_millisek[1] = T2_millisek;
34
    t_eps_sek[1] = T2_sek;
35
    flag_ch_eps[1] = 1;
36
  }
37
  //PCICR &= ~(1<<PCIE0);
38
  //PCIF0 &= ~(1<<PCIF0);
39
  //PCMSK0 &= ~(1<<Pin_eps2);        //Ausschalten des PinChangeInterrupts fuer den Pin an PortB
40
}

Für Zylinder 3 und 4 gilt das Gleiche wie für PCINT0_vect nur eben mit 
PCINT1_vect und PCINT2_vect)

Vielen Dank schonmal.

Alois

von Alois (Gast)


Angehängte Dateien:

Lesenswert?

Hier nochmal ein Bildchen, der Daten, die ich über RS232 aufzeichne.
Hier bei Zylinder 3 und 4.

von jonas biensack (Gast)


Lesenswert?

>Mir sind diese "Fischlein" schon bekannt. Aber selbst ein
>Bundespräsident ist höflich! Und dass MaWin hier öfters mal mit Leuten
>durch seine unhöfliche Art aneinander gerät ist glaube ich auch jedem
>bekannt der schon mehr als 2 Themen durchgelesen hat ;-)


-kann es sein das die Drehzahl zu hoch ist, so dass die ISR nicht 
komplett abgearbeitet werden kann, bevor die nächste aufgerufen wird ?

-Max U/min?
-F_CPU?

gruß jonas

von jonas biensack (Gast)


Lesenswert?

Sorry copy&paste fehler im letzen post !

So richtig:

>Jetzt habe ich das Problem, dass gerade die 3 Zylinder die mit den
>PCINTs verbunden sind bei bestimmten Drehzahlen einfach Sprünge
>aufweisen, d.h. ohne erkennbaren Grund 12° Kurbelwinkel zuviel anzeigen.

-kann es sein das die Drehzahl zu hoch ist, so dass die ISR nicht
komplett abgearbeitet werden kann, bevor die nächste aufgerufen wird ?

-Max U/min?
-F_CPU?

gruß jonas

von jonas biensack (Gast)


Lesenswert?

Nochwas:
> if ( (phi < 46) & (phi > 39) ) {

Meinst du damit, "wenn phi kleiner 46 und phi größer 39" müsstest du so 
schreiben

if ( (phi < 46) && (phi > 39) ) {

oder nicht?

von Michel (Gast)


Lesenswert?

jonas biensack schrieb:
> -kann es sein das die Drehzahl zu hoch ist, so dass die ISR nicht
> komplett abgearbeitet werden kann, bevor die nächste aufgerufen wird ?

Da würde wohl eher der Motor auseinanderfliegen.
Selbst bei 12000 U/min wären noch 5 ms Zeit

von jonas biensack (Gast)


Lesenswert?

>Da würde wohl eher der Motor auseinanderfliegen.
>Selbst bei 12000 U/min wären noch 5 ms Zeit

mh...stimmt ich war irgendwie bei U / sec aber selbst dass würde ja noch 
gehen...

>Ich lasse für die PCINTs nur ein gewisses Zeitfenster zu, so dass nur im
>Falle einer fallenden Flanke in der ISR etwas berechnet wird.

Das interesiert mich mal, du schaltest sie also mit sei() und cli() an 
und aus oder wie?

von Alois (Gast)


Lesenswert?

Komischerweise tritt es nur bei gewissen Drehzahlen auf. Ich habe mir 
auch schon überlegt, ob das evtl. irgendwelche Resonanzfrequenzen sind 
und daher die Sensoren Quatsch machen. Werde gleich mal das Oszilloskop 
bemühen...

if ( (phi < 46) && (phi > 39) )   <-- Das habe ich auch schon probiert,


Macht aber keinen Unterschied.

von Alois (Gast)


Lesenswert?

Mit dem Zeifenster meinte ich das Kurbelwinkelfenster. Ich weiß dass die 
Magneten innerhalb dessen in den Auslösebereich der Hallsensoren sind, 
aber nicht wieder aus dem Bereich austreten.
Das passiert erst nach dem angegebenen Kurbelwinkelbereich.

von jonas biensack (Gast)


Lesenswert?

>if ( (phi < 46) && (phi > 39) )   <-- Das habe ich auch schon probiert,

Ist aber einfach besserer und schönerer Stil, denn du vergleichst ja 
zwei Ausdrücke ob sie wahr sind, und verknüpst nicht zwei Ausdrücke 
binär mit einer Undverknüpfung...oder?

von jonas biensack (Gast)


Lesenswert?

Ah "Hallsensoren, die können Übles verursachen bei hohen Frequenzen...da 
war doch was...muss mal gerade schauen...

von Alois (Gast)


Lesenswert?

Meinst du?

Wobei meine Frequenzen sind ja nicht wirklich hoch!

Stutzig macht mich nach wie vor, dass Zylinder 1, der mit dem Int1 
zusammenarbeitet, diese Fehler nicht verursacht. Bis jetzt zumindest.

Da muss doch irgendein Zusammenhang sein?!

von jonas biensack (Gast)


Lesenswert?

So, dann mach mal folgendes: Tausche mal Zylinder 1 ISR und Zylinder 3 
ISR und schaue ob der Fehler immer noch auftritt - dann können wir sagen 
ist ein Software Problem :)

Das wäre doch schon mal ein Schritt weiter...

von Peter D. (peda)


Lesenswert?

Alois schrieb:
> Ich lasse für die PCINTs nur ein gewisses Zeitfenster zu, so dass nur im
> Falle einer fallenden Flanke in der ISR etwas berechnet wird.

Dann aber direkt vor der erneuten Freigabe das Interruptflag löschen 
(also setzen)!


Peter

von jonas biensack (Gast)


Lesenswert?

>Dann aber direkt vor der erneuten Freigabe das Interruptflag löschen
>(also setzen)!

>>Das interesiert mich mal, du schaltest sie also mit sei() und cli() an
>>und aus oder wie?

Genau in die Richtung habe ich auch gedacht.

von Alois (Gast)


Lesenswert?

Also ich habe jetzt noch mal die Steuerleitungen zu den Interrupts 
vertauscht.

Das Ganze tritt nur bei den PCINTs auf der INT1 des ersten Zylinders 
funktionert tadellos.

Mit dem Oszilloskop kann ich bis jetzt auch nichts gravierendes 
erkennen.


Das mit dem Interruptflag probiere ich jetzt noch aus. Momentan verstehe 
ich nicht ganz den Zusammenhang warum ich eine 1 in das PCIFR* eintragen 
muss, damit es gelöscht wird, ich dachte wenn ein Interrupt am Pin 
ausgelöst wird, dann steht da auch eine 1 drin?

Grüße

von Alois (Gast)


Lesenswert?

Ich habe jetzt noch einmal einiges an Zeit investiert, aber das Problem 
nicht wirklich wegbekommen.

Ich habe aber auch ein Problem im AVR-Simulator. Und zwar wenn ich 
innerhalb des PCIF-Registers die Flags während einer Simulation setze, 
dann funktionieren die ISRs für PCINT1_vect und PCINT2_vect aber mein 
Interrupt an PB0, also PCINT0_vect wird bei Setzen des PCF0 Flags nicht 
angesprungen.

Und wenn ich PINC Bit5 also meinen deklarierter Pin für den PCINT1_vect 
während der Simulation auf 1 setze, dann wird die ISR angesprungen, aber 
nicht mehr verlassen weil das PCIF1 weder vom Programm noch von Hand 
gelöscht werden kann. Nur wenn PINC Bit5 von Hand wieder auf 0 gesetzt 
wird, wird die ISR verlassen.

Ist das ein AVR-Simulatorproblem oder liegt das an mir?

Grüße,
Alois

von Klaus D. (kolisson)


Lesenswert?

Nimm doch einfach normale Int´s.
M88 hat int 0 , int1, Aco Int und ICP.
Dann hast du das gerögel mit den Pinchange Dingern nicht.

Gruss
klaus

von Alois (Gast)


Lesenswert?

Naja, ich brauche ja genau 5 Interrupts, deshalb bot sich ja der ATmega 
an, wegen den zwei externen und den 3 PCINTvektoren.

Momentan löse ich es ja so, dass ich die Werte vergleiche und dabei die 
fehlerhaften "rausfiltere".

Grundsätzlich wäre es auch eine Option auf den ATmega64 zu wechseln

Ich würde aber halt gerne wissen, wo hier das Problem liegt. Vielleicht 
hatte ja schon mal jemand ein ähnliches Verhalten. Oder ich mache 
irgendeinen grundätzlichen Fehler.

von Uwe (Gast)


Lesenswert?

Man löscht das PCIF1 flag indem man eine 1 reinschreibt

von Klaus D. (kolisson)


Lesenswert?

Alois schrieb:
> Naja, ich brauche ja genau 5 Interrupts, deshalb bot sich ja der ATmega
> an, wegen den zwei externen und den 3 PCINTvektoren.

Wenn du also die von mir vorgeschlagenen unkastrierten Int´s nimmst
hast du schon 4 Stück.
als 5ten nimmst du dann noch Pin Change , musst aber nicht mehr 
auswerten,
welcher Pin das tat.

Zudem hast du ja kenntnis über deinen Motor.
Das verschafft dir einen starken Vorteil gegenüber der maschine.
Es ist auch unwarscheinlich m dass der erste Kolben oben ist,
wenn der vierte auch oben ist. ... Dann wäre ja die Maschine kaputt.

Zudem gibt es auch immer noch AND und NAND Gates.
Es gibt auch 7474 flankengetriggerte D-Flip Flop
und es gibt Schieberegister.

Überleg mal genau !

Klaus

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.