Hallo, ich habe mich ein wenig in die Theorie zum Thema des Timers in AVR eingelesen. Allerdings weiß ich nicht wie soetwas praktisch aussehen würde. Angenommen ich möchte eine Led genau 2sec einschalten und 2 sec ausschalten. (Mit einem Atmega8) Wie mache ich das? Gibt es irgendwo ein einfaches Beispiel wo man sich soetwas anschauen könnte. Wie gestalte ich den Timer dass ich ihn im Sekundentakt verwenden kann. Müsste man das mit Vorteiler machen? Aber wie? Danke...
Artikelsammlung - nicht gesucht, nicht gefunden oder nicht verstanden? Z.B. https://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer bietet doch einiges.
S. Landolt schrieb: > Artikelsammlung - nicht gesucht, nicht gefunden oder nicht verstanden? > Z.B. > https://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer > bietet doch einiges. doch habe ich gesehen...werde ich gleich mal ausprobieren.
Ich habe das Beispiel im AVR Studio durchgespielt. Wenn ich den Prescaler erhöhe, z.b auf 1024 dann reduziert sich meine Frequenz. Aber ich wüsste immer nicht wie ich etwas im Sekundentakt ansteuere. Ich habe eine Aufgabe vorliegen, da sollen 2 Ausgänge geschaltet werden. Der erste Einschaltverzögert mit 3 sec. Der zweite Ausschaltverzögert mit 5 sec. Würde mich über Hilfe freuen.
Hallo O. A., im Datenblatt des Atmega8 findet man Informationen über 8 Timer. Jeder Timer[0-2] hat andere Eigenschaften, insbesondere lässt er sich unterschiedlich einstellen. Je nach Einstellung und Timervorteiler ergeben sich eine andere Berechnung, dazu findet man eine Formel im Datenblatt. *8-bit Timer/Counter0* ... *16-bit Timer/Counter1* unter "Modes of Operation" findet man: # Normal Mode # Clear Timer on Compare Match (CTC) Mode # Fast PWM Mode # Phase Correct PWM Mode # Phase and Frequency Correct PWM Mode *8-bit Timer/Counter2* ... _Beispiel_: Wir setzen Timer1, im CTC Modus Aus Tabelle 39 lesen wir ab: Mode = 4 --> WGM1[3-0] = 0b0100 Zählregister ist OCR1A Im Datenblatt auf Seite 88 finden wir folgende Formel: f_OC1A = F_CPU / (2 N (1+OCR1A)) Diese kann man einfach umstellen --> Schule: f_OC1A = F_CPU / (2* N* (1+OCR1A)) <==> 2* N* (1+OCR1A) = F_CPU / f_OC1A <==> 1+OCR1A = F_CPU / (f_OC1A *2 *N) <==> OCR1A = F_CPU / (f_OC1A *2 *N) -1 Wobei N E {1,8,64,256,1024}, der Timer1 Prescaler ist N ist dabei die "Abstufung" für den Timer. Reale Rechnung in meinen Programmen: F_CPU = 8*10⁶ ; [Hz] f_OC1A = 1000 ; [Hz] Da OCR1A eine 16Bit Werte Aufnehmen kann, muss für die Rechnung der passenden Timer1 Prescaler gewählt werden. OCR1A = 8*10⁶ /(1000 *2 *N) -1 OCR1A = 8*10³ /(2 *N) -1 Wir setzen hier N = 8: OCR1A = 8*10³ /16 -1 OCR1A = (500 -1) Wäre N = 1, so folgt: OCR1A = 8*10³ /2 -1 OCR1A = (4000 -1) Wir sehen also für N = {1,8} ergeben sich sinnvolle Einstellungen, um eine 1000Hz Schwingung zu erzeugen.
O. A. schrieb: > Aber > ich wüsste immer nicht wie ich etwas im Sekundentakt ansteuere. Wichtig ist, dass du erstmal sowas wie ein Timer Tick hin bekommst. Das scheinst du ja schon geschafft zu haben.... Dann brauchst du einen Tick Zähler im Speicher. Und immer, wenn 1 Sekunde erreicht, dann tue dein Ding. Die Anwendung der Grundrechenarten und ein paar Vergleiche reichen dafür....
Oh, da gibt es viele Wege! (... sagte der Geist und strahlte) Eine Art Uhr und dann rechnen, hat bereits Arduinos Fanboy vorgeschlagen. Wenn man etwas mehr über Timer lernen will, dann für jede Teilaufgabe einen eigenen Timer nehmen, der ATmega8 hat ja deren 3. Und dann gibt es sicher noch ein halbes Dutzend Variationen davon. Haben Sie denn schon eine Idee oder einen Ansatz, den Sie uns vorzeigen können und worauf sich aufbauen lässt?
In Ergänzung des Beispiels aus dem Artikel hier etwas mit den verlangten 3 Sekunden, minimalistisch, d.h. ohne Interrupt (führt in dieser Form jedoch in eine Sackgasse, dient also nur zur Anschauung bzw. zum Lernen).
1 | ; cave: setzt Startwerte nach Reset laut Datenblatt voraus |
2 | |
3 | .include "m8def.inc" ; mit Werkseinstellung: 1 MHz |
4 | |
5 | .equ DDR_A1 = DDRB ; Ausgang1: einschaltverzoegert 3 s |
6 | .equ PORT_A1 = PORTB |
7 | .equ A1 = 0 |
8 | |
9 | .def tmp0 = r16 |
10 | |
11 | .cseg ; flash |
12 | .org $0000 |
13 | |
14 | sbi DDR_A1,A1 ; Pin auf Ausgang schalten |
15 | |
16 | ; Startereignis: |
17 | ; keine Ahnung |
18 | |
19 | ; Ausgang1: Timer1 mit 1 ms -> 3 s |
20 | cbi PORT_A1,A1 ; ausschalten |
21 | ldi tmp0,high(3000) ; Timer1-Output-Compare auf 3000 (ms) |
22 | out OCR1AH,tmp0 |
23 | ldi tmp0,low (3000) |
24 | out OCR1AL,tmp0 |
25 | ldi tmp0,(1<<CS12)|(1<<CS10) ; 1 MHz /1024: so etwa 1 ms |
26 | out TCCR1B,tmp0 ; Start |
27 | |
28 | loop: |
29 | in tmp0,TIFR ; warten, bis Timer1 auf 3000 (ms) |
30 | sbrs tmp0,OCF1A ; gezaehlt hat |
31 | rjmp loop |
32 | |
33 | sbi PORT_A1,A1 ; einschalten |
34 | |
35 | rjmp pc |
S. Landolt schrieb: > In Ergänzung des Beispiels aus dem Artikel hier etwas mit den verlangten > 3 Sekunden, minimalistisch, d.h. ohne Interrupt (führt in dieser Form > jedoch in eine Sackgasse, dient also nur zur Anschauung bzw. zum > Lernen). Verlorene Liebesmüh'. Der Kerl will einfach nur seine Hausaufgaben von einem anderen für lau gemacht bekommen. Der ist weder willig, sich irgendwas anzuschauen, noch will er irgendwas lernen.
O.A. hat in gepflegter Form um Hilfe gebeten. Er hat meine Eingangsfrage indirekt beantwortet: "nicht verstanden". Ich vergebe mir nichts mit dieser Fingerübung. Warum sollte ich nicht versuchen, ihm zu helfen?
c-hater schrieb: > Verlorene Liebesmüh'. Der Kerl will einfach nur seine Hausaufgaben von > einem anderen für lau gemacht bekommen. Der ist weder willig, sich > irgendwas anzuschauen, noch will er irgendwas lernen. Es gibt noch etwas, was vergebliche Mühe bedeutet: Auch nur einen Satz von Deinem immer gleichen Gesülz für bare Münze zu nehmen.
S. Landolt schrieb: > Warum sollte ich nicht versuchen, ihm zu helfen? Weil Hilfe auch kontraproduktiv sein kann. Wenn der Kerl sich in seiner Auffassung des Lebens bestätigt sieht (man muss nur einen Idioten finden, der mir das für lau liefert) wird er zeitlebens ein Sozialfall sein und damit schädlich für sich und die Gesellschaft. Das ist in etwa so, als wenn du einem Drogenabhängigen als "Hilfe" die nächste Dosis seines Gifts besorgst... Er hatte im Thread bereits alles bekommen, was nötig ist, um aus eigener Kraft das Problem lösen zu können. Das ist echte Hilfe. Hilfe zur Selbsthilfe. Das schöne Bild: gib dem Hungernden keinen Fisch, sondern erkläre ihm Bau und Benutzung einer Angel. Dann steht er nämlich nicht morgen schon wieder bei dir auf der Matte und bittet um Mitleid und Almosen...
Ich hatte, im Gegensatz zu Ihnen, den Eindruck, dass O.A. eben noch nicht alles Nötige bekommen hatte, nicht bei seinem Kenntnisstand. Und für mich gilt auch hier der alte Geschäftsgrundsatz 'Ich muss den Kunden dort abholen, wo er steht'. Was nun aber den Begriff 'Sozialfall' angeht, so kann man diesen auch ganz anders interpretieren! Damit ist aber das Thema für mich durch, ich wünsche Ihnen einen Guten Abend.
Ich weiß nicht welche Mission du hast C-hater. Anstatt hier irgendwelche unnötigen Diskussion über mich anzufangen, bitte ich dich inständig: Vergeude doch einfach nicht deine Zeit mit einem Sozialfall wie mir. Und für die anderen Antworten möchte ich mich schonmal bedanken, ich werde es mir morgen in aller Ruhe anschauen.
:
Bearbeitet durch User
Kinderkram wie das Hausaufgaben Problem musste der Betroffene nach seinem Bericht schon vor 30 Jahren machen,ohne dass es wohl was gebracht hat, aber eine etwas andere Wortauswahl bzw.Vorstellung der Tätigkeit eines Timer/ Counter kann (muss nicht) evtl. helfen das Problem zu finden. Nicht nur im deutschen wird Hz genauso für Anzahl der Schwingungen und Anzahl der Tätigkeiten je Sekunde genutzt, was ja auch häufig sehr eng verbunden ist, aber manchmal für den einen die eine Betrachtungsweise und den andere verständlicher macht. Etwas albern eine altmodische Uhr mit 2 Hz (Tick + Tack)/sek vorgestellt bei der der Prescaler 60 gerade in der Werkstatt ist und mit 8 bit 30min gewartet werden soll. Prescaler 2 (wg. Zeiger) 10,100,1000 sind noch in Ordnung, aber ohne den gewohnter 60er ist das fast wie die andere Aufgabe. Der erste Versuch mit praktischem 1min-Tick : 1 Min==60s*2 Tätigkeiten/sek[2Hz] == 120 Tätigkeiten bzw. Takte vom Prescaler zumindest bis 60 zählen zu lasen geht wg. der Werkstatt schief Der zweite Versuch: 30min = 30*60*2 Tätigkeiten = 360TfZ [TfZ:zu zählende (T)ätigkeiten (f)ür die (Z)eit] mit Prescaler 10 passt dann in ein byte und ein Programm könnte:
1 | prescaler10 timer //'Vorzähler' tick/tack/tick/....und |
2 | |
3 | bool compZ (int anz_tät){ ret= timer > anz_tät} |
4 | |
5 | lampe_aus |
6 | while !compZ(36)do ; |
7 | lampe_an //30min gewartet |
sehr sehr ungefähr so aussehen. Die Funktion compZ ist praktisch schon im counter eingebaut und wird ansonsten eher mit
1 | loop: |
2 | in tmp0,func(compZ)+div.t_flags ; warten, bis Timer1 auf 30 (min) |
3 | sbrs tmp0,flagbit(compZ) ; gezaehlt hat |
4 | rjmp loop |
aufgerufen. Beim dritten Versuch die Uhr dann mit 8MHZ übertakten und nachzählen wie viele Tätigkeiten (bei timern/coutern meist Berechnung von t=t+1 ) von den 8 Millionen in der Sekunde gezählt werden müssten bis eine Sekunde vorbei ist....
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.