Hallo zusammen, für verschiedene Anwendungen habe ich bereits mehrmals erfolgreich das DCF77-Signal dekodiert und in den jeweiligen Applikationen genutzt - soweit alles kein Problem. Im aktuellen Fall würde ich neben der DCF77-Funktionalität aber auch noch die Timer des gleichen Controllers für eine andere Aufgabe benötigen. Deswegen folgende Frage: Die DCF77-Library von Bascom verwendet eine Softclock die in einstellbaren Intervallen mit den DCF77-Daten abgeglichen wird. Für den Sekunden-Interrupt der Softclock wird ein Timer verwendet (beim ATmega8 bietet sich lediglich Timer1 an weil 16 Bit breit). Timer0 wird nicht verwendet. In der aktuellen Schaltung würde ich aber beide Timer für eine andere Funktionalität verwenden und deswegen würde ich den Sekundentakt für die Softclock gerne direkt vom DCF77-Modul abgreifen anstatt den Sekundentakt im Controller zu erzeugen und damit einen Timer zu "verschwenden". Nun gibt es in der Bascom-Hilfe zwar relativ viel Material was auch recht aufschlussreich ist, allerdings hilft es mir in dieser speziellen Frage nicht richtig weiter - vielleicht verstehe ich es auch einfach nicht. Würde mich jedenfalls freuen, wenn jemand damit schon Erfahrungen gesammelt hat und vielleicht den ein oder anderen Tipp geben könnte! Viele Grüße, Stefan
Hallo, vom DCF77-Modul bekommst Du keinen direkt nutzbaren Sekundentakt. Einmal, weil der 59. Sekundenimpuls zur Syncronisation der Minute fehlt und außerdem, weil der Empfang nur selten so stabil ist, daß überhaupt jeder Impuls erkannt wird. Normalerweise kann man DCF77 wunderbar in einem 10ms-Timer-IRQ einsammeln, den man für Uhr, Tastenentprellung und diverse andere zyklisch ablaufende Prozesse meist sowieso braucht. Dafür reicht auch ein 8Bit-Timer, muß man eben in Software mitzählen. Da Basic aber eher ein Baukasten ist, wird man wohl wenig Einfluß auf die fertigen Module haben. Man kann sowas natürlich auch in Bascom komplett "zu Fuß" schreiben, dann kommt aber meist die Erkenntnis, daß man dann auch gleich alles in C oder ASM machen könnte. ;) Gruß aus Berlin Michael
Hallo Michael, vielen Dank erst einmal für deine Antwort! Sicher sind deine Einwände berechtigt dass ein direkter Sekundenimpuls vom Modul etwas heikel ist. Allerdings würde ich die Idee trotzdem gerne weiter verfolgen weil: 1) ich glücklicherweise einen sehr stabilen Empfang des DCF77-Signals habe (ich verwende das Modul von Pollin, die interne AGC scheint bei diesem Modul wirklich äusserst gut zu arbeiten) 2) der Sekundentakt als solcher einfach abgreifbar ist. Der fehlende Impuls beim Minutenstart stellt kein großes Problem dar; man könnte ihn quasi manuell einfügen wenn das überlange Pausenverhältnis zur vollen Minute erkannt wird. 3) ich leider beide Hardware-Timer des Controllers für eine PWM benötige. Zwar habe ich schon alternative Szenarien durchgespielt (Soft-PWM statt Hardware, einen zweiten Controller nur für die PWM, einen anderen Controller mit mehr Timer), allerdings wäre es mir natürlich am liebsten den vorhandenen Controller zu verwenden und nicht extra noch einen zweiten für die PWM herzunehmen. Ich denke, mein Problem lässt sich einfach auf folgende Frage herunterbrechen: Die DCF77-Library bietet die Funktion TIMER1SEC. "0" = kontinuierliche Zeiterfassung, "1" = stündlich, "2" = täglich. Leider bietet die Bascom-Hilfe keine detaillierten Infos über die Betriebsart "0". Meine Vermutung / Hoffnung ist aber, dass in der kontinuierlichen Betriebsart die Library tatsächlich den Sekundentakt vom Modul bezieht und keine Softclock nutzt. Wenn dem so wäre, könnte ich den Timer anderweitig nutzen. Wenn das aber nicht der Fall ist und die Library von der Betriebsart unabhängig den Timer verwendet ist die Sache so nicht praktibel und ich muss mich nach einer Alternative umsehen. Mit anderen Worten: Kennt jemand den Aufbau der DCF77-Library genauer und weiß wie sie die Betriebsart TIMER1SEC = 0 handhabt? Noch kurz zum Hintergrund: Wie bereits erwähnt soll der Controller neben dem Empfang der Funkuhrzeit noch drei PWMs machen und darüber hinaus ein zweizeiliges LC-Display ansteuern (HD44780). Dies funktioniert im Moment auch wirklich super: Das DCF77 wird korrekt dekodiert, die PWMs laufen sauber in Software und das Display funktioniert so wie es soll. Der Haken an der Sache: Das Aktualisieren des Displays ist so langsam (geschätzte 50 Millisekunden), dass die Soft-PWM in dieser Zeit merklich abweicht. Deswegen eben die Frage, ob die Bascom-DCF77-Sache wirklich zwingend den Timer benötigt. Hardware-PWM wäre ne feine Sache.
Der ATmega8 hat 3 Timer: T0, T1, T2. Somit kannst Du bequem 2 Timer für ne PWM benutzen und den T2 als RTC/Dekoder und für alle sonstigen Zeitintervalle. Man kann natürlich auch im PWM-Mode einen Interrupt des gleichen Timers als Zeitbasis benutzen. Peter
>man könnte ihn >quasi manuell einfügen wenn das überlange Pausenverhältnis zur vollen >Minute erkannt wird. Wie willst Du das bewerkstelligen? >Der Haken an der Sache: Das Aktualisieren >des Displays ist so langsam (geschätzte 50 Millisekunden), dass die >Soft-PWM in dieser Zeit merklich abweicht. Dann läuft die Erzeugung der Soft-PMW anscheinend nicht über einen Timerinterrupt. Das wäre vielleicht eine mögliche Lösung für Dein Problem. >Deswegen eben die Frage, ob >die Bascom-DCF77-Sache wirklich zwingend den Timer benötigt. Ich tippe auf "ja". Ist aber nur ne Vermutung. Jeder DCF-Decoder benötigt einen unabhängigen Zeitgeber (welcher Art auch immer), um überhaupt die Pulslängen und Flankenabstände des DCF-Signals messen zu können. >Hardware-PWM wäre ne feine Sache. Schreib doch mal, welche Wunschdaten (Frequenz, Auflösung) die PWM haben soll.
@ Peter Dannegger: Jein. Der ATmega8 hat eigentlich zwei Timer (Timer0 mit 8 Bit, Timer1 16 mit Bit), wobei das Hardwaredesign es ermöglicht dass die beiden Timer aber für drei unabhängige PWM-Ausgänge genutzt werden können (PWM1a, PWM1b und OCR2). Korrigiere mich bitte wenn ich mich täusche, aber mit diesen Infos bin ich bislang in der Praxis gut gefahren. KORREKTUR: Ich sehe gerade, du hast Recht. Es sind 3 Timer. Ich werde mir das Datenblatt noch etwas genauer zu Gemüte führen, sorry... Timer0 und Timer1 teilen sich allerdings einen Prescaler. Offensichtlich ist das Hauptproblem dass niemand genau wissen kann, was die DCF77-Library von Bascom intern eigentlich macht. Und solange man das nicht genau weiß, bleibt alles andere Spekulation. @Gast: Ich denke du hast Recht. Ich kann den Timer1 nicht für andere Zwecke nutzen solange ich vermuten muss dass die Library in jeder Betriebsart zwingend darüber verfügen muss. Somit liegt der Schluss nahe, dass ich meine drei PWMs weiterhin in Software realisieren muss. Und du hast vollkommen Recht, die Soft-PWM läuft nicht über einen Interrupt. Wahrscheinlich habe ich es sogar sehr dilettantisch realisiert... Das war mein erster Versuch eine PWM in Software zu schreiben, habe ehrlich gesagt wenig Ahnung davon. Here we go:
1 | Config Timer0 = Timer , Prescale = 64 |
2 | Enable Timer0 |
3 | |
4 | If Timer0 < PWM1 Then Portd.7 = 1 |
5 | If Timer0 > PWM1 Then Portd.7 = 0 |
6 | |
7 | If Timer0 < PWM2 Then Portd.6 = 1 |
8 | If Timer0 > PWM2 Then Portd.6 = 0 |
9 | |
10 | If Timer0 < PWM3 Then Portd.5 = 1 |
11 | If Timer0 > PWM3 Then Portd.5 = 0 |
Ich verwende also den 8-Bit-Timer mit einem 64er Prescaler (Systemtakt ist 16 MHz). Die Variablen PWM1, PWM2 und PWM3 sind als Byte dimensioniert und können demzufolge Werte von 0 bis 255 annehmen, wie auch der Timer. In euren Augen ist das wahrscheinlich etwas schräg, aber wie gesagt es ist mein erster Versuch mit Soft-PWM. Und prinzipiell läuft die Sache auch hervorragend - nur die Aktualisierung des Displays bringt die Sache logischerweise aus dem Tritt. Wenn ihr mir also bei einer sinnvolleren Soft-PWM mit Interrupt helfen könnt, wäre das super! Die Anforderungen liegen niedrig, es sollen lediglich LEDs in der Helligkeit gedimmt werden.
Ich glaube, ich habe es jetzt kapiert. Ich lasse den verfügbaren Timer einfach ständig hochzählen und bei jedem Überlauf wird eine Interruptroutine aufgerufen. In dieser Routine lasse ich jeweils eine Byte-Variable um eins hochzählen. Ausserdem werden in dieser Routine jeweils die Ausgangspins in Abhängigkeit vom gewünschten Wert geschaltet. Mein obiges Listing wäre also soweit schon in Ordnung, nur dass das Listing eben bei jedem Überlauf aufgerufen werden muss und ich den Wert nicht direkt aus dem Timer0 nutze, sondern aus der Variablen die bei jedem Interrupt um eins erhöht wird. Falls ich es doch nicht kapiert habe und einem Denkfehler unterliege dürft ihr mich gerne korrigieren :-) Werde diesen Denkansatz baldmöglichst in der Schaltung testen.
Ich habe folgendes Listing entworfen - Bascom meckert nicht, scheint soweit also in Ordnung zu sein. Konnte es leider noch nicht in Hardware testen, weil ich die Schaltung gerade nicht da habe.
1 | 'Initialisieren des Timers: |
2 | Config Timer0 = Timer , Prescale = 64 |
3 | Enable Timer0 |
4 | 'An diese Stelle wird gesprungen wenn der Zähler einen Überlauf hat: |
5 | On Timer0 Pwm |
6 | Enable Interrupts |
7 | Dim Zaehler as Byte |
8 | 'Hier ist die Hauptprogrammschleife: |
9 | Do |
10 | ... |
11 | ... |
12 | ... |
13 | Loop |
14 | 'Hier ist die Subroutine die bei Überlauf angesprungen wird: |
15 | Pwm: |
16 | Incr Zaehler |
17 | If Zaehler < PWM1 Then Portd.7 = 1 |
18 | If Zaehler > PWM1 Then Portd.7 = 0 |
19 | If Zaehler < PWM2 Then Portd.6 = 1 |
20 | If Zaehler > PWM2 Then Portd.6 = 0 |
21 | If Zaehler < PWM3 Then Portd.5 = 1 |
22 | If Zaehler > PWM3 Then Portd.5 = 0 |
23 | Return |
Alles richtig verstanden oder gibt es Hinweise? :-)
That's it! :-) Probiers mal mit dem 8-Bit-Timer T/C0. Interessant wäre noch eine kleine Abschätzung zur erreichbaren PWM-Frequenz und -Auflösung: Bei FOSC = 8 MHz und T/C0-Prescaler 1 produziert das Dingens Overflow-Interrupts mit der Frequenz 8000000 Hz/256 = 31250 Hz. Nutzt Du die (allen PWM-Kanälen gemeinsame) PWM-Zählvariable "komplett" (Zählschema 0...255, 0...255), bekommst Du eine PWM-Frequenz von 31250 Hz/256 = 122 Hz. Das ist so schnell, dass das menschliche Auge bereits kein Flimmern mehr wahrnimmt, außer beim raschen Wechseln der Blickrichtung. "Echte" Helligkeitsstufen [*] gibts acht Stück ("ganz aus" unberücksichtigt): 1/1, 1/2, 1/4, 1/16, 1/32, 1/64, 1/128, 1/256. Möchtest Du eine höhere PWM-Frequenz, z. B. 488 Hz, steht es Dir frei, die PWM-Zählvariable schon bei z. B. 64 zu resetten. Dann zählt sie 0...63, 0...63. Der Preis für die höhere PWM-Frequenz sind zwei Helligkeitsstufen weniger; 1/128 und 1/256 fallen weg. [*] Der Zusammenhang zwischen der physikalischen Lichtstärke und der Helligkeitsempfindung durch das Auge ist näherungsweise logarithmisch (Weber-Fechnersches Gesetz). Du könntest aus den 31250 Hz sogar noch einen schönen Takt für die Main ableiten, z. B. durch einen weiteren Software-Postscaler von 250. Das liefert dann eine Frequenz 125 Hz, entsprechend 8 ms Tickintervall. Damit kann man prima Tasten entprellen, oder eine DCF-Decodier-Zustandsmaschine oder eine Software-RTC takten (für Sekundentakt einfach noch mal einen Software-Postscaler von 125 hintendranhängen, gefolgt von einem 60er für die Minuten, gefolgt von noch einem 60er für die Stunden usw... das Prinzip ist immer dasselbe). Du musst nur sicherstellen, dass die T/C0-Overflow-Interruptroutine (ISR) immer in weniger als 256 Systemtakten abgearbeitet wird. Also auf schnellen Code achten. Bei 50 Takten würde die PWM-Erzeugung den µC zu knapp 20 % auslasten. Die Forderung, ISRs möglichst kurz zu halten, gilt übrigens generell. :Alles richtig verstanden Ja. Eine Aktualisierung des LCDs wird auf diese PWM keinen Einfluss mehr haben. (Pass auf, am Ende hast Du noch T/C1 unbenutzt übrig... ;-) )
Hey, Danke für den aufmunternden Zuspruch ;-) Ich habe einen Takt von 16 MHz und werde wohl einen Prescaler von 64 nutzen. Das dürfte schnell genug sein... Ja, die logarithmische Wahrnehmung wird dann die nächste Baustelle... Ich komme eigentlich aus der Audiotechnik, weswegen mir das nicht ganz fremd ist. Wie ich aber die Sache in Bascom für das Dimmen der LEDs richtig hinbekomme, weiß ich jetzt noch nicht so genau. Werde mir da noch ein paar Gedanken machen und ggf. nochmal hier nachfragen :-) Heute oder morgen will ich aber erst das heute erreichte in der Schaltung testen. Vielen Dank nochmal für die große Hilfe in Sachen Soft-PWM!
Nun gut, die Idee mit dem 64er Prescaler war natürlich nicht ganz zu Ende gedacht... Habe jetzt den Faktor 1 und damit funktioniert das wunderbar ;-) Jetzt kommt aber der logarithmische Zusammenhang zwischen Lichstärke und Wahrnehmung... Irgendwie macht das jeder mit Tabellen, was sehr einfach wäre, ich aber eher ungern machen würde. Gibt es da nicht eine mathematische Funktion die man dazu nutzen kann?
Glückwunsch g Ein höherer Prescaler wäre nur sinnvoll, wenn Du deutlich mehr PWM Kanäle haben wolltest (z. B. 20), aber mit einer nur geringen Auflösung (z. B. 4). Dann könntest Du durch Heraufsetzen des Prescalers von 1 auf z. B. 8 die PWM absichtlich verlangsamen und dadurch die Rechenlast des µCs reduzieren. >Jetzt kommt aber der logarithmische Zusammenhang zwischen Lichstärke und >Wahrnehmung... Irgendwie macht das jeder mit Tabellen, was sehr einfach >wäre, ich aber eher ungern machen würde. Aha. Und Dich stört an einer Tabelle was genau? Magst Du keine kleine, unkomplizierte, effiziente, schnelle Lösungen? Logarithmusfunktion in Fließkommaarithmetik: Alles in allem werden x hundert Zeilen Code einen Riesenbatzen Programmspeicher verschlingen und jede Berechnung wird x hundert Taktzyklen dauern. Tabelle: Ca. 20 Bytes, ca. 20 Taktzyklen. >Gibt es da nicht eine >mathematische Funktion die man dazu nutzen kann? Beantwortet die Doku zu Bascom diese Frage nicht?
Okay, die Antwort sagt alles ;-) Mich hätte an einer Tabelle vor allem die Größe gestört - weil ich ursprünglich angenommen habe, dass man da relativ einfach eine Formel hernehmen könnte. Aber nachdem ich nicht gerade ein Mathe-Freak bin, lasse ich mich gerne eines Besseren belehren. Die Bascom-Doku habe ich zu Rate gezogen und damit versucht eine praktikable Lösung zu finden, was leider gescheitert ist. Nachdem du was von x hundert Zeilen Code schreibst, wundert mich das auch nicht... Gut, wieder was gelernt!
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.