Moin, also eigendlich bin ich nun wirklich kein Neuling im AVR Proggen, aber das überfordert mich irgendwie. Es geht um einen ATmega8, programmiert wird in ASM unter AVR-Studio 4.13. Also ich möchte den Comparator dazu bringen das er mir den Timer/Counter1 hochzählt beim auslösen. Was bisher geht: Also ich hab den Analog Comperator soweit das er mit einen Interrupt ausführt. Sprich er bekommt mit wenn negativ:AIN1 (PD7) und positiv:AIN0(PD6) sich abwechseln. Desweiteren habe ich den Timer/Counter1 soweit das er OC1A (PB1)bzw. OC1B (PB2) toggelt wenn OCR1A bzw. OCR1B erreicht wurde. Allerdings "nur" wenn ich ihm sage das er keinen Prescaler verwenden soll (mit jedem anderen Prescaler würde es wahrscheinlich auch funktionieren). Was nicht geht: Ich aktiviere nun im ACSR Register des Comperators das Bit ACIC und schalte als Prescaler einen Externen Clock ein. Wenn ich nun an AIN1 und AIN0 wieder meinen Impuls setzte (der Nachweislich funktioniert da eine Interrupt Routine ausgeführt wird -> anderes Programm) sollte er doch eigendlich den Timer/Counter1 hochzählen, macht er aber nicht. Weder mit fallender noch mit steigender Flanke. Ich hänge meinen bisherigen Code mal an, allerdings sind die Kommentare natürlich mit vorsicht zu genießen, da ich schon sehrviel mit rumgespielt habe. Also z.B. hab ich im "Datenblatt" gelesen, das ich ICR1 nicht als TOP definieren darf, da ansonsten die externen Trigger ausgeschaltet werden, usw. Ich hoffe einer kann mir helfen, oder hat das vielleicht schonmal gemacht und kann mir einen Beispiel Code dazu senden. P.S.: liegt es vielleicht am Input Capture Flag das ich clearen muß. Ich denke allerdings das muß man nur, wenn man zum Programmlauf die Trigger Source umstellen will, wenn ich das richtig verstehe....Ralf ratlos :-( Gruß Ralf
Ich habe keinen Blick auf dein Programm geworfen, weil ich mit Assembler gerade nichts anfangen kann. Hast du dir das Bild auf Seite 75 (Figure 32) angeguckt? Der Analog-Komparator kann als alternative ICP-Quelle genutzt werden, aber nicht zum zählen.
Wau, danke Rahul, Du hast natürlich völlig recht, daher komm ich mit der Erklärung auch durcheinander. Jetzt stellt sich mir die Frage, was erwartet er denn am input Capture Pin (ICP1) bzw. meinem Analog Comparator Ausgang (AC0)?? Ich meine, ich sehe daraus das der Pin irgendwie in das ICRn (Register?!? hä?) geschrieben wird. Aber ich geb doch nur ein Bit rein? Und dann macht er daraus mein "TOP Value" wenn ich das richig interpretiere. Aus einem Bit generiert er das Top Value von 16Bit?? Wie geht das denn? Ich meine, mir ist schon klar das meine Frage schon so ist, übersetz mir bitte mal das Datenblatt... puh... eigendlich kann ich Englisch... aber ich versteht´s nicht... Hilfe?!? äääh, Bitte?!? :-)
Ah, oky, also wenn AC0 ausgelöst wird schreibt er den Wert den er bis dahin hochgezählt hat (TCNT1) in das Input Capture Register (ICR1). Hm, oky, nerv, er zählt nicht,...nicht ansatzweise, naja, zumindest ist jetz klar warum es nicht funktioniert ;-) Danke nochmal, muß ich halt anders hochzählen, danke zumindest nochmal Gruß Ralf
>Ich meine, ich sehe daraus das der Pin irgendwie in das ICRn >(Register?!? hä?) geschrieben wird. Nein, nicht der Pin, sondern der aktuelle Zählerstand, also TCNT1, wird bei einem "Ereignis" am ICP-Pin augenblicklich ins ICR1-Register kopiert. Welches Ereignis es sein soll, kann man festlegen auf "fallende Flanke", "steigende Flanke" oder "fallende und steigende Flanke". Das "augenblicklich" ist wörtlich zu nehmen: der Kopiervorgang findet im selben Taktzyklus (!) statt - das ist das Besondere am Input Capture. Mit einem Externen Interrupt kann man das nicht schaffen; dort könnte man TCNT1 erst einlesen, wenn das Programm im INterrupthanler gelandet ist, und das dauert ja so seine Zeit (mindestens ein paar Taktzyklen). Den Input Capture-Vorgang kannst Du auch vom Analog Comparator-Ausgang triggern lassen, über das Bit ACIC im ACSR. Klarer geworden?
>Also ich möchte den Comparator dazu bringen das er mir den >Timer/Counter1 hochzählt beim auslösen. Etwas verrückte Lösung: Toggle doch irgendeinen als Ausgang konfigurierten Pin im Analog-Comparator-Interrupt. Diesen Pin verbindest Du mit Pin T1 (= PD5 beim ATmega8). Dann nur noch über TCCR1B den Modus "external clock, triggered by [rising/falling] edge" für T/C1 wählen - fertig ist die Laube :-)
Wenn Du die Impulse am Analog-Komparator zählen willst, dann brauchst Du dazu keinen Timer/Counter, dazu reicht eine stinknormale Variable (mehrere Register). ...
@Hannes: jupp, denk ich mir auch so, einfach in einer Variable hochzählen, allerdings hast Du mich jetzt doch neugierig gemacht. Was meinst Du mit "mehrere Register"? Ich wollte jetzt einfach im Interrupt ACI eine Variable hochzählen und danach mit einer anderen Variable vergleichen. Wenn gleich, dann Ziel erreicht. Mit dem Timer/Counter1 wäre es halt schöner gewesen, weil der Controller in der Zeit wo der Counter mit den Impulsen aus dem Comparator beschäftigt gewesen wäre, noch andere Sachen machen hätte können. (puh, was für ein Deutsch, nunja) So ist der uC halt zu 100% damit beschäftigt die Interrupts zu bearbeiten...naja, geht halt nicht anders, oder??
>"mehrere Register"?
Wenn du mehr als 255 Impulse zählen willst, brauchst du mehr als ein
Register. Mehr hat Hannes Aussage nicht zu bedeuten (meine Deutung...).
R. Quentin wrote: > @Hannes: > jupp, denk ich mir auch so, einfach in einer Variable hochzählen, > allerdings hast Du mich jetzt doch neugierig gemacht. Was meinst Du mit > "mehrere Register"? Wie Rahul richtig vermutete meinte ich eine Deinen Ansprüchen angemessene Variable von 16/24/32 Bit, also 2, 3 oder 4 Register bzw. RAM-Zellen. > Ich wollte jetzt einfach im Interrupt ACI eine Variable hochzählen und > danach mit einer anderen Variable vergleichen. Wenn gleich, dann Ziel > erreicht. Genau so hätte ich das auch gemacht. > > Mit dem Timer/Counter1 wäre es halt schöner gewesen, weil der Controller > in der Zeit wo der Counter mit den Impulsen aus dem Comparator > beschäftigt gewesen wäre, noch andere Sachen machen hätte können. Das kann er doch so auch. Nehmen wir an, Dir reicht eine 16-Bit-Zahl (0..65535), dann muss in der AC-ISR Folgendes geschehen: - SREG sichern (in) - 4 Register sichern (push) - 4 Bytes (2 für Zähler, 2 für Vergleichswert) aus SRAM holen (ld/ldd/lds) - Zählerstand (mit Übertrag) erhöhen (inc, brne) - veränderten Zählerstand im RAM sichern (st/std/sts) - Zählerstand mit Referenz vergleichen (cp, cpc, brne) - Jobflag für erfolgreichen Vergleich setzen (sbr) - Register wiederherstellen (pop) - SREG wiederherstellen (out) - Rücksprung (reti) In der Mainloop kann sich der Controller um andere Dinge kümmern. Falls Deine Signale sehr langsam sind und prellen, dann solltest Du Dir mal die bulletproof-Entprellung von Peter Dannegger ansehen. Die findest Du in der Codesammlung oder im Tutorial. Sie läuft dann im Timer-Interrupt. Man kann damit nicht nur Tasten entprellen, sondern auch andere Ereignisse. > (puh, > was für ein Deutsch, nunja) > So ist der uC halt zu 100% damit beschäftigt die Interrupts zu > bearbeiten...naja, geht halt nicht anders, oder?? Doch, geht anders. Welche Methode die beste ist, kommt auf das Signal an. Ob allerdings ein (sauber arbeitender) "Klatsch-Schalter" so einfach realisierbar ist, wage ich zu bezweifeln. Ich danke, dass der Filteraufwand schon etwas höher sein muss, damit das Ding nicht auf alle anderen Geräusche anspricht. ...
Oh Oh Oh, mist, also erstmal Danke für die Antworten. Natürlich hätte ich schreiben müssen für was ich das ganze brauche, ... hüstel... nein, ein Klatsch-Schalter ist es nicht... ;-) Es sind die Impulse eines Inkrementalgebers einer Druckerkopf Positionsbestimmungs Mechanik. Also ein Plastikband mit tausenden von kleinen, kaum sichtbaren Strichen drauf. Wenn nun der Druckerkopf nach rechts/links fährt sollen diese Impulse vom uC eingelesen und mit einem Soll-Wert verglichen werden. (einlesen geht auch schon) Also für´s schreiben ins Ram, obwohl sehr nette Idee, ist da wirklich keine Zeit. Die Auslastung des uC kann ich noch nicht so genau sagen, muß erst noch experimentell bestimmt werden, da es mir unmöglich ist die Striche zu zählen, aber ich befürchte halt das bei höherer Geschwindigkeit ein Interrupt pro Takt des uC ohne Probleme zu schaffen sein wird ;-). Sorry das ich Euch so im Dunkeln habe tappen lassen, für die Ausgangsfrage war die Projektbeschreibung nicht wichtig. Aber ich denke ab hier komme ich auch wieder alleine klar. Vielen Dank nochmal an alle. Gruß Ralf
Natürlich kannst Du auch in Registern zählen, hast ja schließlich 32 Stück davon. Ich nehme auch erst dann RAM, wenn die Register knapp werden. Einige kleinere AVRs haben nichtmal RAM, da gibt's nur 32 Register... Hast Du eine oder zwei Lichtschranken an Deinem Strichband? Bei zwei könntest Du mal in der Codesammlung nach Drehgeber-Auswertung suchen, denn dann sind beide Signale vermutlich um 90° versetzt. ...
>aber ich befürchte halt das bei höherer Geschwindigkeit ein >Interrupt pro Takt des uC ohne Probleme zu schaffen sein wird ;-). Das glaube ich kaum. Wie schnell willst du deinen "Druckerkopf" denn bewegen? Ich bin der Meinung, dass die Striche eine Auflösung haben, die man mit Hannes Methode problemlos erkennen kann. Ich kann mich aber auch irren...
So, also vorweg funktionieren tut es leider noch nicht. Erstmal Daten: Das Strichband hat eine "Auflösung" von 60 Strichen pro cm. Gesamte Länge ist 14cm. Im Datenblatt des Mega8 (S.238) hab ich gefunden das die max. Propagation Delay bei Vcc 2,7V bei 750ns liegt. (Propagation Delay = Signallaufzeit ich nehm mal an das ist die Grenzfrequenz) Bei 750ns komm ich also auf ca 1,33MHz. Wenn man dann mal weiter rechnet müßte ich den Schlitten in 630us über die vollen 14cm fahren lassen. Nein, da liegt das Problem sicherlich nicht. Ich Denke das das Problem in der Amplitude des Inkrementalgebers zu suchen ist. Der Hub von 0,5V ist doch recht wenig. @Hannes: jupp, es sind zwei Lichtschranken um 90° versetzt. Um die Amplitude (Spannung) etwas größer zu bekommen habe ich daher schon den Comparator des uC genommen, manchmal klappt es ja auch, aber nicht gesichert. Sprich, mal erkennt er mehr Impule, mal weniger. Ich befürchte ich muß wohl noch nen OP davor basteln, der mir das Signal erstmal Spannungstechnisch in ein verträgliches Maß für den uC hebt. Hab natürlich keinen da, und WE ist schon wieder, nerv... Oder vielleicht hat ja jemand ne andere Idee wie man das Problem lösen könnte... Gruß Ralf
R. Quentin wrote: > Das Strichband hat eine "Auflösung" von 60 Strichen pro cm. > Gesamte Länge ist 14cm. Also 840 Striche insgesamt... > > Im Datenblatt des Mega8 (S.238) hab ich gefunden das die max. > Propagation Delay bei Vcc 2,7V bei 750ns liegt. (Propagation Delay = > Signallaufzeit ich nehm mal an das ist die Grenzfrequenz) Bei 750ns komm > ich also auf ca 1,33MHz. Wenn man dann mal weiter rechnet müßte ich den > Schlitten in 630us über die vollen 14cm fahren lassen. Nein, da liegt > das Problem sicherlich nicht. Das Tempo wirst Du aufgrund der Massenträgheit nicht erreichen. Wenn Du das (incl. Anfahren und Bremsen) in einer halben Sekunde schaffst, bist Du schon gut. > > Ich Denke das das Problem in der Amplitude des Inkrementalgebers zu > suchen ist. Der Hub von 0,5V ist doch recht wenig. Dann muss es eben verstärkt werden. > > @Hannes: > jupp, es sind zwei Lichtschranken um 90° versetzt. Also 2 Signale, 2 Eingänge... > Um die Amplitude > (Spannung) etwas größer zu bekommen habe ich daher schon den Comparator > des uC genommen, Es gibt aber pro AVR nur einen AC. Also muss eine andere Lösung her. > manchmal klappt es ja auch, aber nicht gesichert. > Sprich, mal erkennt er mehr Impule, mal weniger. Dann solltest Du Dir die Signale mal mit einem Oszilloskop genauer ansehen. Damit könntest Du auch gleich die zu erwartende Signalfrequenz (halbwegs) ermitteln. > > Ich befürchte ich muß wohl noch nen OP davor basteln, der mir das Signal > erstmal Spannungstechnisch in ein verträgliches Maß für den uC hebt. Das wäre vermutlich eine Lösung. > > Hab natürlich keinen da, und WE ist schon wieder, nerv... > > Oder vielleicht hat ja jemand ne andere Idee wie man das Problem lösen > könnte... Vielleicht kannst Du die Signale ja woanders abgreifen. Denn der Rechner des Druckers braucht schließlich auch höhere Pegel an seinen Eingängen. > > Gruß > Ralf ...
Hannes Lux schrieb: Es gibt aber pro AVR nur einen AC. Also muss eine andere Lösung her. He he, ja ne, warum, ich hab einfach den einen Signalausgang auf AIN0 und den anderen auf AIN1 gelegt. Da die Signale ja um 90° verschoben sind, sprich wenn #1 auf High ist ist #2 auf Low, ergibt sich, so denke ich mir das zumindest, eine bessere Erkennung des Comparators des Signales, oder stimmt das so nicht?? Die Signale woanders abgreifen ist leider keine Option. Mehrlagen Platine. Ausserdem nutze ich die original Platine nicht mehr. Da war, besser ist, was man so sehen kann, keine OP´s verbaut, allerdings ist auch der Processor der verwendet wurde eine "spezial" Anfertigung. Sprich man findet über diesen nichts. Die anfallenden Signale guck ich mir natürlich mit dem Oszilloskop an. Anders könnte ich wohl kaum sagen das das Signal eine Amplitude von 0,5V hat. Signalverlauf sieht gut aus, daher hab ich bisher ja auch noch auf einen Tiefpass verzichtet. Wie Du allerdings die zu erwartende Frequenz ablesen willst?? Obwohl, mit einem Speicher-Oszilloskop würde es wahrscheinlich gehen, tja, soviel Geld hab ich allerdings dann doch nicht ;-)
R. Quentin wrote: > He he, ja ne, warum, ich hab einfach den einen Signalausgang auf AIN0 > und den anderen auf AIN1 gelegt. Naja, damit kannst Du aber keine Richtung erkennen und weißt daher nicht, ob Du incrementieren oder decrementieren musst... > Da die Signale ja um 90° verschoben sind, sprich wenn #1 auf High ist > ist #2 auf Low, ergibt sich, so denke ich mir das zumindest, eine > bessere Erkennung des Comparators des Signales, oder stimmt das so > nicht?? Ein Zyklus hat meiner Meinung nach 4 Zustände: 00, 01, 11, 10 (Gray-Code). > Wie Du allerdings die zu erwartende Frequenz > ablesen willst?? Man sieht doch die ungefähre Periodendauer beim Bewegen des Druckkopfes anhand der Einstellung der Zeitablenkung. > Obwohl, mit einem Speicher-Oszilloskop würde es > wahrscheinlich gehen, tja, soviel Geld hab ich allerdings dann doch > nicht ;-) Ich hab' auch kein Speicheroszi. Das lässt sich auch so schätzen. ...
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.