Forum: Compiler & IDEs LED Fading und Uhr beides benötigt Timer1


von Viktor K (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

Schon mal das Datenblatt gelesen?

von Viktor K (Gast)


Lesenswert?

Falk Brunner schrieb:
> Schon mal das Datenblatt gelesen?

Ja und da finde ich diese nicht!

von Ralf (Gast)


Lesenswert?

> 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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Timmo H. (masterfx)


Lesenswert?

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) );

von Viktor K (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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?

von Viktor K (Gast)


Lesenswert?

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 ?

von Vuvuzelatus (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

> 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.

von Viktor K (Gast)


Lesenswert?

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?

von Viktor K (Gast)


Lesenswert?

Kann ich egal welche Zahl dafür nehmen? 256, 512, 760 etc

oder muss es eine Zahl der Zweier Potenz sein?

von Viktor K (Gast)


Lesenswert?

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 ???

von Peter (Gast)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

15625 ist ja nicht der prescaler sondern nur eine Zahl (Hz)

das Ergebnis von 4000000 / 15625 muss ja 1Byte groß sein.

von Peter (Gast)


Lesenswert?

Viktor K schrieb:
> das Ergebnis von 4000000 / 15625 muss ja 1Byte groß sein.

und warum? Man kann doch auch 1/10 Sekunden zählen.

von Viktor K (Gast)


Lesenswert?

Peter schrieb:
> und warum?

weil mein OCR0A nur 1Byte groß ist

von Peter (Gast)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

Ja aber wie willst du dann die Fehlerkorrigierung machen? Das ist ja das 
was ich nicht so ganz verstehe mit nur 8 Bit Timer

von Karl H. (kbuchegg)


Lesenswert?

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.

von Peter (Gast)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

kannst du garantieren, dass der Quarz auch mit 3,6864Mhz schwingt?

von Viktor K (Gast)


Lesenswert?

soweit ich das nun verstehe, es ist nicht möglich Led-fading und eine 
Uhr (Geneue Sekunde) zusammen zu haben!

von Falk B. (falk)


Lesenswert?

@  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

von Viktor K (Gast)


Lesenswert?

OK danke, werde ich mal ausprobieren!

von Viktor K (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

Wenn ich den CTC verwende, rechnet er aber dann falsch.

TCCR1B = (1<<CS10)|(1<<WGM12);

von Peter (Gast)


Lesenswert?

Viktor K schrieb:
> kannst du garantieren, dass der Quarz auch mit 3,6864Mhz schwingt?

ja genauso wie ein 4Mhz Quarz mit 4Mhz schwingt.

von Karl H. (kbuchegg)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Peter (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

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.

von Bastler (Gast)


Lesenswert?

> 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 :)

von Viktor K (Gast)


Lesenswert?

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?

von Viktor K (Gast)


Angehängte Dateien:

Lesenswert?

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

von Viktor K (Gast)


Lesenswert?

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.

von Viktor K (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.