Gast
#1191055
Hallo, Ich möchte bei meinem Tiny13 auf PB0 auf fallende Flanke triggern und die Zeit messen, bis dieses Ereignis eintritt. Mein Code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
Was mache ich falsch?
|
Anzeige
|
ICP auf PB0 bei Tiny13
Gast
#1191055
Hallo, Ich möchte bei meinem Tiny13 auf PB0 auf fallende Flanke triggern und die Zeit messen, bis dieses Ereignis eintritt. Mein Code:
Was mache ich falsch?
Gast
#1191065
Die Syntaxhervorhebung sagt mir das rechts neben dem << eine Null steht und kein Ohh.
Gast
#1191071
Kann es sein, dass der Tiny13 kein ICP kann? Wenn dem so ist, wie kann ich mein Problem dann lösen?
Gast
#1191275
Hallo, also ich denke jetzt, dass der Tiny13 wohl kein ICP beherrscht. Daher würde ich gerne einen Timer möglichst schnell laufen lassen, um Zeit zu messen (der Tiny läuft auf 1MHz). Hier ist mein Code:
Leider zeigt mir das Oszi, dass im Moment der PB3 nur mit etwa 65ms getogglet wird. Wenn ich diesen Wert durch 1024 Teile beudetet das, dass ich die Runtime nur auf etwa 60µs genau messen kann. Ich würde die Genauigkeit gerne steigern. Wie kann ich das machen?
Gast
#1191432
> also ich denke jetzt, dass der Tiny13 wohl kein ICP beherrscht. Das ist korrekt, ein Blick ins Datenblatt hätte diese Vermutung bestätigt. > Daher würde ich gerne einen Timer möglichst schnell laufen lassen, Das geht mit Vorteiler 1:1. Da der Tiny13 nur einen 8-Bit-Timer (mit Zählumfang von 256) hat, ist schnell aber nicht immer gut, denn damit kann man dann längere Impulse nicht mehr so ohne weiteres messen. > um Zeit zu messen (der Tiny läuft auf 1MHz). Das (1MHz) halte ich für ein Gerücht. Der Tiny13 läuft üblicherweise mit 9,6MHz und Systemtaktvorteiler 1:8, was einen Takt von 1,2MHz ergibt. Der Systemvorteiler kann vom Programm verändert werden, wie das geht, steht im Datenblatt. Wenn Du Zeiten mit dem Tiny13 messen willst, dann kläre estmal ab, welchen Bereich die Zeiten haben können. Daraus ermittels Du den benötigten Timer-Vorteiler und notfalls auch noch den benötigten Systemvorteiler. Nun kannst Du den externen Interrupt oder einen Pinchange-Interrupt benutzen, um die Flanke zu dedektieren. Der Timer läuft dabei frei durch. In der ISR des ext. Interrupts prüfst Du, ob es Impulsbeginn oder Impulsende ist. Bei Impulsbeginn merkst Du Dir den aktuellen Timerstand (Zeitstempel), bei Impulsende liesr Du den Timerstand ein und subtrahierst davon den gemerkten Stand des Impulsbeginns. Wenn Du dieses Grundprinzip ausbaust, kannst Du Impulsdauer, Impulspause und Periodendauer in (fast) einem Rutsch ermitteln. In ASM ist das kein Akt, C ist allerdings nicht mein Ding, da kann ich Dir kein Beispiel geben. ...
Gast
#1191736
Ich würde gerne auf 1µs genau messen. Dazu muss ich wohl auf 9,6MHz takten. Aber obwohl ich TCNT0 immer auf 255 setze bekomme ich nur alle 10µs einen Interrupt?
Gast
#1191824
> Ich würde gerne auf 1µs genau messen. Dazu muss ich wohl auf 9,6MHz > takten. Es interessiert nicht nur die Auflösung, sondern vor allem die der Wertebereich der Dauer der zu erwartenden Impulse. Die Impulszeit muss ja in den Zählbereich des Timers passen, und der ist nur 256, denn der Tiny13 hat nur einen 8-Bit-Timer. Mit einem AVR, der über einen 16-Bit-Timer verfügt, geht ICP besser, einerseits wegen des größeren Wertebereiches von 65536, andererseits wegen der verfügbaren Hardware-ICP-Einheit. > Aber obwohl ich TCNT0 immer auf 255 setze bekomme ich nur alle > 10µs einen Interrupt? Das verstehe ich jetzt nicht... Wiso setzt Du TCNT0 auf 255? Wenn Du Impulsdauer messen willst, dann brauchst Du den Timer überhaupt nicht auf irgendeinen Wert zu setzen. Du brauchst den Timer doch nur im externen Interrupt zu lesen. Den Timer lässt man frei durchlaufen, das hat den angenehmen Nebeneffekt, dass man nebenher noch einen (oder auch beide) Compare-Interrupts benutzen kann, um Zeiten zu erzeugen, z.B. für serielle Ausgabe. Ich glaube fast, Du hast eine völlig falsche Vorstellung von der Funktionsweise des ICP (egal ob in Hardware oder Software) und versuchst, die Impulsdauer durch Pollen des Portpins und Zählen im Timer-Interrupt zu realisieren. Das ist für langsamere Impulse zwar auch ein praktikabler Weg, ist aber kein ICP. Unter dem Aspekt, dass Du vielleicht im Timer-Interrupt pollen und zählen willst, bekommt Deine Aussage: > Ich würde gerne auf 1µs genau messen. Dazu muss ich wohl auf 9,6MHz > takten. eine andere Bedeutung. Ein Interrupt-Intervall von 1ms bekommst Du mit 9,6MHz Controllertakt nicht hin, da alleine der Aufruf des Interrupts und dessen Rücksprung etwa 10 Takte braucht. Dazu kommt noch SREG-Sicherung und die eigentliche Arbeit. Unter 20-30 Takte wirst Du (in ASM) nicht auskommen, in einer Hochsprache vermutlich mehr. ...
Gast
#1191856
Hallo, also ich dachte eher daran eine Variable "runtime" in der ISR hochzählen zu lassen und somit die Zeit zu messen. Aber du hast recht: Einfach den Timer Zählen lassen und den Timerstand auszulesen ist natürlich deutlich schneller -- wenn auch weniger genau. Ich probiere es... Ich möchte Zeitspannen im Bereich 10µs bis 250µs messen. > also ich dachte eher daran eine Variable "runtime" in der ISR hochzählen > zu lassen und somit die Zeit zu messen. Das ist auch eine akzeptable Methode, ist aber kein ICP. 8-( Software-ICP mit externem Interrupt als Flankentrigger und einem Timer-Vorteiler von 1:8 (bei 9,6MHz Controllertakt) erlaubt einen Messbereich bis 213µs. Vielleicht kannst Du ja Deine Ansprüche korregieren. Ergänzend kannst Du ja auch eine Compare-Einheit auf den ICP-Zeitstempel des Impulsbeginns setzen und mit dem Compare-Interrupt den Übertrag zählen. Dann macht es vielleicht auch Sinn, mit Timer-Vorteiler 1:1 zu arbeiten. Die ermittelten Zahlen sind dann allerdings nicht im 1ms-Raster, das Ergebnis müsste also noch skaliert werden. Besser fährst Du mit einem AVR, der mit 1MHz bzw. 8MHz intern läuft (z.B. Tiny2313). Der hat dann (meist) auch Hardware-ICP am 16-Bit-Timer. Mit 8MHz Controllertakt und Timer-Vorteiler 1:8 erhält man das Ergebnis im Raster von 1µs. Dann sind auch noch genug Pins vorhanden, das Ergebnis auf einem LCD oder einer mehrstelligen gemultiplexten Siebensegmentanzeige anzuzeigen. ...
Gast
#1191960
Hallo, danke für die vielen Tipps! :-) Ich habe mich jetzt für die Methode mit dem Analog-Comparator-Interrupt (interne Referenzspannung) mit Timer entschieden. Da ich aber noch nie mit dem Analog-Comparator gearbeitet habe wollte ich nun erst einmal den Interrupt betrieb zu laufen bringen. Einstellen möchte ich: Interrupt bei fallender Flanke auf ADC1. Der Interrupt soll dann eine LED blitzen lassen. Leider funktioniert es nicht. Hier mein Code:
Gast
#1192007
Ich kann zwar kein C, aber 100ms Delay in der ISR ist tödlich. Auch das CLI und SEI ist Humbug, das macht die Hardware des AVRs alleine. ...
Gast
#1192755
Hallo, leider habe ich das Problem noch nicht gelöst bekommen. :-(
Gast
#1192771
>Ich habe mich jetzt für die Methode mit dem Analog-Comparator-Interrupt >(interne Referenzspannung) mit Timer entschieden. Wo ist der Timer? "Delay" zählt nicht! In der ANA_COMP-ISR musst du je nach eingestellter Flankenrichtung den Timer starten oder stoppen (bei steigender Flanke starten, bei fallender stoppen). Wenn der Timer gestoppt ist, liest man den Timer-Wert aus, speichert ihn in einer Varibalen und setzt ein Flag, damit das Hauptprogramm weiß, dass es eine neue Pulslänge gibt., die verarbeitet werden kann. Die Flankenrichtung kann man anhand der ACIS-Bits im ACSR feststellen und ein (Abfrage und Änderung von ACIS0 sollte reichen). Den Code mußt du dir jetzt aber selber ausdenken...
Gast
#1192803
Das Problem ist nicht das Timing... im ersten Schritt möchte ich eigentlich nur die den Interrupt auslösen und die LED aufblitzen lassen (bei fallender Flanke an PB0). Leider wird der Interrupt nicht ausgelöst oder zumindest die ISR nicht aufgerufen.
Gast
#1192807
Hi
>Ich habe mich jetzt für die Methode mit dem Analog-Comparator-Interrupt...
Und wo wird der initialisiert?
MfG Spess
Gast
#1192820
>Und wo wird der initialisiert? >ACSR = (0 << ACD) | (1 << ACBG) | (1 << ACI) | _(1 << ACIE)_ | (1 << ACIS1) | (1 << ACIS0); Oder nicht?
Gast
#1192825
Hi Entschuldige. Übersehen. MfG Spess
Gast
#1193632
Leider habe ich das Problem immer noch. Wo liegt der Fehler in meinem Code? Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|