Forum: Mikrocontroller und Digitale Elektronik PWM auf ATmega328p Timer0 nicht so wie erwartet.


von Ralph S. (jjflash)


Lesenswert?

Ich bin am Überarbeiten meiner Sourcen und stellte Fest: FAST-PWM auf 
Timer0 habe ich nicht implementiert. Kein Problem (dachte ich), Timer0 
sollte genauso sein wie Timer 2.

Pustekuchen !

Wahrscheinlich sehe ich den Wald vor lauter Bäumen nicht und ich habe 
jetzt auch schon wirklich ne lange Zeit ins Datenblatt geschaut, aber 
ich komme nicht drauf!
1
void pwmt2_init(uint8_t prescale, uint8_t tg, uint8_t tp)
2
{
3
  // PD3 is "Ausgabepin" fuer Output Compare 2 B (OC2B)
4
  TCCR2A = (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);
5
  TCCR2B = (1 << WGM22) | prescale;
6
  OCR2A = tg;
7
  OCR2B = tp;
8
}
9
10
void pwmt0_init(uint8_t prescale, uint8_t tg, uint8_t tp)
11
{
12
  // PD5 is "Ausgabepin" fuer Output Compare 0 B (OC0B)
13
  TCCR0A = (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);
14
  TCCR0B = (1 << WGM02) | prescale;
15
  OCR0A = tg;
16
  OCR0B = tp;
17
}
18
.
19
.
20
pwmt0_init(5,94,47);
21
pwmt2_init(5,94,47);

Warum produziert Timer2 eine korrekte, besser gesagt eine erwartete 
Frequenz, von 1315 Hz, aber Timer0 eine Frequenz von 163 Hz ?

Beide sollten im Fast-PWM Modus laufen (WGM22=WGM21=WGM20= 1 und 
WGM02=WGM01=WGM00= 1), haben denselben Prescaler und dieselben 
Comparewerte.

Was übersehe ich ?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

was haben wir (ich) versucht dir im letzten Thread zum Thema 
beizubringen?
Bist du lernfähig? Es gibt auch keinen Prescaler 5. Auch wenn ich erahne 
was das sein soll, macht man nicht.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> ... macht man nicht.

Stimmt!
Faktor 8 zwischen den Ergebnissen - aha: bei Timer2 entspricht die '5' 
/128, bei Timer0 /1024.

von Oliver S. (oliverso)


Lesenswert?

Ralph S. schrieb:
> Timer0 habe ich nicht implementiert. Kein Problem (dachte ich), Timer0
> sollte genauso sein wie Timer 2.

Bei allen AVR Mega/Tiny ist Timer 0 anders als die anderen, und Timer 2 
ist ganz anders.

Oliver

von S. Landolt (Gast)


Lesenswert?

> ... im letzten Thread ...

Hallo Veit Devil,

? - mit Herrmann verwechselt, oder gusseisernes Gedächtnis?

von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> was haben wir (ich) versucht dir im letzten Thread zum Thema
> beizubringen?
> Bist du lernfähig? Es gibt auch keinen Prescaler 5. Auch wenn ich erahne
> was das sein soll, macht man nicht.

Ich bin ja sonst ein sehr umgänglicher Mensch, aber gehts dir noch gut 
??? Noch überheblicher gehts ja nun wohl wirklich nicht ! Behandel mich 
mal nicht wie einen dummen Schuljungen. Wenn du nur absolut ansatzweise 
halb so gut wärst würdest du etwas sehen (und jeder hat seinen eigenen 
Stil und macht die Dinge so, wie er sie eben macht).

Einen Prescaler lt. Datenblatt gibt es nicht, sonder wird über 3 Bits 
eingestellt macht bei Timer 0 und 2 insgesamt 8 Möglichkeiten... du 
kapierst und hast etwas Ahnung von binären Zahlen - ich kann das auch, 
überheblich sein. Das sind dann sämtliche Kombinationen von 0-0-0 bis 
1-1-1 ... die clockselctorbits liegen auf D3:D0 auf den jeweiligen 
Registern, was da heißt: 5 entspricht 1-0-1 und setzt CS2:CS1:CS0 auf 
... na ... überleg das mal .. natürlich auf Option 5 , in Worten FÜNF 
... und das ist der Prescaler ... na... für was ... für einen Divisor 
128.

Für dich vllt. hätte man das auch Prescaleroption nennen können oder wie 
auch immer. Ändert aber nichts an der Tatsache dass du keinen Deut 
geholfen hast ! (im übrigen ist das in MEINER Source dokumentiert)

Ich reg mich auf ... BEIZUBRINGEN ... VEIT ist noch sein Clone von 
zensiert

Meine Gedanken über dich ... kennst du nicht, aber jetzt vllt. schon . 
Ich bitte dich höfflichst, dich von meinen Threads fernzuhalten. Danke !

von S. Landolt (Gast)


Lesenswert?

Also hier bei uns ist Feiertag ...

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
> Stimmt!
> Faktor 8 zwischen den Ergebnissen - aha: bei Timer2 entspricht die '5'
> /128, bei Timer0 /1024.

Die Initialisierung wird an anderer Stelle vorgenommen und hat dann 
etwas in dieser Art, weil ein automatischer Scan der Optionen 
vorgenommen wird. Da st

S. Landolt schrieb:
>> ... macht man nicht.
>
> Stimmt!
> Faktor 8 zwischen den Ergebnissen - aha: bei Timer2 entspricht die '5'
> /128, bei Timer0 /1024.

Sagt wer, dass "MAN" das nicht macht?

Im übrigen Programm steht da dann so etwas drin:
1
  switch (csbits)
2
  {
3
    case 1 : divisor= 1; break;
4
    case 2 : divisor= 8; break;
5
    case 3 : divisor= 64; break;
6
    case 4 : divisor= 256; break;
7
    case 5 : divisor= 1024; break;
8
    default : break;
9
  }

Damit ein iterativer Scan über alle möglichen einstellbaren Frequenzen 
machbar ist.

Naaaaaatürlich kann man auch so etwas machen:

  TCCR2B = (1 << WGM22) | CS22 | CS21 | CS20;

Das ist dann besser lesbar? Ich kenne nicht jedes Bit und jeden Teiler 
auswendig (vor allen Dingen nicht wie die Teilerverhältnisse sind) und 
noch lustiger, dass der Teiler von Timer1 zu Timer0/2 abweicht. Also 
erklärt mir nicht, was "MAN" tut und was nicht !

Vllt. sollt ich für die absoluten "Lehrmeister" (ich bin selbst 
Ausbilder) dann noch hinzuschreiben:

// 1 : CS20= 0; CS21= 0; CS20= 0;

so als Kommentar?

Mir ist das binäre Zahlensysteme (und das hexadezimale) durchaus 
geläufig !

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
> Also hier bei uns ist Feiertag ...

Hier auch

von Ralph S. (jjflash)


Lesenswert?

Oliver S. schrieb:
> Bei allen AVR Mega/Tiny ist Timer 0 anders als die anderen, und Timer 2
> ist ganz anders.
>
> Oliver

Das bemerke ich gerade, nur werde ich nicht schlau draus was. Ich sehe 
noch andere Optionen, aber lt. Datenblatt müßte das funktionieren. Müßte 
! (und es hat wohl auch einen Grund, warum ich damals Timer0 nicht als 
PWM-Generator verwendet habe).

Ziel des ganzen ist ein:

uint16_t pwmt0_setfreq(uint16_t freq, uint16_t duty);
uint16_t pwmt1_setfreq(uint16_t freq, uint16_t duty);
uint16_t pwmt2_setfreq(uint16_t freq, uint16_t duty);

Das funktioniert für Timer1 (16-Bit) und Timer2 (8-Bit) sehr gut. Die 
wirklich eingestellte Frequenz wird zurückgegeben. Nur Timer0 will da 
nicht (wobei das ganz merkwürdige ist, dass das für bestimmte 
Einstellung doch funktioniert).

Und wenn ich schon dabei bin: Wenn eine PWM auf einem Pin bereits 
gelaufen ist, sagen wir mittels Timer1 auf PB1.

Wie initialisiert man den PB1 nach gestoppter PWM wieder als GPIO ?

von S. Landolt (Gast)


Lesenswert?

> Ich kenne nicht jedes Bit und jeden Teiler auswendig ...
Nun ja, und eingangs gezeigte Schreibweise verleitet eben dazu, nicht 
ins Datenblatt zuschauen. Nach meiner unmaßgeblichen Meinung zumindest.

> (ich bin selbst Ausbilder)
Pardon, dann allerdings erstaunt mich der Umgangston.

von S. Landolt (Gast)


Lesenswert?

> Nur Timer0 will da nicht

Ich hatte doch oben geschrieben, dass diese '5' bei Timer0 einen 
Vorteiler von 1024 einschaltet.

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
> /128, bei Timer0 /1024.

Timer 0 hat dieselben Einstellungen des Prescalers wie Timer1 und nicht 
wie Timer 2

Das war der Fehler.

--------------

Und an die Besserwisser:

Nein, das hätte man auch mit einer Bitverknüpfung nicht richtig gemacht:

  TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
  TCCR0B = (1 << WGM02) | CS02 | CS00;   // teilt durch 1024

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
> Ich hatte doch oben geschrieben, dass diese '5' bei Timer0 einen
> Vorteiler von 1024 einschaltet.

;-) ja ... sorry... ich habe es in meinem Zorn überlesen gehabt. Danke

von Bentschie (Gast)


Lesenswert?

Ralph S. schrieb:
> Wie initialisiert man den PB1 nach gestoppter PWM wieder als GPIO ?

Ganz einfach. Du musst im Register TCCR0A die COM0Ax/COM0Bx bits wieder 
löschen, dann ist das wieder ein normaler GPIO.

von S. Landolt (Gast)


Lesenswert?

> Nein, das hätte man auch mit einer Bitverknüpfung
> nicht richtig gemacht:
>
>  TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
>  TCCR0B = (1 << WGM02) | CS02 | CS00;   // teilt durch 1024

Pardon, aber: so natürlich auf gar keinen Fall.

von c-hater (Gast)


Lesenswert?

Ralph S. schrieb:

> Behandel mich
> mal nicht wie einen dummen Schuljungen.

Er behandelt dich als das, was du bist: offensichtlich vollständig 
lernresistent.

> Einen Prescaler lt. Datenblatt gibt es nicht

Ach ja? Also in meinem DB gibt's sogar eine ganze Tabelle dazu, nämlich 
folgende:

Table 15-9. Clock Select Bit Description
CS02 CS01 CS00 Description
0 0 0 No clock source (Timer/Counter stopped)
0 0 1 clk I/O /(No prescaling)
0 1 0 clk I/O /8 (From prescaler)
0 1 1 clk I/O /64 (From prescaler)
1 0 0 clk I/O /256 (From prescaler)
1 0 1 clk I/O /1024 (From prescaler)
1 1 0 External clock source on T0 pin. Clock on falling edge.
1 1 1 External clock source on T0 pin. Clock on rising edge.

> eingestellt macht bei Timer 0 und 2 insgesamt 8 Möglichkeiten...

Ja, nur halt verschiedene. Die entsprechende Tabelle von Timer2 
(natürlich ebenfalls im DB enthalten) sieht nämlich so aus:

Table 18-9. Clock Select Bit Description
CS22 CS21 CS20 Description
0 0 0 No clock source (Timer/Counter stopped).
0 0 1 clk T2S /(No prescaling)
0 1 0 clk T2S /8 (From prescaler)
0 1 1 clk T2S /32 (From prescaler)
1 0 0 clk T2S /64 (From prescaler)
1 0 1 clk T2S /128 (From prescaler)
1 1 0 clk T 2 S /256 (From prescaler)
1 1 1 clk T 2 S /1024 (From prescaler)

> was da heißt: 5 entspricht 1-0-1 und setzt CS2:CS1:CS0 auf
> ... na ... überleg das mal .. natürlich auf Option 5 , in Worten FÜNF
> ... und das ist der Prescaler ... na... für was ... für einen Divisor
> 128.

Bei Timer2 ja, aber nicht bei Timer0...

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
>> Nein, das hätte man auch mit einer Bitverknüpfung
>> nicht richtig gemacht:
>>
>>  TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
>>  TCCR0B = (1 << WGM02) | CS02 | CS00;   // teilt durch 1024
>
> Pardon, aber: so natürlich auf gar keinen Fall.

Ganz genau: so eben nicht!

Bentschie schrieb:
> Ganz einfach. Du musst im Register TCCR0A die COM0Ax/COM0Bx bits wieder
> löschen, dann ist das wieder ein normaler GPIO.

genau das tut es nicht !

von Ralph S. (jjflash)


Lesenswert?

Ralph S. schrieb:
> S. Landolt schrieb:
>>> Nein, das hätte man auch mit einer Bitverknüpfung
>>> nicht richtig gemacht:
>>>
>>>  TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
>>>  TCCR0B = (1 << WGM02) | CS02 | CS00;   // teilt durch 1024
>>
>> Pardon, aber: so natürlich auf gar keinen Fall.
>
> Ganz genau: so eben nicht!

In anderen Programmen (außerhalb des automatischen Einstellens) habe ich 
das so gemacht (und hätte ich in meinen weiteren Sourcen gelesen, wäre 
es mir aufgefallen):
1
#define tim01_divisor1       1
2
#define tim01_divisor8       2
3
#define tim01_divisor64      3
4
#define tim01_divisor256     4
5
#define tim01_divisor1024    5

Für das Scanen war das aber nicht praktikabel (und wurde deshalb mit 
switch-case gemacht... )

von Ralf G. (ralg)


Lesenswert?

Ralph S. schrieb:
> Und an die Besserwisser:
>
> Nein, das hätte man auch mit einer Bitverknüpfung nicht richtig gemacht:
>
>   TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
>   TCCR0B = (1 << WGM02) | CS02 | CS00;   // teilt durch 1024

Ergibt aber keinen Sinn. Außer du hast dir deine eigenen 'CSnn' 
definiert.

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> Pardon, aber: so natürlich auf gar keinen Fall.
Das ist ganz normal...
Wenn die Zorn Emotion das Gehirn durchspült, setzt der Verstand und die 
Logik aus.
Zorn schließt die Poren der Wahrnehmung.

Ralph S. schrieb:
> genau das tut es nicht !
Doch genau so tut das!
Du kannst die Pins an den Timer binden, und auf umgekehrtem Wege wieder 
lösen.

von Ralph S. (jjflash)


Lesenswert?

Ralf G. schrieb:
> Ergibt aber keinen Sinn. Außer du hast dir deine eigenen 'CSnn'
> definiert.

Wenn du das ausprobierst, wirst du feststellen, dass diese als 
Bitpositionen in der AVR-Toolchain bpsw. in iom328p.h deklariert sind 
und automatisch mit eingebunden werden.

von Bentschie (Gast)


Lesenswert?

Ralph S. schrieb:
> Wenn du das ausprobierst, wirst du feststellen, dass diese als
> Bitpositionen in der AVR-Toolchain bpsw. in iom328p.h deklariert sind
> und automatisch mit eingebunden werden.

Ähh, ich glaube ja er meint das du die Schiebeoperation vergessen hast.

Also statt:
TCCR2B = (1 << WGM22) | CS22 | CS20;   // teilt durch 128
das hier:
TCCR2B = (1 << WGM22) | (1 << CS22) | (1 << CS20);   // teilt durch 128

Siehst du es jetzt?

von Ralph S. (jjflash)


Lesenswert?

Ja okay, das war im Eifer des Gefechtes...

von Ralph S. (jjflash)


Lesenswert?

Durchschnaufen, baumeln lassen... runterkommen (gilt für mich)

Wie hatte das der Fanboy gesagt:

Arduino Fanboy D. schrieb:
> Wenn die Zorn Emotion das Gehirn durchspült, setzt der Verstand und die
> Logik aus.
> Zorn schließt die Poren der Wahrnehmung.

Stimmt

von Veit D. (devil-elec)


Lesenswert?

S. Landolt schrieb:
>> ... im letzten Thread ...
>
> Hallo Veit Devil,
>
> ? - mit Herrmann verwechselt, oder gusseisernes Gedächtnis?

Hallo,

vielleicht habe ich ihn ja doch verwechselt, liegt im Bereich des 
möglichen. Dann tuts mir leid. Timer Threads gabs in letzter Zeit zu 
viele.

Nur wenn man mit jeder Antwort immer nur Bruchstücke liefert, muss 
zwangsweise Verwirrung entstehen. Man sieht ja was dabei herauskommt. Im 
Eingangsthread war nichts ersichtlich was er am Ende alles definiert 
bzw. nicht definiert hat. Man musste aus seiner Sicht falsche Schlüsse 
ziehen. Ich habe jedoch hier die Lust verloren meine Hilfe anzubieten.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich habs doch richtig in Erinnerung gehabt.
Beitrag "AVR, progmenu array mit strings und unsigned char: will nicht so recht !"

Ich zitiere:

Veit D. schrieb:
> Ab dem neuen Jahr zeigste den kompletten Code!

Ralph S. schrieb:
> den zeige ich in der Regel immer. Hier ging es aber ums Array an sich
> (und das was die Lösung war hatte ich schon mal gewußt und schlicht
> wieder vergessen gehabt).

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

... und für den ganze Ärger (ich reg mich nicht mehr auf), der komplette 
(und fertige) Code im Anhang (den sowieso keiner lesen will).

Irgendwie habt ihr es wirklich wirklich drauf, einem ...

Im Anhang halt (und kümmere ich mich um meine anderen Dinge).

von S. Landolt (Gast)


Lesenswert?

> Irgendwie habt ihr es wirklich wirklich drauf, einem ...

Wie dem auch sei - Tatsache ist, dass bereits nach zehn Minuten der 
korrekte Hinweis kam, in anständigem Umgangston.

von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> ich habs doch richtig in Erinnerung gehabt.
> Beitrag "AVR, progmenu array mit strings und unsigned char: will nicht
> so recht !"
>
> Ich zitiere:
>
> Veit D. schrieb:
>> Ab dem neuen Jahr zeigste den kompletten Code!
>
> Ralph S. schrieb:
>> den zeige ich in der Regel immer. Hier ging es aber ums Array an sich
>> (und das was die Lösung war hatte ich schon mal gewußt und schlicht
>> wieder vergessen gehabt).

Was machst du mich eigentlich immer permanent schräg von der Seite an? 
Ich habe dir noch nicht ans Bein gepinkelt oder vors Schienbein 
gestoßen. Du bist auch nicht mein Arbeitgeber oder mein Vormund oder 
mein was weiß ich und schon überhaupt gar nicht hast du irgendein Recht 
mich (oder sonst jemanden) zu bevormunden und Regeln aufzustellen. Wenn 
du nur xyz daherlaberst ohne einen fachlichen Zusatz, so kannst es 
lassen. Dann... gibts hier welche, die fahren auch jemanden über den 
Mund und meinen zu schulregeln zu müssen, lassen dann aber dennoch einen 
fachlichen Kommentar oder eine Idee ab.

Du gehörst schlicht nur zu denen, die sagen: so nicht ! Das ist einfach. 
Aber schon gar nicht - und jetzt sage ich : so nicht  - lädt man im 
Reflex eine Beleidigung ab ohne noch mal richtig den Sachverhalt gelesen 
zu haben. Hier muß ich sagen Burschi:

SO NICHT !

Das hier ist ein tolles Forum, würde es nicht solche  wieder zensiert  
geben wie es dich gibt. Sie können einem den Spaß an der Sache 
verleiten. Außerdem macht der Ton bekanntlich die Musik. Einem Menschen, 
der kurz vor der Rente ist zu behandeln wie jemandem im 1. Lehrjahr 
(ohne genauer hinzugucken) ist schlichtweg extremst daneben deshalb auch 
hier:

SO NICHT !

Respekt - und ich gehe davon aus dass du deutlich jünger bist als ich - 
ist etwas, das du scheinbar noch lernen mußt. Nicht vor mir, es gibt 
genügend, die Respekt vor mir haben. In der heutigen Zeit scheint es 
immer weniger Anstand und Manieren zu geben und du gehörst zu 
Führungsgruppe der Manier- und Anstandslosen. Ich sagte Führungsgruppe, 
denn es gibt da noch einige andere mehr.

Es ist nicht Sinn und Zweck der Übung, mit brachialer Gewalt jedem 
seinen eigenen Stil aufzwingen zu wollen (das fängt bspw. mit der Art 
und Weise der Einrückung im Quelltext an) und hört mit 
Namenskonventionen nicht auf.

So, und dann zu dem "vollständigen Code" : Es kann bisweilen etwas schon 
sehr groß werden im Code und keiner wird das lesen. In der Regel kann 
ich schon sehr gut realisieren wo der Teufel begraben ist (und in diesem 
Falle hier war es die Initialisierung). Was interessiert der komplett 
andere Rest?

Es ist unglaublich, wie schnell (und ich muß auch sagen bösartig) manche 
hier sofort reagieren wenn etwas nicht so geschrieben ist wie IHR das 
wollt. Unfassbar.

Ich hoffe das lesen genügend, aber helfen wird dieser Text hier auch 
nichts... Leider

Außerdem hatte ich es ja gesagt Veit D. : es wäre mir Recht, wenn du 
dich von Postings von mir fernhälst, von dir kommt nur die heiße Luft 
die ich nicht brauche. In aller Regel würde ich von mir aus über dich 
nicht schreiben und auch zu den Kommentaren die du ablädst (so er sich 
nicht direkt auf mich bezieht) keine Äußerung tätigen. Schade ist, dass 
es hier nicht so etwas wie \ ignore user gibt (wie das in uralten Chats 
mal möglich war) um den Mist von manchen erst gar nicht zu lesen.

In diesem Sinne: Es ist Feiertag

von c-hater (Gast)


Lesenswert?

Ralph S. schrieb:

> ... und für den ganze Ärger (ich reg mich nicht mehr auf), der komplette
> (und fertige) Code im Anhang (den sowieso keiner lesen will).

Ich hab' ihn gelesen und festgestellt, dass er immer noch sehr 
unvollständig ist. Er bildet gerade mal einen Teil der "klassischen" 
ATMegas ab.

> Irgendwie habt ihr es wirklich wirklich drauf, einem ...

Ja, die Wahrheit ist manchmal schwer zu akzeptieren. Aber sie bleibt 
trotzdem wahr. Das ist dein Problem: du bist nicht bereit, diese 
Wahrheit zu akzeptieren. Und die heisst: Es ist Schwachsinn, Baugruppen, 
die in ihrer Hardware offensichtlich massiv differieren können, über ein 
gemeinsames API benutzen zu wollen.

Das führt nach den Gesetzen der Logik nämlich unweigerlich dazu, dass 
entweder Teile der Funktionalität verborgen werden müssen (=der 
Arduino-Weg...) oder dass das API mindestens genauso komplex sein muss, 
wie die Hardware selber (=der Weg vieler APIs für die Hardware neuerer 
MCUs).

Beides ist letztlich Scheisse, denn es verhindert, dass man einfach im 
DB nachschauen kann, um die Funktion festzulegen bzw. zu ermitteln.

Ein Irrweg, der letztlich nur in den Abgrund führen kann. So oder so, 
man macht sich abhängig von den "Zulieferern".

von Ralph S. (jjflash)


Lesenswert?

S. Landolt schrieb:
> Wie dem auch sei - Tatsache ist, dass bereits nach zehn Minuten der
> korrekte Hinweis kam, in anständigem Umgangston.

... der kam von dir als erstem und ich habe mich auch bedankt. Von dir 
hatte ich es auch gar nicht so.

Aber bei so etwas hier:

Veit D. schrieb:
> was haben wir (ich) versucht dir im letzten Thread zum Thema
> beizubringen?

... unglaublich. So rede ich nicht mal mit Lehrlingen wenn sie zum 
wiederholten male gleiches falsch machen.

Veit D. schrieb:
> Bist du lernfähig?

Bin ich, es wird zwar langsamer, aber immer noch satt...

Veit D. schrieb:
> Es gibt auch keinen Prescaler 5

Den es eben sehr wohl gibt, selbst C-hater hat das absolut auch so 
gesehen (und das will schon etwas heißen) und außerdem (aber zeitlich 
nach dir)

c-hater schrieb:
> Bei Timer2 ja, aber nicht bei Timer0...

meinen Fehler gesehen hat.

Wirklich wirklich wirklich übel an diesem Forum ist, dass man sich auf 
jeden großen oder kleinen Fehler stürzt wie ein Geier um sich über 
andere zu stellen. Das ist nicht Sinn und Zweck. Ich habe keine Ahnung 
wie oft ich ein Problem- und ein Problemchen gehabt habe, das mich Zeit 
gekostet hat und das hier jemand sofort gesehen hätte.

Es gibt Dinge, da geht es ums lernen, ums Verständnis. Da ist es 
gerechtfertigt bestimmte Dinge durchzukauen, nachzuhaken, zu fragen ob 
etwas verstanden wurde. Und dann gibt es Fehlersuche bei der im besten 
Falle das Vorgehen bei der Fehlersuche eine Sache ist.

Ich muß aber nicht rudimentäres C neu lernen und mich dem Stil anderer 
anpassen oder gar unterwerfen ("das macht man so nicht") und ich habe 
auch kein Verständnisproblem, wie eine PWM, ein Timer oder ein Interrupt 
funktioniert (dafür mache ich das schon - auch beruflich - zu lange).

Aber du hast Recht, der Ton blieb halbwegs anständig (außer von Veit... 
und von C-hater von dem man das sowieso gewohnt ist.. aber hier auch: 
von C-hater kommt wenigstens ein fachlicher Hinweis).

von Veit D. (devil-elec)


Lesenswert?

@ Ralph S.

Du bist leider dermaßen in deiner Wutphase gefangen, dass du nicht 
verstehen möchtest was in deinem Eingangspost schief gelaufen ist. Wie 
will man da helfen? Vielleicht war ich zu direkt, vielleicht auch nicht. 
Beleidigend war es auf jeden Fall nicht. Von permanent kann auch keine 
Rede sein. Du steigerst dich in etwas rein was gar nicht vorhanden ist.

Wie c-hater schon sagte, dein Code ist immer noch fehlerhaft.

Ich lasse mich gern belehren und korrigieren, aber wer laut wird muss 
liefern können.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Ralph S. schrieb:
> (ich bin selbst Ausbilder)
Dann bin ich froh, dass dich nicht während meiner Ausbildung vor dir 
hatte.
Und du solltest auch darüber froh sein.

Bei dem ganzen Schaum vorm Mund, merkst du gar nicht, das du dich am 
dollsten daneben benimmst....

Tipp:
Lese dir den Thread noch mal in einem Monat durch.

Zudem wäre es mir recht, wenn du mich nicht weiter per PMs belästigst.

von S. Landolt (Gast)


Lesenswert?

an Ralph S.:

Da Sie seit neun Jahren dabei sind, kennen Sie ja auch die gravierenden 
Missstände hier - die Umgangsformen sind regelmäßig unterirdisch. Und 
von einem Ausbilder hätte ich bessere Nerven erwartet; aber ich sehe und 
akzeptiere, dass es sich geradezu um eine allergische Reaktion handelt.
  Und muss zugeben, dass auch ich über Veit D.s Ton etwas erstaunt war - 
eigentlich kenne ich ihn anders.

an Veit D.:

> ... Eingangspost schief gelaufen ist. Wie will man da helfen?
Es lag doch offen zutage!? Das ursprüngliche Problem, meine ich; um 
andere Fehler kümmere ich mich nicht, zumindest nicht ungefragt.


Ein schönen Abend allerseits, ich bin hier weg.

von my2ct (Gast)


Lesenswert?

Ralph S. schrieb:
> Vllt. sollt ich für die absoluten "Lehrmeister" (ich bin selbst
> Ausbilder)

Ralph S. schrieb:
> Ich bitte dich höfflichst, dich von meinen Threads fernzuhalten. Danke !

Dann solltest du in der Lage sein, Konsistenz zwischen deiner Wortwahl 
und dem Inhalt herzustellen.

von Ralph S. (jjflash)


Lesenswert?

c-hater schrieb:
> Es ist Schwachsinn, Baugruppen,
> die in ihrer Hardware offensichtlich massiv differieren können, über ein
> gemeinsames API benutzen zu wollen.

Puuuh, darüber kann man trefflich streiten. Ich gebe dir in soweit 
Recht, dass hierüber sich Fehler einschleichen (wie man gesehen hat) und 
ich gebe dir erst recht Recht damit, dass über so ein API nicht mehr 
gesehen wird was sich dahinter verbirgt (und dass das heute leider die 
übliche Geschichte ist wo etwas zu "lernen" aufhört, weil man nur eine 
API verwendet aber kein Gespür dafür hat wieso das funktioniert und wo 
die Grenzen liegen).

Die API eines PKW's und eines LKW's sind gleich: Gaspedal, Bremspedal, 
Kupplung, Lenkrad. Wenn du nicht weißt, warum das Ding fährt kannst du 
dennoch damit fahren. Aber bisweilen ist es sinnvoll zu wissen, warum 
das fährt, wie das zu reagieren hat und was man machen kann und was man 
tunlichst nicht machen sollte. Die API ist aber gleich.

c-hater schrieb:
> Das führt nach den Gesetzen der Logik nämlich unweigerlich dazu, dass
> entweder Teile der Funktionalität verborgen werden müssen

Genau das war mein Sinn !

c-hater schrieb:
> (=der
> Arduino-Weg...)

Na ja ... hmmm.... ob man jetzt den "Arduino-Weg" mag oder nicht sei 
dahingestellt.
Es sind fertige Baugruppen und die verwendet man eben, ohne sich 
jedesmal neu Gedanken darüber zu machen warum das jetzt funktioniert. 
Bspw. weiß ich, dass auf einem Cortex Controller schon alleine für die 
GPIO's ein Takt einzuschalten ist und eine Unmenge an Konfiguration zu 
machen ist, bevor ich auch nur eine 1 oder 0 setzen kann. Es macht 
keinen Sinn, mir jedesmal Gedanken darüber zu machen  wie das geht (und 
schon gar nicht für unterschiedliche Prozessorfamilien). Es sollte doch 
genügen, wenn man im Datenblatt sieht wie es geht, das einmal umsetzt 
und die Grenzen der Umsetzung kennt.

Wenn es dann spezieller wird, oder die Resourcen (Geschwindigkeit ist 
auch eine Resource) nicht reichen, kann man sich noch einmal etwas 
vornehmen.

Ob das alles Scheiße ist, darf jeder für sich selbst beantworten.

c-hater schrieb:
> Beides ist letztlich Scheisse, denn es verhindert, dass man einfach im
> DB nachschauen kann, um die Funktion festzulegen bzw. zu ermitteln.

Na ja... ich hab heute lange ins DB geschaut und in aller Regel schaue 
ich ins DB. Aber das DB hat die böse Angewohnheit wie ein 
selbstgeschriebener Text: Du liest deinen Text (deinen eigenen) 1000 mal 
und findest keine Schreibfehler. Weil du GLAUBST deinen eigenen Text zu 
kennen. Jemand anderes sieht die Fehler jedoch sofort. Genauso verhält 
es sich mit dem Datenblatt. Du liest die entsprechenden Stellen zig 
mal.. im vorliegenden Falle gibt es 3 Tabellen mit den Prescaler-Bits. 2 
sind identisch, einer differiert. Du siehst noch nicht einmal sofort, 
wenn du auf die Tabelle schaust, zu welchem Timer die jetzt gerade 
gehören die du auf dem Bildschirm hast. Dann kommt die "Unmöglichkeit" 
hinzu, dass ein 8-Bit Timer dieselben Einstellungen (beim Prescaler) wie 
der 16-Bit Timer hat wo man eigentlich schwer davon ausgeht, dass eher 
die beiden 8-Bit Timer identisch wären. Dann vergleicht man zwar noch 
(und zwar immer wieder) die Positionen der Selektorbits im Register... 
aber wie in meinem Falle nicht mehr alle Teiler (was mir natürlich nicht 
mehr passieren wird, zumindest nicht mit AVR).

Dass du kein Freund vom Arduino-Weg bist, ist bekannt. So wirklich ein 
Freund davon bin ich auch nicht, aber Arduino hat den einen Vorteil 
eben, dass die Hardware sehr abstrahiert wird. Wie stark man diese 
Abstraktionen annehmen will sollte jedem selbst überlassen bleiben.

Im Laufe meines Berufslebens hatte ich mit MCS-51, PIC16F, MSP430, AVR, 
STM32F und STM8F zu tun (lustigerweise dienstlich noch nie NXP). Hier 
habe ich es mir sehr zur Angewohnheit gemacht, eine API (auch wenn die 
Hardware sehr unterschiedlich ist) so ähnlich wie nur möglich zu machen. 
Kommt es auf Geschwindigkeit nicht an, werden Pins immer nach demselben 
Schema angesprochen. Muß es genauer werden, schaut man eben nochmal ins 
Datenblatt. Scheiße ist... das Rad jedesmla neu zu erfinden

von Veit D. (devil-elec)


Lesenswert?

S. Landolt schrieb:

> Und muss zugeben, dass auch ich über Veit D.s Ton etwas erstaunt war -
> eigentlich kenne ich ihn anders.
>
> an Veit D.:
>> ... Eingangspost schief gelaufen ist. Wie will man da helfen?
> Es lag doch offen zutage!? Das ursprüngliche Problem, meine ich; um
> andere Fehler kümmere ich mich nicht, zumindest nicht ungefragt.

Keine Sorge. Eigentlich helfe ich jedem der möchte im normalen Ton. Hier 
lag noch eine Erinnerung im Gedächtnis, deswegen ist das etwas direkter 
gewurden. Wer das als Beleidigung aufgefasst hat bitte ich um 
Entschuldigung.

von c-hater (Gast)


Lesenswert?

Ralph S. schrieb:

> Die API eines PKW's und eines LKW's sind gleich: Gaspedal, Bremspedal,
> Kupplung, Lenkrad. Wenn du nicht weißt, warum das Ding fährt kannst du
> dennoch damit fahren.

Nicht wirklich. Das fängt schon auf viel kleinerer Ebene an: ein Mensch, 
der nur auf einem Vehikel mit Automatikgetriebe gelernt hat, ist unfähig 
ein Vehikel mit manueller Schaltung zu fahren. Und tatsächlich nimmt 
sogar der Gesetzgeber (der mit technischer Kompetenz typischerweise 
nicht gerade gesegnet ist) darauf die entsprechende Rücksicht...

So blöd ich Auto-Vergleiche normalerweise finde: das ist ein schönes 
Beispiel, wo sie vom Prinzip her durchaus passen...

Arduino-User=Automatik-Fahrer...

Schlimm ist nur, dass zwar dem Automatik-Fahrer verboten ist, ein Auto 
mit manuellem Schaltgetriebe im öffentlichen Straßenverkehr zu bewegen, 
aber nicht dem Arduino-Sklaven, einen Controller, von dem er ganz 
offensichtlich nichtmal das DB gelesen hat...

Hier würde ich dringend eine entsprechende Gesetzgebung fordern. 
Insbesondere für den Fall, dass es in's Netzwerk geht...

von Veit D. (devil-elec)


Lesenswert?

Ralph S. schrieb:

> Die API eines PKW's und eines LKW's sind gleich: Gaspedal, Bremspedal,
> Kupplung, Lenkrad. Wenn du nicht weißt, warum das Ding fährt kannst du
> dennoch damit fahren. Aber bisweilen ist es sinnvoll zu wissen, warum
> das fährt, wie das zu reagieren hat und was man machen kann und was man
> tunlichst nicht machen sollte. Die API ist aber gleich.

Dein Interface ist dabei jedoch absolut irreführend.
Dein Interface spricht "prescaler".
1
void pwmt2_init(uint8_t prescale, uint8_t tg, uint8_t tp)
und du schreibst prescale = 5
1
pwmt2_init(5,94,47);

Jeder denkt gleich das es einen Prescaler 5 nicht gibt. Damit sind wir 
wieder beim Eingangsposting. Ohne zu wissen was du mit prescale 
definierst muss man erstmal zum Schluss kommen das es falsch ist. Ich 
selbst würde auch niemals abweichend vom Manual irgendwas neues 
erfinden. Weil es die Nutzung erschwert. Man benötigt in deinem Fall 
wieder eine Übersetzungstabelle welche Nummer welchen tatsächlichen 
Prescaler darstellt. Das will man doch nicht.

Einen Hinweis gebe ich dir noch, wie man es vernünftiger, lesbarer 
schreiben kann. Dann ist zumindestens Prescaler gleich Prescaler und 
nicht irgendwas aus der Luft gegriffenes.
1
void runTimer1 (const unsigned int prescaler)
2
{
3
    TCCR1B &= ~( _BV(CS12) | _BV(CS11) | _BV(CS10) );
4
5
    switch (prescaler) {  
6
      case    1 : TCCR1B |= _BV(CS10);              break;
7
      case    8 : TCCR1B |= _BV(CS11);              break;
8
      case   64 : TCCR1B |= _BV(CS11) | _BV(CS10);  break;
9
      case  256 : TCCR1B |= _BV(CS12);              break;
10
      case 1024 : TCCR1B |= _BV(CS12) | _BV(CS10);  break;
11
      default :   break;
12
    }  
13
}

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

So, jetzt hatte ich mir ja eigentlich vorgenommen gehabt, eine Weile nix 
im Forum zu schreiben, aber jetzt mal ohne "roten Kopf" ohne Zorn, im 
"normalen" halt:

Veit D. schrieb:
> void runTimer1 (const unsigned int prescaler)
> {
>     TCCR1B &= ~( _BV(CS12) | _BV(CS11) | _BV(CS10) );
>
>     switch (prescaler) {
>       case    1 : TCCR1B |= _BV(CS10);              break;
>       case    8 : TCCR1B |= _BV(CS11);              break;
>       case   64 : TCCR1B |= _BV(CS11) | _BV(CS10);  break;
>       case  256 : TCCR1B |= _BV(CS12);              break;
>       case 1024 : TCCR1B |= _BV(CS12) | _BV(CS10);  break;
>       default :   break;
>     }
> }

Man muß ja dieses _BV(bitposition) nicht unbedingt lieben (und ich mags 
gar nicht, dann schon wirklich eher die für mich geläufigere 
Schreibweise

case 1 : TCCR1B |= (1 << CS10); break;

Aber wie auch immer, ich stell das jetzt mal zwar auszugsweise aber 
komplett zusammnenkopiert als Ganzes aus meinem eigenen 
Sourcenverzeichnis hier ein:
1
#include <avr/io.h>
2
3
//----------------------------------------------------------------
4
//   per copy & paste meiner eigenen atm_timers.h
5
//   und das was zu Timer2 gehoert
6
7
#define tim2_fastpwm_enable   1
8
#define tim2_normalmode_init  1
9
10
#define tim2_divisor1         1
11
#define tim2_divisor8         2
12
#define tim2_divisor32        3
13
#define tim2_divisor64        4
14
#define tim2_divisor128       5
15
#define tim2_divisor256       6
16
#define tim2_divisor1024      7
17
18
//----------------------------------------------------------------
19
//   per copy & paste meiner eigenen atm_timers.h
20
//   und das was zu Timer2 gehoert
21
22
#if (tim2_fastpwm_enable == 1)
23
24
  void tim2_fastpwm_init(uint8_t clockdivider, uint8_t t_periode, uint8_t t_pulse)
25
  {
26
    // tim2 = fast-pwm, compare match b, output auf pd3
27
    
28
    // PD3 als Ausgang
29
    DDRD |= 1 << PD3;
30
    
31
    // Timermode und Divider
32
    TCCR2A = (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);    
33
    TCCR2B = (1 << WGM22) | clockdivider ;  
34
    
35
    // Compare match Werte
36
    OCR2A = t_periode;
37
    OCR2B = t_pulse;
38
  }  
39
  
40
#endif  
41
42
#if (tim2_normalmode_enable == 1)
43
44
  void tim2_normal_init(uint8_t clockdivider)
45
  {
46
    // tim2 = normaler timer/counter  
47
    // Timermode benoetigt nur Divider, alle anderen Bits der Register
48
    // sind fuer Normalmode= 0
49
    TCCR2A = 0;
50
    TCCR2B = clockdivider;
51
    
52
    // Zaehlregister reset
53
    TCNT2= 0;
54
  }  
55
56
#endif
57
58
//----------------------------------------------------------------
59
//   und hier damit das als Gesamtes funktioniert ist.
60
int main(void)
61
{
62
  tim2_fastpwm_init(tim2_divisor128, 127, 63);
63
  while(1);
64
}

Das ganze (und ich stoße so etwas normalerweise nicht an) zur 
Diskussion, zu dem, was man tut und was nicht.

Das hier sind für mich 2 Dinge, um nicht immer ins Datenblatt schauen zu 
müssen, sondern ich verwende sie einfach (und das seit Jahren). Da wird 
man wohl betriebsblind, weil das eben meine Namensgebung ist. So, was 
ist daran jetzt (keine provokative Frage) verkehrt. Standardmäßig 
kopiere ich mir den Header in mein Projektordner und mache (wenn wie im 
hier vorliegenden Falle) meine Einstellungen.

Ist es tatsächlich besser, anstelle von

#define tim2_divisor32        3

besser:
#define tim2_divisor32        (1 << CS01 ) | (1 << CS00)

oder:
#define tim2_divisor32        (_BV(CS11) | _BV(CS10))

zu schreiben?

Macht es denn keinen Sinn, sich für die Dinge die man permanent braucht 
sich seine eigene API zu schaffen mit der man versucht halbwegs 
konsistent mit anderen Familien zu sein. Jetzt würde ich wirklich 
wirklich wirklich gerne wissen, wie ihr das handhabt (aber bitteschön 
nicht mit dem Anspruch dass das Gott und die Welt übernehmen muß).

Grundsätzlich (und deswegen ärgere ich mich über meinen Zorn) 
hinterfrage ich meine Dinge schon immer wieder mal, bei Elektronik / 
Hardware, Software oder auch sonst im Leben ob meine Ansichten oder 
Verhaltensweisen noch gültig sind. Wie handhabt ihr Eure euch eigenen 
API's ?

von Ralph S. (jjflash)


Lesenswert?

(und natürlich, wenn ich mir das so ansehe, hätte man die #defines für 
divisor1, divisor8 etc. als Enumerator deklarieren können ...

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ach Mensch Ralph, du machst dir dein Leben hier echt unnötig schwer.
Mir ist es doch vollkommen egal wie du die Bitschieberei schreibst.
1
(1 << CS10 )
2
oder
3
_BV(CS10)

Es ging um den Prescaler. Wenn du deine "Nummerierung" so richtig 
findest dann mach das. Nur sorge bitte beim nächsten Thread dafür das 
man auch gleich sieht was das bedeutet, ansonsten führt das wieder zur 
Verwirrung. Es hat auch niemand etwas gegen selbst geschriebene APIs 
bzw. Interfaces. Hat niemand behauptet und wird niemand behaupten.

Falls du mich fragst. Ich würde bei den vorhandenen im Manual stehenden 
Prescaler Werten bleiben. Das heißt ich würde in dem Fall
1
#define tim2_divisor32   32
schreiben. Und eigentlich würde ich gar kein define schreiben. Enums in 
dem Fall eigentlich auch nicht. Ich würde
1
const uint8_t tim2_divisor32 = 32;

schreiben. Außer es gibt Gründe für define. Wie gesagt, diese defines 
kann man sich dann auch gleich schenken. Denn normalerweise schaut man 
ins Manual welche Prescaler ein Timer hat und freut sich wenn man diese 
Angabe direkt ohne Umschweife im Interface verwenden kann. Das Interface 
ist das was man als Erstes sieht, dass muss möglichst leicht 
verständlich sein.

von Ralph S. (jjflash)


Lesenswert?

so, ich habe mir das jetzt ein paar mal mit verschiedenen Optionen 
angeguckt, wie es für mich am besten ausschaut, nicht nur für die Timer 
jetzt ... auch wenn es ein paar Byte mehr Flash kostet (wenn der eng 
wird muß man das eben händisch machen) mach ich das jetzt so, dass der 
Teilerfaktor als Zahlenwert der Funktion übergeben wird:
1
void pwmt0_init(uint16_t clockdivider, uint8_t t_periode, uint8_t t_pulse
2
{
3
  // WGM00:WGM01, WGM02 in TCCR0B  = 1:1:1 ---> FAST PWM
4
  // COM0B1:COM2B0                 = 1:0   ---> setzt OC2B zu Beginn der Periode, setzt zurueck
5
  //                                            bei erreichen des Comparewerts (in OCR0B)
6
7
  // ----------------------------------------------
8
  // Bits TCCR0B: CS02:CS01:C020 = Bit2:Bit1:Bit0
9
  // ----------------------------------------------
10
  //  CS02   CS01  CS00
11
  //   0      0     0   ---> keine Taktquelle, Timer gestoppt
12
  //   0      0     1   ---> F_CPU / 1
13
  //   0      1     0   ---> F_CPU / 8
14
  //   0      1     1   ---> F_CPU / 64
15
  //   1      0     0   ---> F_CPU / 256
16
  //   1      0     1   ---> F_CPU / 1024
17
  
18
  // PD3 als Ausgang
19
  DDRD |= 1 << PD3;  
20
  
21
  TCCR0A = (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);
22
  TCCR0B = (1 << WGM02);
23
  switch (clockdivider(
24
  {
25
    case 1     : TCCR0B |= (1 << CS00); break;
26
    case 8     : TCCR0B |= (1 << CS01); break;
27
    case 64    : TCCR0B |= (1 << CS01) | (1 << CS00); break;
28
    case 256   : TCCR0B |= (1 << CS02); break;
29
    case 1024  : TCCR0B |= (1 << CS02) | (1 << CS00); break;
30
    default : break;
31
  }
32
33
  OCR0A = t_periode;
34
  OCR0B = t_pulse;
35
}
36
.
37
.
38
// Aufruf
Ganz glücklich bin ich dennoch nicht mit der Lösung, weil es als 
Funktionsargument für - clockdivider - eine 16-Bit Variable benötigt.


pwmt0_init(32, 127, 63);

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn du alles const machst was konstant ist, dann wird auch das switch 
quasi wegoptimiert. Zumindestens ist das bei C++ so. Sollte auch bei C 
so sein, denke ich.
Schreib mal
1
void pwmt0_init(const uint16_t clockdivider, const uint8_t t_periode, const uint8_t t_pulse)
und kompiliere erneut, es sollte kleiner werden ...

Dir fehlt in der Funktionssignatur noch eine Klammer.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> Dir fehlt in der Funktionssignatur noch eine Klammer.

die ist beim Kopieren "verlustig" gegangen ! Ohne die Klammer würde der 
Compiler Fehler ausgeben.

Hmm... mit einem const davor kann ich dann aber zur Laufzeit den Timer 
nicht mehr ändern !

von Einer K. (Gast)


Lesenswert?

Ralph S. schrieb:
> Hmm... mit einem const davor kann ich dann aber zur Laufzeit den Timer
> nicht mehr ändern !

Bei einem const vor einem Funktionsparameter kannst du den Parameter in 
der Funktion nicht mehr ändern.
Das verhindert manche logische Fehler und hilft dem Optimierer etwas 
aufs Pferd.

Aber nichts kann dich daran hindern die Funktion mit verschiedensten 
Parametern aufzurufen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

habe es selbst ausprobiert mit der einen gezeigten Funktion. Es belegt 
306 Byte Flash und 0 Byte RAM. Unabhängig ob die Funktionsparameter 
konstant sind oder nicht. Unabhängig davon sollte man sie dennoch 
konstant machen. Erklärt hat das schon Arduino Fanboy. Bewahrt einem vor 
Syntax Unsinn o.ä..

Ich verstehe nicht warum Arduino Fanboy negativ bewertet wird. Ist doch 
alles korrekt was er sagt.

Im Nachhinein erklärt, kann der Compiler das wohl nicht weiter 
optimieren, weil der Übergabeparameter direkt als Literal ja schon 
konstant ist. So schlau ist der Compiler also schon.

Der größere const Effekt lauert darin, dass hatte ich tiefer in Gedanken 
gehabt, wenn man den Prescaler als Variable übergibt und diese konstant 
macht. Wenn man den zur Laufzeit ändern möchte geht das natürlich nicht. 
Mit enums macht das auch großen keinen Sinn.

Ändere ich den Prescaler Datentyp auf uint8_t werden "nur" 290 Byte 
Flash und 0 Byte RAM belegt. Kommt es dir wirklich auf die 16 Byte Flash 
an? Ich persönlich halte das für den falschen Weg.

Mit enums habe ich auch experimentiert, es ändert sich nicht viel, je 
nachdem was man damit anstellt. Reicht von 290 bis 316 Byte Flash, 
abhängig ob man das enum direkt übergibt oder mittels zusätzlicher enum 
Variable

enums können Sinn machen, wenn du damit sprechende Variablen definierst 
um den Timer-Mode als Parameter zu übergeben.

Jetzt liegst an dir womit du glücklich wirst. Für mich zählt in erster 
Linie lesbarer Code. Wenn man sich deine gezeigte Funktion anschaut, 
dann erübrigt sich die einkommentierte Doku, weil genau das 1:1 im 
switch case steht. Das ist für mich lesbarer Code.

Ich habe mir jetzt genügend Gedanken für dich gemacht. Es gibt Tausende 
Möglichkeiten. Wähle die Sinnvollste.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Veit D. schrieb:
> Ändere ich den Prescaler Datentyp auf uint8_t werden "nur" 290 Byte
> Flash und 0 Byte RAM belegt. Kommt es dir wirklich auf die 16 Byte Flash
> an? Ich persönlich halte das für den falschen Weg.

Nein, kommt mir nicht darauf an. Im Moment geht es mir schlicht darum 
(deswegen jetzt mal zur Diskussion gestellt gewesen) was denn am 
praktikabelsten ist.

Veit D. schrieb:
> Ich habe mir jetzt genügend Gedanken für dich gemacht.

Na ja, das hat ja keiner verlangt, aber dennoch danke !

Veit D. schrieb:
> dann erübrigt sich die einkommentierte Doku

... das kommt immer dann so vor, wenn ich etwas neu mache. Dann kopiere 
ich mir die entsprechenden Stellen aus dem Datenblatt und habe das dann 
in der Übersicht. Schlimm wirds (wie mir hier ja passiert ist), wenn das 
falsch "abgeschrieben" wurde, sich dann nach dem falsch abgeschriebenen 
aber gerichtet wird.

Veit D. schrieb:
> Wenn man den zur Laufzeit ändern möchte geht das natürlich nicht.

Das ist aber genau das, was ich momentan mache. Dieses zu ändern während 
der Laufzeit, weil ich nicht nur die Duty-Cycle ändern will, sondern 
auch die Frequenz.

--------------------------------

Es ist gut, wenn wir diesen Thread abschließen !

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.