PCINTs funktionieren anders als INTs

Gast #2219532
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
Gast #2219550
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
Gast #2219552
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
Gast #2219563
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?
Gast #2220054
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
Gast #2237337
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
Gast #2237371
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.
#2237551
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren