Hi Leuts, folgendes: Ich habe hier einen ATMega16 auf dem STK500 und zwei externe Signale, A und B. Diese Signale können 3 Zustände haben: 0V, 5V oder Rechteckimpulse mit ca. 4 Hz. Ich muss alle drei Zustände auswerten. Nun dachte ich, ich könnte mir mit externen Interrupts helfen, deshalb habe ich die Signale auf INT0 und INT1 verdrahtet. Variante 1: Für eine bestimmte Zeit (beispielsweise 600 ms) zähle ich die Flankenwechsel Variante 2: Ich zähle die Zeit zwischen den Flankenwechseln. Nun gehts aber schon generell beim Timing los: Ich habe mir also eine Timer-Overflow-Routine geschrieben, die alle 5 ms aufgerufen wird. Zur Kontrolle toggel ich bei jedem Aufruf PORTA.0. Lt. Oszi klappt das, auch wenn die Werte für TCNT0 nicht nachberechnen kann. Nun möchte ich für rund 600 ms messen, bei einem Aufruf alle 5 ms muss ich also nur bis 120 zaehlen, dann sind 600 ms um. Stimmt aber nicht, das Signal verschleift irgendwie total. D.h. wenn ich bei einem Zählerstand von 120 ein Pin toggle, dann sind die 1 und 0 Zeiten unterschiedlich lang, und einen Zusammenhang mit 120 kann ich nirgendwo entdecken. Also habe ich wohl ein grundlegendes Problem mit den Timern. Oder ? Greets Karlheinz
Ist das Signal mit 4Hz frequenzstabil oder variiert die auch noch? Ohne einen Blick auf deinen Quellcode würde ich folgendes vorschlagen: Bei jedem externen Interrupt einen Timer so zurücksetzen, dass er nach 125-150ms (eine Periodenhälfte) überläuft. Bei konstantem Pegel auf der Leitung kommt es zum Überlauf. In der INT0-ISR würde ich eine LED setzen, die den Flankenwechsel anzeigt. In der Timer-Überlauf-ISR würde ich diese LED dann löschen, und dafür pegel-abhängig eine andere setzen. Insgesamt also 3 LEDs... Bei mehr als einem Interrupt könnte man einen Timer verwenden, der regelmässig (100µs oder so) ein Interrupt auslöst. In dessen ISR werden dann für jeden Interrupt Variablen heruntergezählt, und bei 0 ein Überlauf detektiert... Auf dein Problem mit den Timer bin ich jetzt nicht eingegangen... Hab die Fragestellung / das Problem wohl auch nicht ganz verstanden.
Hallo, Das cli() und sei() in der ISR kannste Dir sparen, das passiert automatisch! Abgesehen davon hast Du den INT0 als Low-Level-sensitiv initialisiert. Du inkrementierst Dein nCounterA (wie ist das überhaupt initialisiert??) ständig mit hoher Rate, so lange das TFlagA gesetzt ist. Da kann dann kein sinnvoller Wert drinstehen! Gruß Johnny
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.