DDRD |= (1 << DDD6);
// PD6 is now an output
OCR0A = 128;
// set PWM for 50% duty cycle
TCCR0A |= (1 << COM0A1);
// set none-inverting mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// set fast PWM Mode
TCCR0B |= (1 << CS20);
// set prescaler to 8 and starts PWM
Mein Controller läuft mit ext. 16MHZ (ATMega328) - Arduino Uno
Wo habe ich den Fehler gemacht, dass mir nur ca 1KHZ ausgegeben werden?
es müssten doch eigentlich 8KHZ sein.
Das Gleiche habe ich auch, wenn ich ohne Teiler arbeite, dann müsste ich
ca 62,5KHZ haben und habe nur ca 8KHZ
FUSES habe ich schon überprüft, sollten alle passen.
X. Y. schrieb:> Klaus schrieb:>>> Nebenbei bemerkt: Die Einheit schreibt sich "Hz".>> Das weiß ich wohl ;)
Das mag so sein, wenn Du es sagst. Aber wenn Du es in fünf Fällen
falsch schreibst und in keinem richtig, dann - sagen wir mal - bleibt
ein gewisser Restzweifel. :-)
Klaus schrieb:> X. Y. schrieb:>> Klaus schrieb:>>>>> Nebenbei bemerkt: Die Einheit schreibt sich "Hz".>>>> Das weiß ich wohl ;)>> Das mag so sein, wenn Du es sagst. Aber wenn Du es in fünf Fällen> falsch schreibst und in keinem richtig, dann - sagen wir mal - bleibt> ein gewisser Restzweifel. :-)
schon spät ;) seit 5 uhr wach
X. Y. schrieb:> Klaus schrieb:>> CKDIV8 ?>> gucke nach mom>>> Nebenbei bemerkt: Die Einheit schreibt sich "Hz".>> Das weiß ich wohl ;)
Also FUSES sind zz So:
0xFF 0XDA 0x05
X. Y. schrieb:> schon spät ;) seit 5 uhr wach
Dann würde ich Dir sehr empfehlen mal zu schlafen.
Morgen guckst Du dann in's Datenblatt. Und falls nötig postest Du Code
bitte mit Copy&Paste.
ok, ich machs mal anders, eigentlich will / möchte ich eine Funktion
haben damit ich über
OCR0A = 128;
// set PWM for 50% duty cycle
meine PWM Steuern möchte, eigentlich ohne Teiler und Co. damit ich auf
ca 62.5 KHz komme.
Klaus schrieb:> X. Y. schrieb:>>> schon spät ;) seit 5 uhr wach>> Dann würde ich Dir sehr empfehlen mal zu schlafen.> Morgen guckst Du dann in's Datenblatt. Und falls nötig postest Du Code> bitte mit Copy&Paste.
ich bin noch neu auf diesem Gebiet. Wenn ich 100% ig Bescheid wüsste,
was da so alles passiert, würde ich nicht fragen
X. Y. schrieb:> X. Y. schrieb:>> Klaus schrieb:>>> CKDIV8 ?>>>> gucke nach mom>>>>> Nebenbei bemerkt: Die Einheit schreibt sich "Hz".>>>> Das weiß ich wohl ;)>> Also FUSES sind zz So:>> 0xFF 0XDA 0x05
Und dann guckst Du auch mal nach wofür die Bits stehen. Ich schäme mich
zwar in Grund und Boden für meine Faulheit aber ich will einfach nicht
selbst nachschauen.
X. Y. schrieb:> Klaus schrieb:>> X. Y. schrieb:>>>>> schon spät ;) seit 5 uhr wach>>>> Dann würde ich Dir sehr empfehlen mal zu schlafen.>> Morgen guckst Du dann in's Datenblatt. Und falls nötig postest Du Code>> bitte mit Copy&Paste.>> ich bin noch neu auf diesem Gebiet. Wenn ich 100% ig Bescheid wüsste,> was da so alles passiert, würde ich nicht fragen
Na dann halt nicht. Schönes Leben noch.
Klaus schrieb:> X. Y. schrieb:>> Klaus schrieb:>>> X. Y. schrieb:>>>>>>> schon spät ;) seit 5 uhr wach>>>>>> Dann würde ich Dir sehr empfehlen mal zu schlafen.>>> Morgen guckst Du dann in's Datenblatt. Und falls nötig postest Du Code>>> bitte mit Copy&Paste.>>>> ich bin noch neu auf diesem Gebiet. Wenn ich 100% ig Bescheid wüsste,>> was da so alles passiert, würde ich nicht fragen>> Na dann halt nicht. Schönes Leben noch.
ich habe ja nicht gesagt, das ich mich nicht damit auseinander setzen
möchte. ich will ja verstehen was passiert. das Datenblatt lesen ist ja
kein Problem, die Tabellen und so verstehe ich ja auch, nur das setzten
der einzelnen bits, da habe ich meine Probleme mit
>> Und dann guckst Du auch mal nach wofür die Bits stehen. Ich schäme mich> zwar in Grund und Boden für meine Faulheit aber ich will einfach nicht> selbst nachschauen.http://www.engbedded.com/fusecalc/
Im eingangs gezeigten Programm steht der Vorteiler in Wirklichkeit auf
1, also sollte doch eigentlich eine Frequenz von 16000000/256= 62500
herauskommen.
S. Landolt schrieb:> Im eingangs gezeigten Programm steht der Vorteiler in Wirklichkeit> auf 1, also sollte doch eigentlich eine Frequenz von 16000000/256= 62500> herauskommen.
Ist aber nicht der Fall, es fehlt immer Faktor 8
X.Y schrieb:> Ist aber nicht der Fall, es fehlt immer Faktor 8
Und das liegt eben an deinen Fuses. Wie die eingestellt sind hast du
doch schon geschrieben und die von dir ebenfalls bereits verlinkte
Webseite dekodiert dir das.
Und da steht dann eindeutig dass CKDIV8 aktiv ist!
S. Landolt schrieb:> die low> byte fuse steht nicht auf 0xFF.
Tut sie nicht. Er hat nicht gesagt was die Reihenfolge ist ;)
Aber da der mega328 nur drei Bits in efuse hat, habe ich einfach mal
0xff als efuse angenommen, weil 0x05 für efuse nicht sein kann (nicht
vorhandene Bits müssten gecleart sein)
Er hat lfuse=05 hfuse=da efuse=ff.
S. Landolt schrieb:> Kann ich mir nicht vorstellen, das hieße 'Low Frequency Crystal> Oscillator'.
Hast recht. Das würde nur dann nicht auffallen, wenn der Takt extern
erzeugt wird. Die Unos haben aber nur Quarz oder Keramik.
(Auch scheints wohl Programme zu geben die die nicht vorhandenen Bits
als 0 statt 1 ausgeben. Dann passt 0x05 wieder.)
S. Landolt schrieb:> Kann man in C nicht noch 'F_CPU' oder so was ähnliches definieren?
Hat nur Auswirkungen auf _delay_ms/_delay_us, damit die libc weiß, wie
der Takt eingestellt ist. Verstellen kann man den damit nicht, auch wenn
manche Leute das gerne tun wollen :-)
Das letzte, was ich vorm Bett prüfen würde, ist, welche Frequenz
rauskommt, wenn man das nochmal flasht und CKDIV8 setzt. Und dann,
welche rauskommt, wenn man danach CKDIV8 wieder rausnimmt.
Falls irgendwas falsch gesetzt war, ist es danach vielleicht richtig.
Und wenn nicht, geben die dann noch vorhandenen Fehlerfaktoren ggf
weitere Hinweise, wo der Fehler liegt.
foo schrieb:> Das letzte, was ich vorm Bett prüfen würde, ist, welche Frequenz> rauskommt, wenn man das nochmal flasht und CKDIV8 setzt. Und dann,> welche rauskommt, wenn man danach CKDIV8 wieder rausnimmt.
Das erste was ich prfen würde ist, ob ein _delay_ms(1000) auch wirklich
ca. 1 Sekunde lang dauert, bei einem F_CPU von 16000000.
Das ist der beste Beweis, ob der µC auf 16Mhz läuft oder nicht.
Ehe ich das nicht gecheckt habe, mach ich doch gar nicht erst mit Timern
weiter und such mir einen Wolf in der Konfiguration.
S. Landolt schrieb:> Kann man in C nicht noch 'F_CPU' oder so was ähnliches definieren?
Ja, aber das hat m.E. nur Auswirkungen auf "taktzählende" Routinen wie
ein paar _delay... usw. Funktionen.
Karl H. schrieb:> Schon alleine deshalb, weil die Bezeichnung CS20 zum Timer 2 gehört und> nicht zum Timer 0.
Ist "CS20" nicht einfach eine andere Schreibweise für "0"???
Route 6. schrieb:> Ist "CS20" nicht einfach eine andere Schreibweise für "0"???
Nein, das ist eine Definition.
1
#define CS20 0
Genau so ist auch das CS00, das dahin gehört definiert:
1
#define CS00 0
Das ist jetzt aber nicht die Pedanterie eines Oberkorinthenkackers,
sondern ein Hinweis auf mangelnde Sorgfalt und Copy&Paste ohne Sinn und
Verstand. An dieser Stelle spielt das zufällig keine Rolle. Wer es aber
bei diesen paar Zeilen Code nicht richtig hinkriegt, dem kann man
durchaus zutrauen, dass an anderer Stelle ebensolche Böcke eingebaut
sind, die nicht zufällig funktionieren.
mfg.
Thomas E. schrieb:> sondern ein Hinweis auf mangelnde Sorgfalt und Copy&Paste ohne Sinn und> Verstand. An dieser Stelle spielt das zufällig keine Rolle.
Es spielt insofern eine Rolle, weil das beim Timer 0 keinen Vorteiler
von 8 ergibt. Weder so noch so.
Was, wie du richtig anmerkst, auch für mich ein Hinweis darauf ist, dass
hier wieder mal per Copy&Paste programmiert wird.
Wenn Bezeichnungen nicht zusammenpassen und Kommentare falsch sind,
werde ich stutzig.
hat sich erledigt. keine ahnung was es war aber jetzt wo ich es ohne
bootloader vom arduino gemacht habe sondern es im atmel studio gemacht
habe hat es geklappt
X. Y. schrieb:> TCCR0A |= 10000011;> TCCR0B |= 00000001;
Tut nicht das, was du glaubst, was es tut.
Binärkonstanten werden mit 0b vorne dran angegeben (0b10000011).
(Unabhängig davon, dass es i.A. besser lesbar ist wenn man die
vorhandenen Defines verwendet.)
foo schrieb:> X. Y. schrieb:>> TCCR0A |= 10000011;>> TCCR0B |= 00000001;>> Tut nicht das, was du glaubst, was es tut.>> Binärkonstanten werden mit 0b vorne dran angegeben (0b10000011).>> (Unabhängig davon, dass es i.A. besser lesbar ist wenn man die> vorhandenen Defines verwendet.)
also er tut zz genau das was ich will.
ja werde ich gleich noch ergänzen. aber so weiß ich schonmal, dass es im
Grunde funzt. ich habe direkt mein oszi dran, deswegen weiß ich das es
funzt.
X. Y. schrieb:> also er tut zz genau das was ich will.
Das wird als Dezimalzahl interpretiert. Da in das Register nur 8 Bit
passen werden nur die untersten 8 Bit davon genommen. Du hättest auch
TCCR0A |= 131 schreiben können.
Dass diese untersten 8 Bit nun rein zufällig 0b10001011 entsprechen
und es deshalb das selbe Ergebnis bringt (bei den aktuellen Modellen ist
das vierte Bit noch unbenutzt) heißt nicht dass der Code so korrekt ist.
Würdest du da z.B. 10100011 schreiben (warum auch immer) dann wären die
letzten 8 Bits davon 0b0101011 ... wie du siehst, passt es manchmal
zufällig, manchmal nicht.
Das gleiche gilt natürlich auch für 00000001 (hier passt es aus
naheliegenderen Gründen), beachte hier, dass Zahlen mit führenden Nullen
in C oktal interpretiert werden (d.h. 010 = 8!)
foo schrieb:> X. Y. schrieb:>> also er tut zz genau das was ich will.>> Das wird als Dezimalzahl interpretiert. Da in das Register nur 8 Bit> passen werden nur die untersten 8 Bit davon genommen. Du hättest auch> TCCR0A |= 131 schreiben können.>> Dass diese untersten 8 Bit nun rein zufällig 0b10001011 entsprechen> und es deshalb das selbe Ergebnis bringt (bei den aktuellen Modellen ist> das vierte Bit noch unbenutzt) heißt nicht dass der Code so korrekt ist.>> Würdest du da z.B. 10100011 schreiben (warum auch immer) dann wären die> letzten 8 Bits davon 0b0101011 ... wie du siehst, passt es manchmal> zufällig, manchmal nicht.>> Das gleiche gilt natürlich auch für 00000001 (hier passt es aus> naheliegenderen Gründen), beachte hier, dass Zahlen mit führenden Nullen> in C oktal interpretiert werden (d.h. 010 = 8!)
ok, habe es angepasst :)
hm was jetzt noch mein problem ist, wahrscheinlich wieder simpel, ist
das ich gerne timer 0 und timer 2 mit gleichen config laufen lassen
will. was ich noch nicht ganz verstehe wie ich die timer ausgänge extern
zuweise. es gibt ja für jeden timer 2 externe pins.
Hallo,
für die Ausgabe an den externen Pins hast du im A-Register des Timers
für jeden Ausgang zwei Bits COMnA0/1 für Pin OCnA und COMnB0/1 für OCnB.
Das Datenblatt enthält alle dafür notwendigen Infos.
Sascha
X. Y. schrieb:> keine ahnung was es war aber jetzt wo ich es ohne> bootloader vom arduino gemacht habe sondern es im atmel studio gemacht> habe hat es geklappt
Wenn man Read-Modify-Write Zugriffe macht dann wird der Inhalt nicht
unbedingt komplett überschrieben.
Damit:
1
DDRD|=(1<<DDD6);
2
TCCR0A|=0b10000011;
3
TCCR0B|=0b00000001;
Werden lediglich die angebenen 1-Bits in den Registern auf 1 gesetzt,
die im Register bereits vorhandenen 1-Bits werden aber nicht auf Null
gesetzt.
Wenn der Bootloader die Register bereits anfasst, die also nicht mehr
auf Default-Null sind, dann kann es sein, dass dabei was ganz anderes
raus kommt.
Im Zweifel einfach richtig überschreiben:
Rudolph R. schrieb:> Wenn der Bootloader die Register bereits anfasst, die also nicht mehr> auf Default-Null sind, dann kann es sein, dass dabei was ganz anderes> raus kommt.
Dann ist aber in erster Linie der Bootloader Scheisse.
Das Programm muss von einem Bootloader überhaupt nichts wissen. Wenn der
fertig ist, hat er den Controller besenrein zu übergeben.
mfg.
Thomas E. schrieb:> Das Programm muss von einem Bootloader überhaupt nichts wissen. Wenn der> fertig ist, hat er den Controller besenrein zu übergeben.
Dem kann ich nur zustimmen, ich wollte nur eine mögliche Erklärung für
das Verhalten mit und ohne Bootloader liefern.
Generell ist es aber auch nicht die schlechteste Idee auf sinnlose
Read-Modify-Write zu verzichten und einfach nur zu schreiben wo es
angebracht ist.