Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Re: Interrupt Kategorie: Programmierung (von Henner5 - 3.04.2004 11:33)
Als Antwort auf Re: Interrupt von Andreas - 1.04.2004 9:46
Ich nutze:
C-Control II Unit
Hallo Andreas,
Es war ja erstmal nur Denksport. Aber prima, daĂ? die Mist-
kröte jetz läuft. Ist ja auch gerade die Zeit für
Krötenwanderungen.
Wir sollten in Verbindung bleiben, da bei mir auch manchmal
schier unlösbare Effekte auftreten.
Beste GrĂĽĂ?e
Hendrik

> Also entschuldige bitte erst mal die späte Antwort. Ich hab inzwischen das mit dem Flip Flop umgesetzt
> und es funktioniert gut und vor allem zuverlässig. Ich gebe zu, dass ich deinen Vorschlag wieder nicht
> auf Anhieb verstanden habe, aber so, wie ich inzwischen die kleine Mistkröte kennengelernt habe, würde
> der neue Vorschlag wieder nicht mit absoluter Zuverlässigkeit funktionieren. Vor allem, weil ich wegen
> einem Prellproblem, das nicht durch Entprellkapazitäten zu lösen war, auf einen optischen
> Rotationsgeber ausweichen musste, der nun mit 128 Impulsen pro Umdrehung arbeitet. Da kommt die
> Mistkröte wieder an die Grenzen der Abtastrate. Und da das ganze eine Sicherheits-Relevante
> Anwendung ist, kann ich mich wieder nicht auf eine reine Softwarelösung ohne Interrupt verlassen.
> Ich hätte gern mal deinen Vorschlag ausprobiert, nur um zu sehen, obs geklappt hätte, aber
> inzwischen hab ich die Lösung so schon vermeldet und die nächsten Probleme müssen angepackt
> werden. Ich find es selber schade, das dieser Vorschlag "unprobiert" bleibt....
>
> > Hey Andreas,
> > mein Problem, dass ich mich gerne in einen Job verbeisse.
> > Folgende Idee: In der SchnĂĽffelroutine wird nur noch nach
> > dem Eingang A gefragt und hat nach bestimmter -sagen wir
> > 100ms lang B keinen Inerrupt mehr generiert, so war zu
> > diesem Zeitpunkt B == 0, anderenfalls war B == -1. Mit
> > anderen Worten hast Du dann die Funktion des Latches
> > an der letzten Flanke nachvollzogen:
> >
> > > > //-----------------------------------------------------------------------
> > > > const P1H0 = 8;
> > > > const P1H1 = 9;
> > > > const eingangA = P1H0;
> > > > const eingangB = P1H1;
> > > > const rechts = 0;
> > > > const links = -1;
> > > > const true = -1;
> > > > const false = 0;
> > > >
> > > > type handrad
> > > >   {
> > > >    int ticks, richtung, error;
> > > >   };
> > > >
> > > > handrad HR;
> > > > ....
> > > > ....
> > > > thread handrad_control
> > > > //================
> > > > {
> >
> > > > function askB() returns int; // liefert true, wenn nach A-Ende noch ein Interrupt kam
> > > > //----------------------------
> >     {
> >        sleep 100;
> >        return ports.getcount(eingangB);
> >     }; END of function askB()
> >
> >
> > > > function load_HD ()
> > > > //------------------------- schnĂĽffelt im Hintergrund am Handrad
> > > >   {
> > > >   int i, j, ticksA, ticksB;
> > > >   ticksA = 0;                                  // die Anzahl ist zunächst = 0
> > > >   ticksB = 0;
> > > >   HD.error = false;                         // erst mal eine Vermutung
> > > >   capture;                                     // suspendiert alle anderen threads, sonst verzählt er sich
> > > >   i = ports.getcount(eingangA);       // ist das Handrad bedient worden ?
> > > >   while (i != 0)
> > > >      {
> > > >         ticksA = ticksA + i;               // Inkrementiere A
> > > >         sleep 500;                            // weitere Eingaben abwarten, wie lange? ist Geschmacksache
> > > >         i = ports.getcount(eingangA); // Auslesen A
> >             j = ports.getcount(eingangB); // B verwerfen
> > > >      };
> >     HD.ticks = ticksA; // merken wir uns das Ergebnis
> >     if askB() { HD.richtung = rechts) else // nach dem letzten interrupt A war B == high
> >               { HD.richtung = links; HD.ticks = ticksA + 1;};
> >   > >   release;                                     // gibt alle anderen threads wieder frei
> > > >   }; // END of function load_HD
> > > > load_HD();                                   // AusfĂĽhren der synchronisierten Funktion
> > > > };  // END of thread handrad_control
> > > > //--------------------------------------------------------------------
> > > >
> >
> > Ein Versuch ist's wert,
> > GrĂĽĂ?e
> > Hendrik
> >
> >
> > > Also tiefsten Respekt!!! Ich hab heute fast den halben Tag
> > > gebraucht, nur, um deinen Vorschlag nachzuvollziehen. Allerdings
> > > gings trotzdem nicht, trotz des vielversprechenden Ansatzes. Ich
> > > muss die erste Flanke "abschneiden", um die Drehrichtung
> > > aufgrund der unterschiedlichen Zählstände ermitteln zu können.
> > > Das bekomm ich nicht mit absoluter Zuverlässigkeit hin. Und beim
> > > Ovverride wäre es verhängnisvoll, wenn man zurückdrehen will
> > > und die Maschine auf einmal schneller läuft. Au�erdem sind auch
> > > einzelne "Klicks" nicht sehr zuverlässig erkannt worden, schon
> > > gar nicht deren Drehsinn. Woran das liegt, weiĂ? ich auch nicht,
> > > denn beim Polling gings ja wie schon gesagt. Na ja, was soll's!
> > > Wenn ich noch ein FlipFlop zur Drehrichtungserkennung
> > > dazwischenhäng, sollte es gehen. Ich kann mich jetzt nicht noch
> > > in die ASM Umgebung auch noch einarbeiten...
> > >
> > > > Hallo Andreas nochmal,
> > > > habe ein wenig nachgedacht. Da die Interruptports immer auf die fallende Flanke reagieren kannst
> > > > Du den Phasenvergleich zwischen A und B dadurch vornehmen, dass antweder A oder B einen Tick
> > > > mehr Zählt:
> > > >
> > > > //-----------------------------------------------------------------------
> > > > const P1H0 = 8;
> > > > const P1H1 = 9;
> > > > const eingangA = P1H0;
> > > > const eingangB = P1H1;
> > > > const rechts = 0;
> > > > const links = -1;
> > > > const true = -1;
> > > > const false = 0;
> > > >
> > > > type handrad
> > > >   {
> > > >    int ticks, richtung, error;
> > > >   };
> > > >
> > > > handrad HR;
> > > > ....
> > > > ....
> > > > thread handrad_control
> > > > //================
> > > > {
> > > > function load_HD ()
> > > > //------------------------- schnĂĽffelt im Hintergrund am Handrad
> > > >   {
> > > >   int i, j, ticksA, ticksB;
> > > >   ticksA = 0;                                  // die Anzahl ist zunächst = 0
> > > >   ticksB = 0;
> > > >   HD.error = false;                         // erst mal eine Vermutung
> > > >   capture;                                     // suspendiert alle anderen threads, sonst verzählt er sich
> > > >   i = ports.getcount(eingangA);       // ist das Handrad bedient worden ?
> > > >   j = ports.getcount(eingangB);    
> > > >   while ((i !=0)  or (j !=0))
> > > >      {
> > > >         ticksA = ticksA + i;               // Inkrementiere A
> > > >         ticksB = ticksB + j;               // Inkrementiere B
> > > >         sleep 500;                            // weitere Eingaben abwarten, wie lange? ist Geschmacksache
> > > >         i = ports.getcount(eingangA); // Auslesen A
> > > >         j = ports.getcount(eingangB); // Auslesen B
> > > >      };
> > > >   if (ticksA > ticksB)  {HD.ticks = ticksA; HD.richtung = rechts;} else
> > > >                                {HD.ticks = ticksB; HD.richtung = links;  };
> > > >   if (math.abs(ticksA - ticksB) > 1) HD.error = true; // die Differenz darf maximal 1 werden
> > > >   release;                                     // gibt alle anderen threads wieder frei
> > > >   }; // END of function load_HD
> > > > load_HD();                                   // AusfĂĽhren der synchronisierten Funktion
> > > > };  // END of thread handrad_control
> > > > //--------------------------------------------------------------------
> > > >
> > > > Jetzt brauchst Du in der main - thread lediglich die Variable HD.ticks abfragen, ob diese != 0 ist.
> > > > Wenn ja steht in HD.richtung Deine Richtungsinfo und in HD.ticks immer die grö�ere Anzahl der
> > > > eingegangenen Ereignisse. In load_HD wird geprĂĽft, ob die Differenz zwischen A und B wirklich
> > > > bloĂ? 1 ist, sonst stimmt etwas nicht und HD.error wird true.
> > > > Beste GrĂĽĂ?e
> > > > Hendrik
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > > Danke Thomas! Das war sehr sehr hilfreich, wenn auch
> > > > > niederschmetternd. Mich hat immer noch nicht die Hoffnung
> > > > > verlassen, dass vielleicht einer der sowas schon gemacht
> > > > > hat, mir mit seiner Erfahrung im dritten Punkt hier weiterhilft.
> > > > > Das Problem, Werte zu ĂĽbergeben kommt dann ja auf mich zu...
> > > > > Kann ich mein Programm unter C2 jetzt wegschmeiĂ?en?
> > > > > Muss ich alles unter C nochmal machen, ohne Betriebssystem?
> > > > > Das Buch hab ich mir heut frĂĽh schon bestellt....
> > > > >
> > > > >
> > > > > > Hallo Andreas,
> > > > > >
> > > > > > soweit ich Deine Frage und die verschiedensten Beiträge in diesem Forum verstehe,
> > > > > > gibt es folgende Probleme:
> > > > > >
> > > > > > 1. Grundsätzlich sind CC2-Programme nicht für Interruptroutinen nutzbar!
> > > > > >     (Grund: CC2-Programme werden nur virtuell ausgefĂĽhrt; das bedeutet sie liegen in einer nur vom
> > > > > >     Betriebssystem der CC2 lesbaren Form vor)
> > > > > >
> > > > > > 2. Eine Interruptroutine muĂ? mit Hilfe des Tasking-Compilers entweder in C oder in Assembler
> > > > > >     geschrieben werden.
> > > > > >     (Hierzu gibt es einige Infos auf der CD der CC2)
> > > > > >
> > > > > > 3. Wie werden Werte zwischen dem CC2-Programm und der Interruptroutine ĂĽbergeben. In
> > > > > >     Deinem Fall: "links" oder "rechts" und die Anzahl Pulse.
> > > > > >
> > > > > > Ich stehe momentan vor dem gleichen Problem; allerdings kommt bei mir noch erschwerend hinzu,
> > > > > > daĂ? von der Interruptroutine aus Assemblerroutinen im OS_OPT bzw. anderen Modulen (I2CCOM)
> > > > > > aufgerufen werden mĂĽssen.
> > > > > >
> > > > > > Auf Grund von Problem Nr. 1) gibt es nicht die Notwendigkeit Segment und Offset eines CC2-
> > > > > > Programms zu erfahren (die gibt es so nicht).
> > > > > >
> > > > > > Beim Lösen des Problems Nr. 2) erhältst Du neben dem HEX-File (dem Programmcode, der zur
> > > > > > CC2 ĂĽbertragen werden muĂ?) auch ein .lst-File, in dem Segment und Offset angegeben sind.
> > > > > > Das Segment ist normalerweise immer 3000h.
> > > > > >
> > > > > > Zur Lösung von Problem Nr. 3) gibt es einige Hinweise auf der CD der CC2 und auch im Buch
> > > > > > "Messen, Steuern und Regeln mit der C-Control II". Allerdings finde ich das alles nicht so
> > > > > > dargestellt, daĂ? man das gleich verwenden kann. Und das was ich bisher zu diesem Thema in
> > > > > > diesem Forum gelesen habe war auch nicht unbedingt eine Hilfe. Anscheinend wollen diejenigen,
> > > > > > die wissen wie es geht, nicht so richtig raus mit der Sprache.
> > > > > >
> > > > > > Mehr kann ich dazu erst einmal nicht sagen, weil ich auch keine praktischen Erfahrungen
> > > > > > vorweisen kann.
> > > > > >
> > > > > > TschĂĽĂ? und viel Erfolg,
> > > > > > Thomas
> > > > > >
> > > > > > > Danke fĂĽr deine schnelle Antwort! Geht aber nicht.
> > > > > > >
> > > > > > > Ich sehe keine Möglichkeit wie ich die getcount Funktion
> > > > > > > fĂĽr meine Zwecke nutzen kann.
> > > > > > > Wie gesagt, ich hab einen Inkrementalgeber mit zwei Spuren.  
> > > > > > > (A und B) Ich muss ja die Richtung erkennen, in die das Handrad
> > > > > > > gedreht wird. Die Zähler laufen ja immer vorwärts....
> > > > > > > Ich hab mir gedacht, dass ich die Interrupts auf A auslösen lasse
> > > > > > > bei der Flanke von High auf Low und dann brauch ich nur auf dem
> > > > > > > anderen Kanal nachzusehen, ob der gerade high ist.
> > > > > > > Wenn ja -> zähle vorwärts   wenn net -> rĂĽckwärts
> > > > > > > Das wär alles..........
> > > > > > > Ich versuchs mal die Wechsel zwischen high und low
> > > > > > > zu skizzieren:
> > > > > > >
> > > > > > > Vorwärts:
> > > > > > > A: ___/--------_______/----------_______
> > > > > > > B:_/---------______/----------_________
> > > > > > >
> > > > > > > Rückwärts:
> > > > > > > A:_/---------_______/----------_________
> > > > > > > B:___/-----------_______/----------_______
> > > > > > >
> > > > > > > Hoffentlich kann man das mit verschiedenen Schriftarten erkennen
> > > > > > >
> > > > > > > Ich brauch dafĂĽr aber immer noch die Werte fĂĽr Segment
> > > > > > > und Offset fĂĽr die function hook....
> > > > > > >
> > > > > > > > Hallochen,
> > > > > > > > ich glaube Du machst Dir das Leben unnötig schwer. Die Ports P1H0 .. P1H3 sind von Haus aus
> > > > > > > > interruptsensibel und auch sehr schnell. Du kommst mit den Standardroutinen problemlos an die
> > > > > > > > Zählerstände:
> > > > > > > >
> > > > > > > > //-----------------------------------------------------------------------
> > > > > > > > const P1H0 = 8;
> > > > > > > > const eingang = P1H0;
> > > > > > > >
> > > > > > > > ....
> > > > > > > > ....
> > > > > > > > function handrad () returns int
> > > > > > > >   {
> > > > > > > >      int i, ticks;
> > > > > > > >      ticks = 0;                                  // die Anzahl ist zunächst = 0
> > > > > > > >      i = ports.getcount(eingang);        // alte Zählerstände verwerfen
> > > > > > > >      do
> > > > > > > >         {
> > > > > > > >            sleep 500;                           // 1/2 Sekunde auf die Bedienung des Handrads warten
> > > > > > > >            i = ports.getcount(eingang);  // i = mit der jetzt eingegangenen Zahl laden, Puffer ist leer
> > > > > > > >            ticks = ticks + i;                  // inkrementbildung
> > > > > > > >         } while (i != 0);                        // wenn 1/2 Sekunde keine Eingabe,  dann ERBSE
> > > > > > > >      return ticks;                              // Ă?bergabe an die Funktion
> > > > > > > >   };
> > > > > > > > //--------------------------------------------------------------------
> > > > > > > >
> > > > > > > > Schreib mir mal bitte ob's gefungxt hat
> > > > > > > > tschĂĽss
> > > > > > > > Hendrik
> > > > > > > >
> > > > > > > > > Hallo!
> > > > > > > > >
> > > > > > > > > Ich arbeite mich erst seit drei Wochen in der Materie der C2 ein.
> > > > > > > > >
> > > > > > > > > Ich hab folgendes Problem:
> > > > > > > > > Ich will einen Inkrementalgeber mit 2 Spuren als Handrad zur Eingabe
> > > > > > > > > mit dem C2 zählen. Das Modul inkremental.zip (V1.1) will ich nicht
> > > > > > > > > verwenden, weil ich nicht noch mehr Platinen bzw. HW im Gehäuse
> > > > > > > > > unterbringen kann und will. Bisher hab ichs mit Polling versucht und
> > > > > > > > > das klappt ganz gut. Nur zu schnelle Umdrehungen bekommt die
> > > > > > > > > C2 nicht mit. Daher will ichs nun doch mit Interrupt probieren.
> > > > > > > > > Dazu gibts ja bekanntlich die function hook.
> > > > > > > > > Nur wo bekomm ich bei der Standart Entwicklungsumgebung der
> > > > > > > > > C2 die Werte fĂĽr segment und offset her?
> > > > > > > > > Da muss doch der Compiler eine Liste erstellen, aber die find ich
> > > > > > > > > nicht. Auch bei euch im Forum hab ich dazu nichts dazu gefunden..
> > > > > > > > >
> > > > > > > > > Vielen Dank im Vorraus!


    Antwort schreiben


Antworten: