Hallo,
ich suche für einen Atmega8 mit 16Mhz eine Wartschleife weil ich mit
delay_ms() nicht mehr auskomme leider kriege ich das irgenwie nicht
gebacken ich will Zeiten zwischen 3s und 300s überbrücken mir ist es
gegal wenn der AVR in der Zeit nix macht sollte halt relativ genau sein
( im µs Bereich). Kann mir da jemand helfen?
Schon mal vielen dank!!
Gruß
noop
noop schrieb:
> ich suche für einen Atmega8 mit 16Mhz eine Wartschleife weil ich mit> delay_ms() nicht mehr auskomme leider kriege ich das irgenwie nicht> gebacken ich will Zeiten zwischen 3s und 300s überbrücken mir ist es> gegal wenn der AVR in der Zeit nix macht sollte halt relativ genau sein> ( im µs Bereich). Kann mir da jemand helfen?
_delay_ms geht bis 65535 Sekunden, allerdings dann nur mit einer
Genauigkeit von max 100µs. Wozu braucht man bei einem 300s Delay eine
Genauigkeit im µs-Bereich? Wenn es wirklich so genau sein muss, solltest
du am besten einen Timer benutzen.
Hallo,
ich blick da noch net so ganz durch also ich hab einen Timer z.b. 8 Bit
und lass denn mit 16MHz/ 1024 laufen der kann maximal einen Wert von 256
dann kann der doch bis 0,16384s zählen oder ? und wie komm ich dann auf
z.b. 300s ?
Gruß noop
Hallo,
dann hab ich aber doch wieder die Zeit von der Zählerschleife mit
Variablen drin dann kann ich doch auch _delay_ms en paar tausend mal
laufen lassen oder ?
Du zählst die Überläufe mit bis du die fragliche Zeit erreicht hast.
Wenn ich nicht ganz daneben liege sind es 16,384ms die du mit dem 8bit
timer schaffst. Mit einem 16bit Timer wären es schon 4,194s. Bei jedem
Timeroverflow n+1 while n<x mit x=Wunschzeit/Zähldauer
@ noop (Gast)
Das macht man so. Stell deinen timer so ein, dass er z.B. mit 100Hz
einen Interrupt erzeugt, kann man mit dem CTC-Modus spielend
erreichen. In dem Interrupt wird dann eine Variable hochgezählt.
Erreicht die dann den gewünschten Wert, wird eine Aktion ausgeführt.
Aber an deiner Frage erkennt man, dass du noch VIIIIIELLE Grundlagen
durcharbeiten musst, ehe du dort was Gescheites machen kannst.
MFG
Falk
Zuerst überlegst du dir mal, in welcher Auflösung du deine Delays
brauchst (nicht zu fein, das ist problematisch, die 100 µs von oben sind
doch z.B. ein schöner Wert). Dann nimmst du einen Timer, der den
CTC-Modus beherrscht, und stellst ihn so ein, dass er Interrupts in
dieser Auflösung produziert. Im Interrupt zählst du einen Wert runter.
Das Warten ist dann nur ein Warten darauf, dass der Wert Null wird.
Bisschen Pseudocode:
Hallo,
wie bekomme ich denn den Timer dazu das der bei 100µs ein Interrupt
produziert weil ich kann ja z.b. den Timer 16Mhz/8 nehmen also 2 Mhz das
ergibt dann bei 256 Takten 128µs?
Gruß
noop
Du kannst z.B. den Teiler 64 nehmen, und dann bis 24 zählen lassen. Der
Timer0 des Mega8 kann aber keinen CTC Modus. Musst dann also Timer2
nehmen (wenn es ein 8-Bit Zähler sein soll).
Versuche jetzt aber nicht, das bis ins letzte Detail aus mir
rauszuleiern. Das Stichwort "CTC" ist völlig ausreichend, dass du dir
das selber zusammensuchen kannst. Im Datenblatt und dem Tutorial gibt es
haufenweise Infos darüber.
mal abgesehen davon das das durchaus möglich ist
(und wer weiß wie bekommt das auch im 5 min programmiert)
vermute ich einen Denkfehler bei 300Sek Wait und 100µS Genauigkeit
Erzähl uns doch mal was du vor hast...
Gruß Sven
Welches ist denn die kürzeste Zeit?
In welchen Zeitraster soll eingeschaltet werden? Also in welchen
Intervallen kann man zwischen der oberen und unteren Grenze die Zeit
einstellen?
>also ich brauch von 0,4s - 300s in 0,1s Schritten
Dann kann man den Timer so einstellen, dass er alle 100ms einen
Interrupt erzeugt, und in der ISR dazu einfach Variablen hoch- oder
runterzählen.
In der Hauptschleife guckt man dann einfach nach, ob die "Weckzeit"
erreicht wurde.
Das sollte man sogar mit dem Wissen aus dem Tutorium als "blutiger"
Anfänger an einem Tag hinbekommen.
Hi
zu deiner Sorge das die Schleifenaufrufe mitzählen.
Das machen sie bei Timer-Interrupts nicht. Der Timer läuft unabhängig
von der CPU (bis auf die Taktfrequenz). Wenn also die CPU gerade die
Schleife abarbeitet, läuft der Timer weiter. Kritisch wird es nur wenn
du zulange im Interrupt bist und der Timer noch einen Interrupt auslöst,
dieser wird dann übersehen.
In 100µs sollte das aber locker drin sein, baue aber kein Delay ein :-)
Hallo,
hab mal was rumgebastelt nur warum kann ich das im AVR Studio nicht
vernünftig Simulieren wenn ich über den Teil springen will und dahinter
einen Breakpoint setze dann zeigt der als Stop Watch nur ca 470µs an
woran liegt das er müsste doch 1s anzeigen
1
OCR2=6250;// Wenn Timer bis 62500 gezählt hat dann Ereigniss auslösen und clearen
noop schrieb:
> oh sry hab mich vertippt müsste OCR2 = 62500; heißen
Wieso tippst du Programmcode ab?
Copy&Paste und schon hast du diese blöden Tippfehler nicht mehr und wir
suchen nicht Probleme die du in deinem realen Code gar nichts hast.
okay hab jetzt den 1024 teiler genommen kann dass es daran liegt das der
Compiler mir ne Fehlermeldung rausgibt: warning: large integer
implicitly truncated to unsigned type
1
OCR2=15625;// Wenn Timer bis 15625 gezählt hat dann Ereigniss auslösen und clearen
noop schrieb:
> okay hab jetzt den 1024 teiler genommen kann dass es daran liegt das der> Compiler mir ne Fehlermeldung rausgibt: warning: large integer> implicitly truncated to unsigned type
Der Hinweis des Compilers ist schon nicht schlecht.
Timer 2 ist ein 8 Bit Timer. In 8 Bit passt nichts größeres rein als
255. Wie willst du daher 15625 in 8 Bit unterbringen? Dazu musstest du
mindestens über 14 Bits verfügen, die du aber nicht hast
noop schrieb:
> ich dachte der timer 2 ist ein 16 bit Timer?
Im Zweifelsfall hilft immer: Datenblatt lesen
Und auch im Nichtzweifelfall ist Datenblatt lesen immer eine gute Idee.
okay :-) also nehm ich dann mal Timer 1 :-) pack ich den timer jetzt in
eine For-Schleife und lass die dann entsprechend ausführen oder wie
mache ich das am besten um auf die gewünschte Zeit zu kommen ?
noop schrieb:
> okay :-) also nehm ich dann mal Timer 1 :-) pack ich den timer jetzt in> eine For-Schleife und lass die dann entsprechend ausführen
Das Prinzip, das du benutzt hast, kannst du ja weiterbenutzen (Das Flag
aber auch löschen ehe du den Timer startest. Kein Mensch garantiert dir,
dass das zurückgesetzt ist). Du bist nur darüber gestolpert, dass Timer
2 nicht so weit zählen kann, wie du es brauchen würdest.
> oder wie> mache ich das am besten um auf die gewünschte Zeit zu kommen ?
Das kommt immer darauf an, wie genau die die Zeit brauchst.
Im einfachsten Fall lässt man sich von einem Timer einen periodischen
Interrupt auslösen und zählt in der ISR eine Uhr hoch. Frei nach dem
Motto: Wenn ich 10 mal 1 Sekunde gewartet habe, hab ich in Summe auch 10
Sekunden gewartet.