DCF77 + PWM = Timerproblem

diha525

Neues Mitglied
03. Jan. 2011
10
0
0
Sprachen
Hallo zusammen,

Ich habe mir vorgenommen einen Tageslichtwecker mit Funkuhr selber zu bauen. Ich programmiere nun schon seit einigen Wochen immer mal wieder wenn ich etwas Zeit finde. Leider stehe ich nun vor einem, mir als Anfänger, unlösbaren Problem.
Ich habe einen Atmega16 und möchte zum Wecken ein PWM Kanal + 2 weitere Leuchten (LED) benutzen also insgesamt 3 PWM-Kanäle. Leider benutzt die "DCF77.lib" den Timer1 und somit sind die meisten der 4 PWMs des mega16 schon weg. Nun könnte ich ja mit dem Timer2 und dem Timer0 2 PWMs realisieren, aber dann fehlt mir immer noch 1 Kanal :vollkommenauf:
Was ich nun fragen wollte ist.
1. Ist es irgendwie möglich den Timer1 der DCF77.lib auf den Timer2 oder 0 zu ändern?
oder 2. Kann man die Decodierung irgendwie per Software selber lösen?
oder 3. Kann man die PWMs des Timer1 trotz der DCF77 als PWM nutzen?

Ich hoffe ich habe mich einigermaßen klar ausgedrückt und ich bekomme Hilfe. Denn so langsam wollte ich das Ding mal in Betrieb nehmen :eek:
 
Hallo,

als Tip ...
wenn di nicht genug freie Teimer für deine PWM-Kanäle hast dann bau dir doch
die entsprechende Anzahl an Software-PWMs. Du nimmst einen freien Timer
und läßt den zB auf einer höheren Frequenz laufen ... Beispiel ..
Die PWM-Frequenz soll 50Hz sein (damits nicht flackert)
Du möchtest gerne 256 Schritte haben (von aus bis voll)
also brauchst du 50*256 => 12800Hz.
Dein freier Timer sollte also ungefähr auf 12,8kHz laufen. Den Rest machst du
dann über Software. Wobei 256 Schritte für ne Lampe/LED etwas viel sind.
Die Unterschiede sieht man meißt nicht so genau. Man könnte also auch
auf 64 Schritte runter ... =>
64*50Hz => 3200Hz
Also den Timer auf 3200Hz laufen lassen. Das macht dann ...
1 / 3200Hz => ca. 312ms ...
also wird alle 312ms ein Interrupt ausgelöst der in deine Soft-PWM-Routine
verzweigt in der du die Ausgänge entsprechend der 64möglichen Helligkeitswerte
an oder ausschaltest.

Verstanden ? ... ;)

Gruß
Dino
 
Ok, auf die Idee kam ich natürlich nicht. Die pwm könnte man auch Sw-seitig lösen.
Ich würde dann aber eher >100Hz gehen, denn da liegt die Wahrnehmungsgrenze vom Flackern fürs Auge.
Ich muss dann natürlich noch testen ob alle anderen sachen im prog funzen und meine pwm nicht irgendwas ausnockt.
Hm, und wie so eine soft pwm funktioniert muss ich mir dann mal hier im forum anlesen. Ich hoffe dazu finde ich was.

Danke für den Tip.
 
... oder 312µs.
Dann ist das Flackern auch nicht so störend ;-)
stimmt ;) man sollte nicht milli mit mikro verwechseln ;)
oder anders ausgedrückt ... Am Tachenrechner richtig abgelesen, richtig
gedacht und trotzdem was falsches hingeschrieben ;)

Gruß
Dino
 
Jaja, die Einheitenkontrolle ist das Wichtigste. hat mir mein Physikprof schon immer gesagt :yes4:
Da ich aber hier im Forum irgendiwe zur Sw-PWM nichts finden kann würde ich dich bitten ob du mir das noch mal etwas näher erklären kannst.
Also das mit dem Timer hab ich ja verstanden. Wenn der überläuft kann ich in eine Sub springen wo ich die LED Ein bzw. Ausschalte. Aber was schreib ich da jetzt in die Sub? Lass ich jetzt dann in der Sub noch einen Zähler hochzählen um die Schritte zu realisieren? Und das Ein- und Ausschalten mach ich dann über eine IF / Then Anweisung? Und vor allem, bremse ich damit nicht den Rest meines Programms aus?
Ohmann, Fragen über Fragen. Ich glaub ich bastel einfach mal drauf los und stell dann mal den code hier rein. Mal sehen ob ich es morgen schaffe. Will doch endlich weiter kommen. Ich fang dann mal an :vroam:

Bis dann
 
Hi,

Da ich aber hier im Forum irgendiwe zur Sw-PWM nichts finden kann würde ich dich bitten ob du mir das noch mal etwas näher erklären kannst.

Schau mal hier ... BASCOM-Spielereien für Anfänger
da baue ich nach und nach ein Programm auf das am Ende im Beitrag #18 eine ...
"Binär-Uhr mit Multiplexing und Dimmung" wird. Da ist auch Soft-PWM verwendet.
Sogar gleichzeitig mit Multiplexing und alles ohne Timer oder andere Unterstützung
von der Hardwareseite. Also reine Software.

Aber ich erklärs sicherheitshalber nochmal ...

Der Timer oder irgendein anderer Taktgeber stellt dir eine Frequenz zur Verfügung
mit der du einen Zähler hochzählen läßt. Das ist dein Rampenzähler. Der zählt
bei 64 Dimmschritten zB immer von 0,1,2,...,62,63,0,1,2,... und so weiter.
Er erzeugt also eine Rampe die bei 0 beginnt und bis 63 geht und danach
wieder auf 0 herunterfällt. Nun hast du deinen Dimmwert. Sagen wir mal
einfach 40. Dann schaltest du deinen Ausgangspin ein wenn der Rampenzähler
aus 0 gesetzt wird. Also beim Start der Rampe. Wenn nun der Zähler den
Wert 40 erreicht hat (dein Dimm-Wert) schaltest du den Pin wieder aus.
Damit hast du den Pin für 40 (0..39) Durchlaufzyklen angeschaltet und den
Rest der Zeit ist er aus. Je höher dein Dimm-Wert ist mit dem du den Zähler
vergleichst, desto länger ist der Pin eingeschaltet und desto größer ist deine
gemittelte Ausgangsspannung des PWM-Signals an dem Pin. Du bildest also
nur das nach was die Hardware macht.

Beispiel ...
Zähler für 64 Dimmerstufen (0...63)
Dimmwert 0 => nahezu 0% PWM-Signal (Pin wird sofort wieder ausgeschaltet)
Dimmwert 63 => nahezu 100% PWM-Signal (Pin bleibt wird erst am Ende abgeschaltet)
Dimmwert 32 => etwa 50% PWM-Signal (0..31 an , 32..63 aus)

Mehr ist das nicht. Ein Zähler und ein Vergleich vom Zählerstand mit dem
Dimm-Wert und danach den Ausgangspin an und aus schalten.

Der Timer gibt dir nur einen gleichmäßigen Rhythmus für deinen Rampenzähler.

Bei eine Zähler von 0..63 (64 Schritte) und einer Frequenz des gewünschten
PWM-Signals von 100Hz muß dein Timer also eine Frequenz von 64 x 100Hz
also 6,4kHz liefern oder anders erklärt alle 156µs deine Interruptroutine
aufrufen die den Rampenzähler um Eins erhöht und den Vergleich durchführt.

Gruß
Dino
 
...Und das Ein- und Ausschalten mach ich dann über eine IF / Then Anweisung? Und vor allem, bremse ich damit nicht den Rest meines Programms aus?...
Ja und ja... genau genommen bremst alles, was nicht komplett in der Hardware (im Hintergrund) läuft die Software aus. Ich würde (wenn der Taktgeber 'n IRQ auslöst/auslösen kann) das in die ISR packen. Und zwar in Assembler (also zumindest diese ISR, und die dann mit "nosafe" aufrufen).
Code:
inkrementiere die Rampe (bei Überlauf (255->0) wird automatisch das ZeroFlag gesetzt...)
springe wenn nicht Zero nach...
     PWM-Pin abschalten
     Rampenzähler auf (256-Rampenhöhe (Länge?)) setzen
Einsprung hier
Rampe mit Dimmwert vergleichen (CP - ZeroFlag bei Gleichheit)
Bei NichtZero das setzen des PWM-Pin überspringen.
das wars.
Du brauchst 2 RechenRegister (Rampe und Dimmwert), die neben dem SREG gesichert werden müssen. Bascom selbst würde (fast?) alle 32 Register sichern (und wiederherstellen), neben dem SREG

LotadaC
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)