Re: Interrupt Kategorie: Programmierung (von Andreas - 26.03.2004 19:33) | ||
Als Antwort auf Re: Interrupt von Henner5 - 26.03.2004 10:09 | ||
| ||
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: Re: Interrupt (von Henner5 - 29.03.2004 18:18) Re: Interrupt (von Andreas - 1.04.2004 9:46) Re: Interrupt (von Henner5 - 3.04.2004 11:33) |