Hallo Fachmänner ;-)
Zuerst: Compiler AVR-GCC
Controller: ATTiny2313
Folgendes Problem habe ich.
Ich habe mir eine Schaltung für meinen CarPC gebaut welche das
Powermanagement
übernehmen soll. Unter anderen habe ich mit dem Analog Komparator einen
Schutz eingerichtet, welcher mir den Rechner automatisch runterfährt
sobald die Akkuspannung unter 11,6V sinkt.
Nun das Problem:
Angenommen das Fahrzeug ist aus, Rechner ist an und die Akkuspannung ist
über 11,6V.
Wenn ich jetzt den Motor starte, bricht kurzzeitig die Spannung an der
Batterie ein. Bei diesem Einbruch fährt mir meine Schaltung aber sofort
den Rechner runter, was ja beim Motorstart nicht sein soll weil der Akku
eigentlich nicht leer ist.
Also dachte ich mir, ich lasse den Rechner nur dann runterfahren wenn
der gemessene Akkuzustand von 11,6V mindestens zwei Sekunden lang wahr
ist.
Müsste ich mit dem Timer machen. Laut Datasheet kann ich den Komparator
mit dem Timer verbinden.
Zweites wäre: Ich möchte den 8-Bit Timer benutzen.
Bei einem Systemtakt von 8MHz und einem Prescaler von 1024 würde der
Timer Overflow Interrupt pro Sekunde 30 mal ausgelöst werden (8Mhz /
1024 / 255; richtig gerechnet?). Wie kann ich denn den Timer auswerten
dass er mir erst nach 2 Sekunden in meine PC-Shutdown routine reinläuft?
Das Ergebnis des Timers nach 2 Sekunden müsste 15625 sein (richtig?)
Mein gedanke wäre jetzt, in der Timer Overflow routine die
Timerergebnisse so lange zu addieren bis ich einen wert von 15625 habe
und dann erst in die Shutdown Routine reinspringen. Würde das so
funktionieren oder wird das Ergebnis (TCNT-Register) vor dem Auslösen
des Overflow Interrupts auf 0 zurückgesetzt?
Hoffe ich habe gut genau erklärt was ich vorhabe.
Danke schonmal an alle im Voraus.
MfG Konrad
Hallo,
ich kenne ja Dein Konzept nicht, aber bei mir läuft eigentlich immer ein
10ms Timer für alles mögliche von Uhr über Tastenentprellung usw.
Ich würde nur in jedem Timer-IRQ nach den Comparator schauen, ist
Spannung kleiner als Sollwert -> Variable erhöhen -> Testen, ob größer
als 2s (200 bei 10ms IRQ). Ist die Spannung im Sollbereich -> Variable
auf 0 setzen.
Gruß aus Berlin
Michael
Ok hört sich auch nett an :)
Wie stelle ich denn den Timer ein damit die ISR jede 10ms aufgerufen
wird?
Damit hab ich noch so meine Probleme.
Dann schreibst du: Testen ob größer als 2s.
Also wenn der Komparator kippt meinst du soll ich die Variable erhöhen,
wenn beim nächsten Vergleich immer noch gekippt wieder um eins erhöhen,
und wenn mein Variablenwert 200 erreicht, erst dann runterfahren?!
Wenn der Komparator zwischendurch bei auslesen nicht gekippt ist einfach
meine Zählervariable wieder auf 0 setzen. Verstehe ich dich richtig?
Hallo,
ja, genau so. Damit werden dann kurze Einbrüche sicher ignoriert.
Die Zeit selbst sollte ja nicht sonderlich kritisch sein.
Timer 0 auf CTC-Mode, Vorteiler auf 1024 und Compare auf 77 sollten
8000000/1024 = 7812,5 / (77+1) = 100,16 Hz
1000/100,16= 9,984ms wenn ich jetzt auf die Schnelle richtig gerechnet
habe.
Damit kommst Du bei einem 8-Bit Zähler in der IRQ auf maximal 2,55s.
Wenn Du IRQ nur dafür nimmst, kannst Du natürlich auch mit grüßerem
Compare-Wert arbeiten, mit 144 wären dann maximal rund 5s Wartezeit drin
usw.
Zum Code kann ich jetzt nichts sagen, benutze ASM, kein C...
Gruß aus Berlin
Michael
Ich bin zu blöd für diese ganzen vielen Register hier...
Dieser CTC-Mode schaltet die OCnB Pins durch, da ist an meiner Schaltung
aber nichts angeschlossen...
Kann mir denn nicht jemand mal nen Tritt verpassen wie ich den Timer
initialisieren muss ?! Also welche Bits ich setzen muss und welche
nicht. Ich blicke da nicht durch, sorry.
Hallo,
er kann das machen, wie auch einige andere Modi, er muß aber nicht und
Du brauchst das ja auch nicht.
Von vorn:
wir brauchen einen Interrupt in festem Zeitabstand, dafür bietet sich
CTC an, weil der alles alleine macht.
Der zählt aufwärts bis der Wert in TCCR0A erreicht ist, setzt das
Compare-IEQ-Flag und setzt den Zähler auf 0 und der zählt wieder bis
TCCR0A usw. usw.
CTC ist WGM01 in TCCR0A auf 1, WGN00 auf 0, die COM0A und COM0B-Bits
bleiben auch alle 0, weil keine Ausganbe des Taktes nütig ist.
Dazu in TCCR0B noch CS00 und CS02 auf 1 für Prescaler 1024, Rest bleibt
auf 0.
Nun noch OCR0A miz 77 (oder eben anderen Top-Wert) geladen.
In TIMSK noch OCIE0A setzen für Interrupt bei Comparematch Register
TCCR0A und fertig.
Interrupt-Routine schreiben für den CompareMatchA-IRQ (OC0Aaddr) von
Timer0 und globale IRQ mit SEI freigeben.
IRQ-Routine dann etwa so:
if comparator = 1 (ok, sonst eben andersrum...)
zaehler = 0
else (zu niedrig...)
zaaehler = zaehler+1 ; erhöhen
if zaehler > max
flag = du_sollst_runterfahren ;)
endif
endif
Gruß aus Berlin
Michael
Rush wrote:
> Ich bin zu blöd für diese ganzen vielen Register hier...> Dieser CTC-Mode schaltet die OCnB Pins durch, da ist an meiner Schaltung> aber nichts angeschlossen...
Nö, tut er nicht.
Die Pins werden erst mit dem Timer verbunden, wenn Du das explizit mit
den COM0B0 und COM0B1 Bits so einstellst.
Wenn ich ne Timerfunktion einstellen will, gehe ich einfach ins
Datenblatt unter Register Description (T0: Seite 77).
Jedes Bit ist da schön erklärt.
Und dann arbeite ich die Register der Reihe nach ab, also TCCR0A, TCCR0B
usw.
Peter
Im Simulator scheint es einwanfrei zu funktionieren.
wenn ich es aber in meinen Tiny schiebe leuchtet PD0 kontinuierlich.
Auch wenn ich den Taster PB0 am STK500 drücke tut sich garnichts, LED
leuchtet immer noch durch. Was habe ich denn falsch gemacht? Oder hab
ich hier einfach nur irgendwo einen Denkfehler drin?
Danke schonmal.
MfG Konrad
Mal so auf die schnelle einen Code zusammenfriemeln ist wohl doch nicht
so prickelnd habe ich festgestellt. Hier mein Code für alle die nach
einer Lösung suchen der funzt.
@Michael U.
Danke für die Idee, klappt wunderbar. Nur noch ein mein Progg einbinden
und fertig.