PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Länge eines Pulses messen



waxology
20.08.2007, 12:53
Hallo,
hab das Problem das ich die länge eines Pulses mit einem Atmega644 messen will ich aber bisher nicht so erfolgreich damit bin.
Ausgangssituation:
Ich bekomme an einem Port des AVRs ein Signal davon will ich messen wie lange das Signal high ist. Die Tx eingänge kann ich nicht nutzen da sie bereits mit anderen funktionen belegt sind, sonst könnte ich bei steigende flanke den counter loszählen lassen:-(!!!
Habe leider den quelltext nicht da aber im grunde funktioniert es so:
ich lasse den counter loszählen sobald ich an pin7 ein high bekomme danach lasse ich mir den wert des tcnt ausgeben.
Doch bei einem konstanten Signal bekomme ich verschiedene Werte???
Vielen Dank schonmal für sämtliche hilfen

p.s. wie kann ich eigentlich zwei 8bit counter kaskadieren???

askazo
20.08.2007, 15:23
Du kannst beim 644 doch jeden I/O als externen Interrupt verwenden. Damit ist's doch dann kein Problem mehr, auf eine steigende bzw. fallende Flanke zeitnah zu reagieren.

askazo

franzl
20.08.2007, 15:31
Hi,
das Problem wird folgendes sein, da du ja auch ein Hauptprogramm mit bestimmter Zykluszeit hast kann sich die gemessene Signallänge im ungünstigsten Fall um die Zykluszeit verlängern. Da du deinen Port wahrscheinlich nur einmal im Programm abfrägst.
Hoffe ich konnt dir weiterhelfen.
mfg franz

askazo
20.08.2007, 15:37
@franzl: Ja, genau da liegt das Problem. Und dem kann man abhelfen, indem man auf das Messsignal mit einem Interrupt reagiert.

@waxology: Die T0 bzw. T1-Pins würden Dir im übrigen auch nicht helfen - die dienen nur als externe Taktquellen für die Counter, nicht als Start-/Stop-Signalquellen.

askazo

Yossarian
20.08.2007, 16:08
Hallo
lade einen Kondensator und messe die Spannung.

Mit freundlichen Grüßen
Benno

Gock
20.08.2007, 16:12
Wenn man sowas vorher weiß, dann legt man den Puls, dessen Länge man bestimmen will an den ICP Pin des µC. Der ist nämlich genau dafür da!
Der sorgt auf komfortable Weise dafür, dass der Counter genau solange countet, wie dort High oder Low anliegt, wie man will. Da das ganze IRQ gesteuert ist, muss man sich keinen Kopf machen und hat die Probleme des Pollens nicht.
Gruß

askazo
20.08.2007, 17:19
Huch, den ICP kannte ich auch noch nicht.
Danke Gock, gut das zu wissen :)

askazo

Gock
20.08.2007, 17:48
Da sieht man 's wieder: Man lernt nie aus! ;-)
Wenn der ICP nicht mehr frei ist, lässt sich das auch über den AnalogComparator steuern. Mit ein bisschen Geschick ist es sogar möglich, die ADC Eingange auf den AnalogComparator zu multiplexen, dann kann man theoretisch auch diese benutzen. Habe ich aber noch nicht gemacht und lege daher keine Hände in irgendwelche Feuer.
Gruß

waxology
20.08.2007, 18:04
erstmal vielen dank für alle antworten:-)
so das ich alle pins als externen interrupt nutzen konnte wusste ich noch nicht:-) dachte da gibt es nur die Tx pins die eine flanke erkennen und dann z.B. den counter starten.
aber jetzt mal ne frage im datenblatt zum 644 steht das die externen Interrupts nur dann funktionieren wenn die pins als ausgang geschaltet sind?!? müsste aber doch ein eingang sein um überhaupt ne unterbrechung zu machen?!? wie fange ich den ab??? in meinem quelltext frage ich an PIND ab ob da 0x80 anliegt (pin7 gesetzt, da liegt das signal an) und lass die schleife solange laufen bis das nicht mehr der fall ist.
Mit dem ICP pin wäre das bestimmt ne gute Sache aber hab gesehen das nur einer am 644 ist und denke der ist belegt. ist das den überhaupt so möglich wie ich mir das vorstelle oder hab ich nen großen denkfehler???

askazo
20.08.2007, 19:18
Im Datenblatt steht lediglich, dass die Interrupts - wenn sie denn aktiviert sind - auch dann ansprechen, wenn Du den Pin als Ausgang definiert hast. So könnte man z.B. einen Software-gesteuerten Interrupt generieren.
Bei normaler Verwendung der externen Interrupts muss der entsprechende Pin natürlich als Eingang konfiguriert sein.

Der Interrupt wird mit einer Interruptroutine abgefangen. Im GCC sieht das dann so aus:

ISR (<Name des Interrupts>)
{
<Wenn Timer nicht läuft>
<Timer starten>
<ansonsten Timer stoppen>
}

Den Namen des Interrupts findest Du in der io.h für den 644. Ich habe hier auf dem Rechner GCC nicht installiert, kann also leider gerade nicht nachschauen.

askazo

waxology
22.08.2007, 06:58
Also hab das nun mit dem Interrupt probiert aber irgendwie komm ich damit auch nicht weiter mein Quelltext sieht ungefähr(was ich jetzt noch im kopf habe) so aus:


ISR(PCINT3_vect) // der Auslösende Interrupt PCINT31
{
TCNT0 = 0; //der Counter wird zurückgesetzt auf 0
}
...
uint8_t zeit;
TCCR0B = 0x01; //Counter starten mit Systemtakt
TMSK3 = _BV(PCINT3); //Interrupt an PD7 enable
PCICR = _BV(PCIE3); //Interrupt enable
zeit = TCNT0;


So hoffe ist originalgetreu, jedenfalls es klappt er lösst den Interrupt aus, habs vorher ausprobiert indem ich zeit global gemacht habe und beim interrupt auf 1 gesetzt habe.
Aber Wieder bei einem konstanten Signal ändert sich die Zeit.
Ist es vll. möglich das die flanken sich so schnell ändern das der µC nicht hinterher kommt??? (Kann es mir eigentlich nicht vorstellen da auf dem oszi die die zeit zwischen steigende/fallende Flanke 1ms beträgt)