Hallo, ich bin gerade dabei mir einen Wecker selbst zu bauen. Als Basis dient der ATmega 16. Momentan arbeite ich an der Sequenz, die die Netzfrequenz als Zeitgeber nutzen soll. Dazu will ich einen Counter nehmen. Mein Problem ist eigentlich ein simples Rechenproblem. Wie hoch muss ich den Counter vorab füllen, damit bei 100 Ticks pro Sekunde nach genau einer Minute ein Interrupt ausgelöst wird? Rein logisch wäre ich jetzt so vorgegangen: 100 Ticks sind eine Sekunde 6000 Ticks sind eine Minute Maximalwert des Timer1 als Counter: 65535 65535 - 6000 = 59535 Ist das korrekt? Ich bin etwas verunsichert weil der Counter ja bei 0 anfängt zu zählen. Wäre sehr nett wenn da jemand drüberschaut!
Lass den Counter bei 0 anfangen zu zählen. Dann lässt du ihn 6000 Schritte zählen. Lässt also beim 6000sten Schritt einen Interrupt auslösen, in dem du dann deine Minuten aktualisierst. MfG Chaos
Rechenproblem schrieb: > die die Netzfrequenz als Zeitgeber > nutzen soll. Rechenproblem schrieb: > damit bei 100 Ticks pro Sekunde
:
Bearbeitet durch User
Netzfrequenz, also 50 Hz. Da ich sie aber zuerst mit einem Trafo auf gefahrlose 6V reduziere und dann gleichrichte (Brückengleichrichter) verdoppelt sich die Frequenz. Also 100 Hz. @chaoskind: Wie geht das? Bisher habe ich immer mit vorab gefüllten Countern gearbeitet. Zum CTC-Modus habe ich hier nur ein Beispiel für C gefunden, ich arbeite jedoch mit Bascom :/
Hm mit Bascom kann ich dir da auch nicht weiterhelfen. Davon hab ich keine Ahnung. Aber prinzipiell kannst du den CTC-Modus so einstellen, das er entweder bis zum Wert im ICR-Register zählt, oder bis zum Wert im OCR-Register. Dann musst du noch den Interrupt und die globalen Interrupts freigeben. Frag mich aber nicht, wie das in Bascom geht... In Assembler ist das auch recht fix gelöst zur Not. (Fand ich recht leicht zu lernen, zumindest in den Grundzügen, und man lernt den Controller vor allem sehr gut kennen)
Udo schrieb: > Wieso verdoppelt sich die Frequenz nach dem > gleichrichten ? Vermutlich werden die Nulldurchgänge gezählt?
Rechenproblem schrieb: > Wie geht das? So weit ich weiß Veröffentlicht jeder herstrsteller zu seinen uCs ein Datenblatt in dem man alles was man über den Controller wissen muss finden. Oder ist Atmel da eine ausnahme?
Zum Datenblatt noch eine Liste mit den Assemblerbefehlen, und los geht der wilde Spass ;-) Die findet sich im übrigens auch im Datenblatt, irgendwo recht weit hinten, wenn ich mich recht entsinne.
:
Bearbeitet durch User
Udo schrieb: > Wieso verdoppelt sich die Frequenz nach dem > gleichrichten ? Ich klappe doch beim Brückengleichrichter die negativen Halbwellen nach oben. Das Signal wird durch einen Komparator digitalisiert und anschließend auf den Timerpin gelegt.
Rechenproblem schrieb: > Ist das korrekt? Ich bin etwas verunsichert weil der Counter ja bei 0 > anfängt zu zählen. Der Counter fängt nicht bei 0 an, sondern hört bei 0 auf. Die 0 entspricht 65536. Also ist dein Preload-Wert 65536 - 6000. Diesen Prload schreibst du in der OVF-ISR in den TCNT, der jetzt noch 0 ist. Aber beim nächsten Takt steht Preload im Counter und wird um 1 erhöht. Aber das ist Steinzeittechnik. Nimm den CTC. das wird auch in Bascom gehen. mfg.
ansonsten google mal nach "bascom timer ctc" das ist bei mir gleich der erste Treffer. Ich habs jetzt nur überflogen, aber da hat einer Probleme mit dem CTC mode und am Ende läufts wohl.
Rechenproblem schrieb: > Maximalwert des Timer1 als Counter: 65535 > 65535 - 6000 = 59535 > > Ist das korrekt? Ich bin etwas verunsichert weil der Counter ja bei 0 > anfängt zu zählen. > > Wäre sehr nett wenn da jemand drüberschaut! In CTC-Mode wird auch die Null mitgerechnet und gezählt. Maximalwert interessiert dich nicht, du brauchst 6000, also rechnest du 6000 - 1 = 5999, das ist der Wert, den du in Timer1 Vergleichs- register schreiben must. Wahrscheinlich so etwas wie: OCR1A = 5999
Rechenproblem schrieb: > Netzfrequenz, also 50 Hz. Da ich sie aber zuerst mit einem Trafo auf > gefahrlose 6V reduziere und dann gleichrichte (Brückengleichrichter) > verdoppelt sich die Frequenz. Wenn ich als Arduino-Bastler die Netzfrequenz von einem Netzkabel für einen Atmega-Controller abgreifen möchte, dann ziehe ich einen Draht von einem Input-Pin zum nächsten Netzkabel und klebe es dort mit etwas Klebeband an die Isolierung oder knote es mit genau einer Windung und einem Hausfrauenknoten an das Netzkabel. Macht 100 Hz am Input-Pin ganz ohne Trafo und ohne Gleichrichter.
Jürgen S. schrieb: > Wenn ich als Arduino-Bastler die Netzfrequenz von einem Netzkabel für > einen Atmega-Controller abgreifen möchte, dann ziehe ich einen Draht von > einem Input-Pin zum nächsten Netzkabel und klebe es dort mit etwas > Klebeband an die Isolierung oder knote es mit genau einer Windung und > einem Hausfrauenknoten an das Netzkabel. Macht 100 Hz am Input-Pin ganz > ohne Trafo und ohne Gleichrichter. Ja nee, is klar. Deswegen ist ein Arduino auch genau das richtige für dich. Die Idioten, die nicht so gewieft sind wie du, machen das halt ein bisschen komplizierter. mfg.
:
Bearbeitet durch User
Kurzes Feedback: Ohne CTC funktioniert es. Da ich aber eigentlich Steinzeittechnik vermeiden will versuche ich mich am CTC, leider haut es nicht hin.
1 | $regfile = "M16def.dat" |
2 | $crystal = 8000000 |
3 | $hwstack = 100 |
4 | $swstack = 100 |
5 | $framesize = 100 |
6 | |
7 | |
8 | Config Portb.0 = Output |
9 | Config Pinb.1 = Input |
10 | |
11 | Frequenz Alias Pinb.1 |
12 | Kontrolle Alias Portb.0 |
13 | |
14 | Dim Minuten As Byte |
15 | |
16 | Config Timer1 = Counter , Edge = Rising , Clear Timer = 1 |
17 | Ocr1a = 6 |
18 | On Ocr1a Plusminute |
19 | Enable Timer1 |
20 | Enable Interrupts |
21 | |
22 | Minuten = 0 |
23 | |
24 | |
25 | Do |
26 | Loop |
27 | |
28 | End |
29 | Plusminute: |
30 | Toggle Kontrolle |
31 | Timer1 = 0 |
32 | Minuten = Minuten + 1 |
33 | Return |
Der Compiler meckert, dass OCR1A ein unbekannter Interrupt wäre. Was habe ich falsch gemacht/vergessen?
Rechenproblem schrieb: > Der Compiler meckert, dass OCR1A ein unbekannter Interrupt wäre. Was > habe ich falsch gemacht/vergessen? Der Interrupt-Vektor heisst TIMER1_COMPA. Entweder heisst der in Basic genauso oder es gibt eine Entsprechung dafür. mfg.
Rechenproblem schrieb: > Kurzes Feedback: Ohne CTC funktioniert es. Da ich aber eigentlich > Steinzeittechnik vermeiden will versuche ich mich am CTC, leider haut es > Was habe ich falsch gemacht Bascom verwendet
Thomas Eckmann schrieb: > Rechenproblem schrieb: >> Der Compiler meckert, dass OCR1A ein unbekannter Interrupt wäre. Was >> habe ich falsch gemacht/vergessen? > > Der Interrupt-Vektor heisst TIMER1_COMPA. Entweder heisst der in Basic > genauso oder es gibt eine Entsprechung dafür. > > mfg. Danke, dann mache ich mich mal auf die Suche wie der heißt. TIMER1_COMPA heißt er offensichtlich nicht, gibt ebenfalls eine Fehlermeldung. holger schrieb: > Bascom verwendet Woran erkennt man den Profi? Er lässt ihn jederzeit und überall raushängen.
OCR1A ist das Register, in das der Wert kommt, bis zu dem gezählt werden soll.
j. t. schrieb: > OCR1A ist das Register, in das der Wert kommt, bis zu dem gezählt > werden > soll. Da habe ich nur zum Testen 6 reingeschrieben, da ich einen Taster benutze um Tests durchführen zu können.
Rechenproblem schrieb: > > Der Compiler meckert, dass OCR1A ein unbekannter Interrupt wäre. Was > habe ich falsch gemacht/vergessen? Wahrscheinlich heisst der nur OC1A Das ist doppelt falsch: Ocr1a = 6 On Ocr1a Plusminute Sollte heissen: Ocr1a = 5999 On Oc1a Plusminute Und das ist zuviel: > Plusminute: > Toggle Kontrolle > Timer1 = 0 > Minuten = Minuten + 1 > Return Timer1 ist schon auf Null, nicht nochmal nullen.
:
Bearbeitet durch User
OK, du erzeugst aus der Netzfrequenz nach Trafo und 2-Weg- Geichrichter einen 100-Hz-Trigger für deine Uhrenschaltung. Hat schon vor 50 Jahren jeder Radiowecker so gemacht - sollte also vom Prinzip her funktionieren. Ich kann dir aber nicht glauben, dass du schon vorher mit voreingestellten Zählern was sinnvolles gemacht hast, weil es bei Zählern viel zu aufwändig ist, aus ihrem Maximalwert was abzuleiten! Der ÜBERLAUF beim nächsten Zählschritt, wo sie wieder auf NULL gehen, ist leicht zu detektieren und wird daher üblicherweise verwendet. Somit musst du mit 59536 starten. Überlauf ist bei 65536 (= 0 bei 16 Bit Auflösung). Vor dem nächsten Zähltakt musst du den Zählerstand wieder auf 59536 setzen. UMSTÄNDLICH! Benutze den CTC-Mode (max = 5999) und der 16-Bit-Zähler teilt genau durch 6000. Mit Overflow-, oder Compare-Match-Interrupt kannst du nun die Minuten zählen.
1) hättest Du die Hilfe zu On Interrupt gelesen, würdest Du den richtigen Namen kennen. 2) der Compare-Interrupt muss enabled werden, wird dagegen TimerX enabled, so betrifft das den betreffenden Overflow-Interrupt.
Oldie schrieb: > Ich kann dir aber nicht glauben, dass du schon vorher > mit voreingestellten Zählern was sinnvolles gemacht hast, > weil es bei Zählern viel zu aufwändig ist, aus ihrem Maximalwert > was abzuleiten! Der ÜBERLAUF beim nächsten Zählschritt, wo sie > wieder auf NULL gehen, ist leicht zu detektieren und wird > daher üblicherweise verwendet. > > Somit musst du mit 59536 starten. > Überlauf ist bei 65536 (= 0 bei 16 Bit Auflösung). > Vor dem nächsten Zähltakt musst du den Zählerstand wieder > auf 59536 setzen. UMSTÄNDLICH!
1 | $regfile = "M16def.dat" |
2 | $crystal = 8000000 |
3 | $hwstack = 100 |
4 | $swstack = 100 |
5 | $framesize = 100 |
6 | |
7 | Const Preset = 59536 |
8 | 'Const Preset = 65533 |
9 | Dim Minuten As Byte |
10 | Dim X As Byte |
11 | |
12 | Config Portd.6 = Output |
13 | Config Pinb.1 = Input |
14 | |
15 | Frequenz Alias Pinb.1 |
16 | |
17 | Config Timer1 = Counter , Edge = Rising |
18 | On Timer1 Plusminute |
19 | Timer1 = Preset |
20 | Enable Timer1 |
21 | Enable Interrupts |
22 | |
23 | |
24 | Do |
25 | Loop |
26 | |
27 | End |
28 | Plusminute: |
29 | Timer1 = Preset |
30 | Toggle Portd.6 |
31 | Minuten = Minuten + 1 |
32 | Return |
Rechenproblem schrieb: >
1 | > ... |
2 | > |
Feigling. Es wird sich doch wohl irgendwo im Web ein BASCOM Tutorial auftreiben lassen, bei dem gezeigt wird, wie man den CTC Modus benutzt und wie der Interrupt heisst, an den man sich klemmen muss. Ich wette Google findet sowas in weniger als 0.1 Sekunden. Im übrigen wird deine Lösung nicht richtig funktionieren. Bei einer Uhr ist es nun mal wichtig, dass ausnahmslos alle Ticks richtig gezählt werden. Fällt ein Fehler da in der Testphase von 10 Minuten nicht weiter auf, spätestens nach 2 Monaten fällt der auf, wenn sich der Einzeltickfehler in den Minutenbereich aufsummiert hat. Diese vermaledeite Timer-Preset Lösung ist dann nur auf den ersten Blick einfacher. Spätestens wenn dann das Programm umfangreicher wird, vielleicht noch 1 oder 2 andere Interrupts dazu kommen (um zb eine 7-Segment Anzeige zu multiplexen), ist es dann ganz schnell Essig mit der Langzeit-Genauigkeit.
:
Bearbeitet durch User
Ich habe mich nochmal am CTC versucht, leider erfolglos. Dazu habe ich den halbe Nachmittag verbracht um mich über die Register schlauzumachen, die ich brauche. :/
1 | $regfile = "M16def.dat" |
2 | $crystal = 8000000 |
3 | $hwstack = 100 |
4 | $swstack = 100 |
5 | $framesize = 100 |
6 | |
7 | Config Portd.7 = Output |
8 | Config Portd.5 = Output |
9 | |
10 | '### TIMER INITIALISIERUNG ### |
11 | Tccr1a = 01000000 |
12 | Tccr1b = 01001111 |
13 | Ocr1a = 3 |
14 | Timsk = 01000000 |
15 | '### ENDE TIMER INITIALISIERUNG ### |
16 | |
17 | |
18 | Enable Interrupts |
19 | Enable Oc1a |
20 | Enable Timer1 |
21 | Enable Compare1a |
22 | On Oc1a Plusminute |
23 | |
24 | |
25 | Do |
26 | Toggle Portd.7 |
27 | Waitms 2500 |
28 | Loop |
29 | End |
30 | |
31 | Plusminute: |
32 | Waitms 10000 |
33 | Return |
Die LED toggelt, aber egal wie oft ich an T1 (Timer1/Counter clock source) ein positives High-Signal anlege, es kommt nicht zur Pause von 10 s.
Rechenproblem schrieb: > Tccr1a = 01000000 > Tccr1b = 01001111 > Ocr1a = 3 > Timsk = 01000000 > > Die LED toggelt, aber egal wie oft ich an T1 (Timer1/Counter clock > source) ein positives High-Signal anlege, es kommt nicht zur Pause von > 10 s. Das liegt daran, dass diese Art Konfiguration völliger Quatsch ist, denn wenn schon Binär, dann muss ein "&b" vorangestellt werden, ansonsten ist 01001111 einfach eine Million eintausend einhundertelf und das geht schlecht in ein 8-Bit Register rein.
Hallo an alle, darf ich mal fragen, warum die Netzfrequenz als Zeitzähler genommen werden soll und nicht ein 32,768 kHz Uhrenquarz?? Grüße Daniel
Daniel schrieb: > Hallo an alle, > > darf ich mal fragen, warum die Netzfrequenz als Zeitzähler genommen > werden soll und nicht ein 32,768 kHz Uhrenquarz?? Darfst Du. Antwort wirst Du aber nicht von ALLEN kriegen, sondern bestenfalls vom TO. Es ist gleichgültig, warum er die Netzfrequenz benutzen will, er will es. ----------------------------------------------------------------------- @TO Lege mal die 100 Hz in echt an und lade das Regsietr OCR1A mit 100. Schließe an PortD.5 eine weitere LED an. Die muß dann mit 1HZ blinken. Das Programm erscheint mir so in Ordnung.
Könnte es eventuell so funktionieren und ausreichende Genauigkeit bringen? Ich verpasse ja keine Ticks, weil der Interrupt quasi nur pausiert wird während der Ausführung der if-Schleife und danach nachgeholt wird.
1 | $regfile = "attiny45.dat" |
2 | $crystal = 8e6 |
3 | $hwstack = 50 |
4 | $swstack = 50 |
5 | $framesize = 50 |
6 | |
7 | Dim Zeit As Long |
8 | |
9 | Config Portb.3 = Output |
10 | Config Portb.4 = Output |
11 | |
12 | Config Int0 = Rising 'configuriere Int0 Auf Rising |
13 | Enable Interrupts 'einschalten der Interrupts |
14 | Enable Int0 'einschalten von Interrupt Int0 |
15 | On Int0 Isr_von_int0 'springe zu Isr_von _Int0 |
16 | |
17 | Portb.4 = 1 |
18 | Portb.3 = 1 |
19 | Do |
20 | If Zeit = 3000 Then |
21 | Disable Interrupts |
22 | Zeit = 0 |
23 | Enable Interrupts |
24 | Toggle Portb.3 |
25 | End If |
26 | |
27 | Loop |
28 | End |
29 | |
30 | Isr_von_int0: 'ISR von Int0 |
31 | Zeit = Zeit + 1 |
32 | Return |
Dann hätte ich als Ausgang eine Flanke pro Minute, die ich dann in einem anderen µC auswerten kann. Ein Interrupt pro Minute sollte nicht wirklich ein Problem darstellen, weil der andere µC keine zeitkritischen Aufgaben durchführen muss.
Und nochmals entschuldigung, aber ich kriege das mit dem CTC wirklich nicht gebacken. Ich habe mir wirklich einiges an Beispielen angeschaut aber ich schaffe es nicht. :(
Rechenproblem schrieb: > Wurde korrigiert, leider erfolglos. Rechenproblem schrieb: > Ich habe mich nochmal am CTC versucht, leider erfolglos. Dazu habe > ich den halbe Nachmittag verbracht um mich über die Register > schlauzumachen, > Timsk = 01000000 War leider nix, sonst wäre TIMSK richtig. Auch mit &b wird das also nix. Es wäre problemlos mit den Config-Befehlen gegangen, aber wenn Du schon die Register direkt einstellen willst: es gibt auch Klarnamen für die Konfigurationbits. Darum schrieb ich in Bezug auf diese Binärkonfiguriererei auch von Quatsch, es ist einfach fehleranfällig, besonders dann, wenn man mit der grundsätzlichen Anwendung der Sprache schon Probleme hat.
Hm... ich habe hier nachgelesen: http://www.avrbeginners.net/architecture/timers/timers.html Da stehen folgende Erklärungen bei: ###### TOIE1: Timer Overflow Interrupt Enable (Timer 1); If this bit is set and if global interrupts are enabled, the micro will jump to the Timer Overflow 1 interrupt vector upon Timer 1 Overflow. OCIE1A: Output Compare Interrupt Enable 1 A; If set and if global Interrupts are enabled, the micro will jump to the Output Compare A Interrupt vetor upon compare match. TICIE1: Timer 1 Input Capture Interrupt Enable; If set and if global Interrupts are enabled, the micro will jump to the Input Capture Interrupt vector upon an Input Capture event. TOIE0: Timer Overflow Interrupt Enable (Timer 0); Same as TOIE1, but for the 8-bit Timer 0. ###### Das Bit habe ich deshalb bei OCIE1A gesetzt, weil ich doch will, dass ein Interrupt ausgelöst wird wenn mein OCR1A-Registerwert mit TCNT übereinstimmt. Wie konfiguriere ich das denn nichtbinär?
Das: Timsk = &b01000000 setzt das Bit: TOIE2 = Timer Overflow Interrupt Enable 2 Die 2 bezeichnet die Nummer des Timers, deswegen wird das nix. So könnt's was werden: Config Timer1 = Counter, Clear Timer = 1 COMPARE1A = 3 On COMPARE1A DeineISR Enable COMPARE1A Enable Interrupts
Stimmt, ich habs gerade im Datenblatt auf S. 85 gefunden. Dann steht bei deren Tutorial was falsches da oder es gilt für eine andere CPU. Deins sieht sehr logisch aus, danke dafür. Aber nur zum Verständnis: Laut Datenblatt wäre das Bit für OCIE1A im TIMSK-Register das 4. Also würde der korrekte TIMSK-Code lauten: &b00010000 oder?
heiner schrieb: > deren Tutorial was falsches da oder es gilt für eine andere CPU. Zitat: This description is based on the AT90S2313. > Aber nur zum Verständnis: Laut Datenblatt wäre das Bit für OCIE1A im > TIMSK-Register das 4. Also würde der korrekte TIMSK-Code lauten: > > &b00010000 > > oder? Richtig, es ist Bitnummer 4 und das fünfte Bit. Oder: TIMSK.OCIE1A = 1 Oder: TIMSK = Bits(OCIE1A)
Danke für die Aufklärung. Dann setze ich morgen mal den Quellcode ein, den du mir gezeigt hast. Eine Frage noch: Muss ich nicht noch festlegen, dass er nur die Rising-Flanke zählen darf? Also die Zeile Config Timer1 = Counter, Clear Timer = 1 noch ergänzen Config Timer1 = Counter, Clear Timer = 1, Edge = Rising ? Denn wenn ich einfach nur bei einem Eingang zählen lasse kriege ich ja nicht das gewünschte Ergebnis weil ein Takt von meinem Taktgeber ja deutlich länger als ein Takt meines Prozessors dauert.
Er zählt entweder bei steigender oder fallender Flanke, wobei es eben nur um die Flanke geht, die ordentlich kommen muss. Wie lange danach der Level gehalten wird, ist egal. Bei der Änwendung hier, sollte es egal sein, ob fallende oder steigende Flanke. Da das Beispiel in der Hilfe gezielt auf "falling" konfiguriert, dürfte "rising" die Standardeinstellung sein. Schadet aber nix, es hinzuschreiben.
Rechenproblem schrieb: > uper, scheint zu funktionieren. Danke. Stelle bitte noch den nun funktionierenden Code hier ein. Der Nächste wird Dir dankbar sein. MfG
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.