Hallo, mache gerade die Tutorials auf der Seite durch und stelle gerade fest, dass das Tutorial mit dem LED Fading und das Tutorial mit der Uhr - Genaue Sekunde, beide den Timer1 verwenden. Doch nun entsteht das Problem. Wenn ich beides zusammen Anwenden möchte, würde es nicht funktionieren. Wie genau lösst man solche Probleme? Für die genauere Sekunde benötige ich einen 16Bit Timer. http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC LED Fading http://www.mikrocontroller.net/articles/LED-Fading Oder übersehe ich da was? Verwende den Atmega168
Viktor K schrieb: > Oder übersehe ich da was? Die meisten Controller können auch auf anderen Timern als nur auf dem Timer1 ein CTC machen.
was genau verbirgt sich hintern den hexadezimalen Zahlen? TCCR1A = 0x81; // non-inverted PWM on OC1A, 8 Bit Fast PWM TCCR1B = 0x08; TCCR1B &= ~0x7; Im Dokument finde ich diese Zahlen nicht
> Im Dokument finde ich diese Zahlen nicht > Ja und da finde ich diese nicht! Im Dokument wirst du nicht die Zahlen finden, aber die Beschreibung der Register, in die du diese Zahlen schreibst !!! Und in Abhängigkeit der "Zahl", die im Register steht werden dann entsprechende Einstellungen gemacht. Ralf
Viktor K schrieb: > Falk Brunner schrieb: >> Schon mal das Datenblatt gelesen? > > Ja und da finde ich diese nicht! Dann zerlege einfach mal die Hex-Zahlen in die einzelnen Bits TCCR1A = 0x81 0x81, das ist in Bitschreibweise 1 0 0 0 0 0 0 1 und jetzt gehst du nochmal ins Datenblatt, suchst dir die Register Beschreibung für das TCCR1A Register und siehst nach, was jedes einzelne Bit bedeutet.
Aus diesem Grund sollte man solche Sachen auch nicht als Hex-Wert angeben weil man einfach nicht erkennt was dort gemacht wird. Dafür gibts doch extra die "Namen" für die Bits. Anstatt TCCR1A = 0x81; schreibt man dann TCCR1A = (1<<COM1A1) | (1<<WGM10); Da sieht man im Code schon wo da rumgefummelt wird. Und das "TCCR1B &= ~0x7" kann man sich auch sparen, da du eh alle anderen Bits in dem Register vorher auf "0" setzt: TCCR1B = 0x08; Vermulich sah das vorher so aus: TCCR1B |= 0x08; TCCR1B &= ~0x7; Dann macht es sinn. Besser lesbar ist aber: TCCR1B |= (1<<WGM12); TCCR1B &= ~( (1<<CS12) | (1<<CS11) | (1<<CS10) );
danke, die Hexa-Schreibweise ist ja mal mega doof Habe versucht auf Timer0 die ganzen Register zusetzen. Angeschlossen habe ich die LED an Pin 12 (PD6). Mit Timer1 funktioniert es sehr gut. Beim Timer0 leuchtet die LED nur. Woran kann es liegen?
Viktor K schrieb: > Woran kann es liegen? Für welchen Prozessor?
1 | void pwm_10_64(int16_t tmp) |
2 | {
|
3 | TCCR0A = (1<<COM0A1) | (1<<WGM00) | (1<<WGM01); |
4 | TCCR0B = (1<<WGM02); |
5 | TCCR0B |= 3; |
6 | |
7 | OCR0A = pgm_read_word(pwmtable_10+tmp); |
8 | }
|
9 | |
10 | /*
|
11 | void pwm_10_64(int16_t tmp) {
|
12 | TCCR1A = (1<<COM1A1) | (1<<WGM10) | (1<<WGM11);
|
13 | TCCR1B = (1<<WGM12);
|
14 | TCCR1B |= 3; // 64
|
15 | |
16 | OCR1A = pgm_read_word(pwmtable_10+tmp);
|
17 | }*/
|
kann es sein, dass du einfach nur überall wo im Original eine 1 für 'Timer 1' gestanden ist, du eine 0 für 'Timer 0' reingemacht hast? Das wird so nicht funktionieren. Du musst Funktionalität portieren, nicht einfach nur ein paar Registernamen ändern! Ich kenne keinen AVR-µC der über TCCR0A bzw TCCR0B bzw. OCR0A verfügen würde. Aber das heißt nicht viel, denn ich kenne natürlich nicht alle AVR. Daher die Frage: für welchen Prozessor?
immoment mache ich den Test mit atmega328P Nachträglich habe ich auch festgestellt, dass die Registernamen nicht passten. Im Datenblatt des Atmega32 steht (1<<WGM10) | (1<<WGM11) ist ein PWM, Phase Correct 10, Aber der Timer0 des Atmega328P hat kein 10bit Phase. TCCR0A = (1<<COM0A1) | (1<<WGM00); TCCR0B = (1<<WGM01); TCCR0B |= 3; OCR0A = pgm_read_word(pwmtable_10+tmp); bekomme ich die LED gedimmt aber die "stottert" beim Ausgehen. Also kein sanfter übergang. Liegt es an den Fehlenden 10Bit ?
Für ein ruckelfreies LED-Fading brauchst Du einen 16 bit-Timer mit PWM und für die Basistakterzeugung einen Timer mit CTC-Mode. Warum nimmst Du nicht T/C1 fürs LED-Fading und T/C2 für den Basistakt Deines Programms, dann passt es doch. Die "Genaue Sekunde" kannst Du auch mit einem 8-bit-Timer realisieren - am Prinzip ändert sich ja nichts.
> Wie genau lösst man solche Probleme?
Dein PC löst genau dieses Problem problemlos.
Er hat nur einen (verwendeten) Timer,
und trotzdem hunderte von animierten Sachen.
Man sorgt also nur dafür, daß der Timer einen
genauen Zeitbezug herstellen kann,
und das Programm läuft in einer Schleife und immer dann
wenn es an der Zeit ist, macht es das was zu dieser Zeit
nötig ist, und nur das, nicht etwa "warten" sondern
gleich danach weitermachen mit der Schleife.
Warten ist tödlich.
Natürlich ist es schick, wenn man den Timer auch gleich
nutzen kann, z.B. die benötigte PWM per Pin auszugeben,
dann spart man sich ein paar Codezeilen.
Vuvuzelatus schrieb: > Die "Genaue Sekunde" kannst Du auch mit einem > 8-bit-Timer realisieren brauche ich nicht einen 16Bit Timer wenn ich 4000000 / 256 Teile? die Frage ist auch, wie kommt man auf die 256Hz?
Kann ich egal welche Zahl dafür nehmen? 256, 512, 760 etc oder muss es eine Zahl der Zweier Potenz sein?
Verstehe ich es richtig, die "Genaue Sekunde" lässt sich mit einem 8Bit Timer garnicht realisieren: 4000000 / 15625 = 256 (1Byte groß) dies wären dann 15625Hz, Timerinterruptzeit von 0,064ms ???
Viktor K schrieb: > Verstehe ich es richtig, die "Genaue Sekunde" lässt sich mit einem 8Bit > Timer garnicht realisieren: doch kann man, wenn man nicht immer diesen "schönen" Quarze mit viele nullen nimmt. Es gibt ja auch noch welche mit 4,096Mhz 3,6864Mhz und diese werte lassen sich viel besser durch 256/512/1024 teilen. Damit hat man weniger probleme bei der genauen sekunde und der Uart.
15625 ist ja nicht der prescaler sondern nur eine Zahl (Hz) das Ergebnis von 4000000 / 15625 muss ja 1Byte groß sein.
Viktor K schrieb: > das Ergebnis von 4000000 / 15625 muss ja 1Byte groß sein. und warum? Man kann doch auch 1/10 Sekunden zählen.
Viktor K schrieb: > weil mein OCR0A nur 1Byte groß ist was denn das für ein Grund. du kannst einen Quarz mit 3,6864Mhz nehmen, dort ein Prescaler von 64. Und Im Overvlow zähler du eine Variable bis 225 - dann ist eine Sekunde rum.
Ja aber wie willst du dann die Fehlerkorrigierung machen? Das ist ja das was ich nicht so ganz verstehe mit nur 8 Bit Timer
Viktor K schrieb: > Ja aber wie willst du dann die Fehlerkorrigierung machen? Das ist ja das > was ich nicht so ganz verstehe mit nur 8 Bit Timer Da hast du nicht so unrecht. Ergo: Du möchtest einen Prescaler benutzen der möglichst klein ist. Im Idealfall 1, denn dann kannst du auch den Quarzfehler am besten ausgleichen. Aber auch Peter hat recht. Kein Mensch sagt, dass du 1 Sekunde genau anpeilen musst. Es reicht auch, wenn deine ISR zb alle 1/256 Sekunden (das aber dann schon genau) aufgerufen wird. In der ISR zählt man die Anzahl der Aufrufe mit und nach dem 256 Aufruf (oder dem 200. oder wie es sich eben ausgeht) ist dann 1 Sekunde um.
Viktor K schrieb: > a aber wie willst du dann die Fehlerkorrigierung machen? Das ist ja das > was ich nicht so ganz verstehe mit nur 8 Bit Timer du must gar keine machen, weil es keinen Fehler gibt wenn man einen Frequenz hast die durch 256 Teilbar ist.
kannst du garantieren, dass der Quarz auch mit 3,6864Mhz schwingt?
soweit ich das nun verstehe, es ist nicht möglich Led-fading und eine Uhr (Geneue Sekunde) zusammen zu haben!
@ Viktor K (Gast) >soweit ich das nun verstehe, es ist nicht möglich Led-fading und eine >Uhr (Geneue Sekunde) zusammen zu haben! Das verstehtst du falsch. Klar geht beides zusammen! Die genaue Sekunde macht man wie im Artikel mit Timer 1 ohne Prescaler und durchläufendem Zähler mit OCR1A. http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC#Verbesserte_Version_mit_durchlaufendem_Hardwarez.C3.A4hler Gleichzeitige macht man mit OCR1B das LED-Fading mit 16 Bit. Wenn man sich auch mit 8 Bit LED-Fading zufrieden gibt, kann man auch Timer 0 und Timer 2 nutzen. Wo ist das Problem? MfG Falk
Hallo, so der Timer der Uhr funktioniert soweit, s wird ganz genau jede 1000ms hochgezählt. Wenn ich aber TCCR1A = (1<<COM1A1) | (1<<WGM10) | (1<<WGM11); mache, funktioniert der Timer der Uhr nicht mehr richtig.
Was ich gerade noch festgestellt habe, das die LED nicht am Ausgang OC1B geschaltet war. Dies habe ich nun geändert, ohne aber einen Erfolg!
Viktor K schrieb: > Hallo, > > so der Timer der Uhr funktioniert soweit, s wird ganz genau jede 1000ms > hochgezählt. Wenn ich aber > > TCCR1A = (1<<COM1A1) | (1<<WGM10) | (1<<WGM11); > > mache, funktioniert der Timer der Uhr nicht mehr richtig. Logo geht das nicht. Du kannst hier natürlich keinen fixen 10-Bit PWM Modus nehmen! Für die Uhr brauchst du die Einstellung, dass du taktgenau das Rücksetzen veranlassen kannst. Da führt kein Weg vorbei! Das geht zb mit dem CTC Modus (wie er in der genauen Uhr verendet wird) oder aber mit einem PWM Modus, bei dem du dir Obergrenze vorgeben kannst, wie zb dem Modus 14 oder 15 Versuch doch wenigstens zu verstehen, wie Timer, CTC MOdus und PWM funktionieren. Wenn du Code immer nur abmalst ohne zu verstehen was da eigentlich warum passiert, wirst du immer auf die Nase fallen.
Wenn ich den CTC verwende, rechnet er aber dann falsch. TCCR1B = (1<<CS10)|(1<<WGM12);
Viktor K schrieb: > kannst du garantieren, dass der Quarz auch mit 3,6864Mhz schwingt? ja genauso wie ein 4Mhz Quarz mit 4Mhz schwingt.
Viktor K schrieb: > Wenn ich den CTC verwende, rechnet er aber dann falsch. > > TCCR1B = (1<<CS10)|(1<<WGM12); 1) Wer rechnet was falsch? 2) Berechnungen kann man geänderte Umstände anpassen 3) Da du eine PWM machen willst, willst du einen PWM Modus und keine CTC! Aber du willst einen PWM Modus, bei dem du die Obergrenze wie beim CTC festlegen kannst. Sozusagen einen PWM MOdus mit eingebautem CTC
Peter schrieb: > Viktor K schrieb: >> kannst du garantieren, dass der Quarz auch mit 3,6864Mhz schwingt? > > ja genauso wie ein 4Mhz Quarz mit 4Mhz schwingt. Peter sei nicht naiv. Das kannst du nicht. Für eine Uhr reicht es nicht, wenn der Quarz 10ppm Abweichung hat, die nicht korrigiert werden. Selbst wenn der Quarz anstelle von 4000000Hz mit 4000010Hz schwingt (und so genau ist der nur durch Zufall an der Sollfrequenz), merkt man das bei einer Uhr ganz schnell. Bei diesen Quarzen liegt die typische Fertigungsgenauigkeit bei ca +-100ppm. D.h. anstelle von 4000000Hz ist von 4000100 bis 3999900 alles drinnen. Und das auch noch temperaturabhängig. Noch nicht einmal dezidierte Uhrenquarze, obwohl genauer gefertigt, haben ohne Abgleich durch Ziehkondensatoren exakt 32768Hz. Eine Quarzarmbanduhr, die nicht am Handgelenk getragen wird, wird nach einiger Zeit eine Abweichung haben, die sie nicht hätte, wenn sie durch die Körpertemperatur auf annähernd gleichbleibenden ~36°C gehalten worden wäre. Für Anwendungen wie UART oder Kurzzeitzeitmessungen sind diese Abweichungen belanglos. Aber in einer Uhr die über Wochen und Monate durchläuft, sind sie das nicht. Der Fehler akkumuliert sich.
Peter hat einfach nur die Links nicht geöffnet und die Artikel nicht mal überflogen, sonst hätte er gewußt, worum es überhaupt geht.
Karl heinz Buchegger schrieb: > Bei diesen Quarzen liegt die typische Fertigungsgenauigkeit bei ca > +-100ppm. merkwürdig bei mir im Datenblatt steht etwas von 30ppm Ich habe selber eine gerade ein Modul mit Urzeit gebaut, da konnte ich nach 24Stunde keine sekunde abweichung feststellen. Und selbst wenn ich noch eine abweichung ermittle muss ich dafür nicht den Timer anpassen sondern kann es als normale Berechnungsschritt einführen. Ich woll hier nur zeigen das man sich mit einem Quarz von 4,000Mhz mehr abeit machen muss als mit einem der durch 256 Teilbar ist. Dafür brauch ich keine CTC Modus und keine Fehlerkorrektur. So lange der Quarz auf seiner Frequenz schwingt stimmt alles exakt. Das die Abweichung von Quarz hinzukommt ist doch klar.
Peter schrieb: > Ich habe selber eine gerade ein Modul mit Urzeit gebaut, da konnte ich > nach 24Stunde keine sekunde abweichung feststellen. Dann lass sie mal laufen. > Und selbst wenn ich > noch eine abweichung ermittle muss ich dafür nicht den Timer anpassen > sondern kann es als normale Berechnungsschritt einführen. Kannst du. Mann kann das aber auch mit dem Timer korrigieren. > Ich woll hier nur zeigen das man sich mit einem Quarz von 4,000Mhz mehr > abeit machen muss als mit einem der durch 256 Teilbar ist. Dafür brauch > ich keine CTC Modus und keine Fehlerkorrektur. So lange der Quarz auf > seiner Frequenz schwingt stimmt alles exakt. Er schwingt aber nicht auf seiner Frequenz! Die bestehst hier geflissentlich darauf, in einer idealen Welt zu leben. Reale Bauteile haben Fertigungstoleranzen. Das ist nun mal so und weder du noch ich können daran was ändern. Das ganze ist auch überhaupt kein Problem, wenn Viktor endlich anfangen würde, Code nicht einfach nur zu klauen, sondern die dahinterstehenden Grundlagen zu begreifen. In diesem Fall, wie Timer eigentlich funktionieren, was die Modi machen und worauf es dabei jeweils ankommt. Ab dort wird es dann genauso einfach wie die Zeiten in einem Skirennen im Fernsehen mit einer Uhr zu stoppen und mit derselben Uhr darüber zu wachen, dass der Schweinsbraten nicht anbrennt. Eine Uhr - 2 Aufgaben.
OK möchte mich nun mit dem Thema tiefgründiger befassen. In welche Themengebiete muss ich mich einarbeiten: - CTC - Timer - PWM Gibs da noch etwas, was ich vergessen habe? Karl heinz Buchegger schrieb: > Wer rechnet was falsch? Meine Sekunde ist dann keine 1000ms lang, sondern etwa 37ms.
> Gibs da noch etwas, was ich vergessen habe?
Hallo Viktor, schau dir doch auch mal das Datenblatt zu deinem MC durch.
Ich arbeite beispielsweise mit atmega168 und ~328. Das Datenblatt zu
diesen Typen hat ca 400 Seiten und ist sehr umfangreich, enthält
Codebeispiele in C und ASM sowie viele Grafiken und Erklärungen, auch
bei den Timern.
Wenn da was unklar ist, einfach noch hier die Artikelsuche bemühen, im
schlimmsten Fall noch die Forensuche ;)
HTH & viel Spass :)
Karl heinz Buchegger schrieb: > Du kannst hier natürlich keinen fixen 10-Bit PWM Modus nehmen! Das verstehe ich nicht. Wieso darf ich kein 10-Bit PWM verwenden?
Also soweit ich das nun verstanden habe, müsste es auch so richtig sein! Aber irgendwo ist immernoch ein Fehler. s++ wird alle 31,67ms aufgerufen
Hallo, ich glaub ich hab das Problem erkannt. Leider hab ich finde ich keine Lösung dazu. Bei der "Genaue Sekunde" wird der TCNT1 gleichmäßig hochgezählt. Erreicht dieser den Wert im OCR1A wird die ISR ausgelöst. Beim LED-Fading springt die TCNT1 counter wirkürlich. Der OCR1A bekommt hier auch einen Falschen Wert, sobald ich die beiden Sachen gleichzeitig betreiben will.
So leider habe ich es nicht Geschaft einen Timer für beide zwecke zu verwenden. Habe es nun schließlich mit Timer0 das Fading realisiert. Für meine Zwecke ist es brauchbar und der Timer0 war noch frei. Die LED sollte nur bestimmt Hell bzw. Dunkel leuchten und dafür reicht der 8Bit PWM.
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.