Guten Tag, ich bin Schüler und schreibe gerade meine ersten Programme für den ATmgea8. Ich würde gerne ein Metronom programmieren, aber der Systemtakt des Controllers ist wohl zu ungenau, deshalb wurde mir ein externer Quarz empfohlen. Ich habe einen Quarz für 2MHz. Jetzt meine Frage: Wie muss ich den anschließen bzw. was muss ich genau einstellen? Vielen Dank und Grüße aus Südtirol Martin
Also bei einem Metronom sollte man die Ungenauigkeit des int. Oszillators nicht merken können. Das wird eigentlich erst bei asynchroner serieller Kommunikation interessant. Dein Controller hat zwei Pins, die im Datenblatt mit "XTAL1" und "XTAL2" beschriftet sind. Da kommt der Quarz mit seinen beiden Pins dran. Und dann müssen von den beiden Pins jeweils noch ein Keramikkondensator mit 12...22pF (der AVR verzeiht da eigentlich recht viel) zu Ground dran. Dazu dann noch F_CPU mit 2000000 definieren und die Fusebits so einstellen, dass ein externer Crystal mit Low Freq. verwendet wird.
Für die Einstellung des Quarzes als Taktquelle musst du die Fuse Bits anpassen. Ist hier beschrieben: https://www.mikrocontroller.net/articles/AVR_Fuses Dabei kommts auf dein Programmiertool an, deswegen Vorsicht. Der Quarzanschluss ist hier beschrieben: https://www.mikrocontroller.net/articles/Quarze_und_AVR brauchst also noch zwei 22pF-Kondensatoren. ACHTUNG: Erst den Quarz einbauen, dann Fusebits ändern, sonst hat der Atmega keibe Taktversorgung mehr und du kannst ihn nur noch mit "Tricks" programmieren!
martin schrieb: > Jetzt meine Frage: Wie muss ich den anschließen bzw. was muss ich genau > einstellen? Datenblatt Seite 27 C1 und C2 richten sich nach dem Quarz und der so genannten Lastkapazität, die dieser benötigt. Wenn du diese nicht kennst, geh' einfach mit 2 x 22 pF ins Rennen und schau, ob am Ende alles sauber anschwingt. Dort stehen auch einige Fusebits, die du passend einstellen musst. Bei einem 2-MHz-Quarz wäre CKOPT = 1 und CKSEL[3:1] = 110 sinnvoll. Auf Seite 28 folgt eine Tabelle, aus der du weitere Bits auswählen musst. Gehen wir mal davon aus, dass du unter “fast rising power” fällst (weil dein Gerät mit einem Einschalter schlagartig an die Versorgungsspannung angeschlossen wird), dann wären CKSEL[0] = 1 und SUT[1:0] = 10 sinnvoll. Die Fusebytes sind auf Seite 216f. erklärt, das low byte sieht so aus:
1 | +-----------------------------------------------+ |
2 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
3 | +-----------------------------------------------+ |
4 | | BOD | BOD | | | |
5 | |LEVEL| EN | SUT | CKSEL | |
6 | +-----------------------------------------------+ |
Gefüllt mit obigen Werten:
1 | +-----------------------------------------------+ |
2 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
3 | +-----------------------------------------------+ |
4 | | BOD | BOD | | | |
5 | |LEVEL| EN | SUT | CKSEL | |
6 | +-----------------------------------------------+ |
7 | + 1 1 1 0 1 1 0 1 | |
8 | +-----------------------------------------------+ |
(Die beiden Bits für BODLEVEL und BODEN entsprechen der Voreinstellung.) D.h. das low fuse byte wäre 0b11101101 oder 0xed. Das Bit CKOPT befindet sich im fuse high byte, steht aber voreingestellt bereits auf 1; daran muss man also nichts ändern.
> die Fusebits so einstellen, dass ein externer Crystal > mit Low Freq. verwendet wird. Nein. An dieser Stelle versteht Atmel unter "low-frequency" den 32 KiHz-Quarz, sogenannter Uhrenquarz. Es muss "Crystal Oscillator" mit dem Bereich 3.0-8.0 MHz eingestellt werden.
martin schrieb: > Ich würde gerne ein Metronom programmieren Wird es richtig schlagen, oder nur piepsen wie hier: https://www.youtube.com/watch?v=WvCBQp2wdkw https://www.youtube.com/watch?v=IghzuazTRtw
Georg M. schrieb: > Wird es richtig schlagen Er ist Anfänger, lass ihn doch erstmal überhaupt nur dem Teil ein paar Töne entlocken. Seinem Spieltrieb freien Lauf lassen und am Ende vielleicht gar mit einem Mikrofon aufgenommene Samples abspielen kann er ja danach immer noch. ;-) (Dafür könnten 2 MHz Grundtakt allerdings etwas zu wenig sein.)
Beitrag #5737374 wurde von einem Moderator gelöscht.
Hallo, habe jetzt Folgendes gemacht: fuse.c: #include <avr/io.h> FUSES = { .low = 0b11101101, .high = HFUSE_DEFAULT }; main.c: #define F_CPU 2000000 #include <avr/io.h> int main (void) { DDRB =0; DDRB |= (1<<PB1); do { //Hier schalte ich eine LED auf PB1 mit einer vorgegebenen Frequenz ein und aus }while(1); return(0); } Aber die die LED blinkt mit der halben Frequenz, als die von mir eingestellte. Danke im Voraus und Grüße Martin
Du bist ja ein Spassvogel, den entscheidenden Teil deines Programmes hast du geheim gehalten. Mal angenommen, du hast ihn richtig programmiert, dann läuft dein Mikrocontroller immer noch mit den Standard-Einstellungen. Das wäre der interne R/C Oszillator mit 8 MHz, sowie dem Vorteiler durch 8 (CLLDIV8) -> Ergibt 1 MHz Systemtakt. Du musst die Fuses mit deinem Programmieradapter einstellen. Wenn du nur die Kommandos zum Flashen des Programms verwendet hast, sind die Fuses immer noch unverändert. Welche Hard- und Software benutzt du denn dazu?
Ich nutze: usbtiny, avrdude, CodeBlocks Stefanus F. schrieb: > Du musst die Fuses mit deinem Programmieradapter einstellen. Wenn du nur > die Kommandos zum Flashen des Programms verwendet hast, sind die Fuses > immer noch unverändert. Wie stelle ich das ein? Abermals Danke!! Hier mein gesamtes Programm: #define F_CPU 2000000 #include <avr/io.h> int main (void) { int i; int x; DDRB =0; DDRB |= (1<<PB1); do { //EIN PORTB |= (1<<PB1); x=100; do { i=20000; do { i--; }while (i!=0); x--; }while (x!=0); //AUS PORTB &= ~(1<<PB1); x=100; do { i=20000; do { i--; }while (i!=0); x--; }while (x!=0); }while(1); return(0); }
martin schrieb: >> immer noch unverändert. > Wie stelle ich das ein? fast genauso wie du den Programmierst, statt ... nimmtst du die Parameter für Controller/Programmer usw. avrdude ... -U lfuse:w:<0xHH>:m zum nachlesen hier: http://www.ladyada.net/learn/avr/avrdude.html hier kannst du die Fuses berechnen lassen/kontrollieren, wenn du die falsch setzt brauchst du sonst eventuell nen HV Fuse Programmer oder einen externen Takt. http://www.engbedded.com/fusecalc/
martin schrieb: > do { > i=20000; > do > { > i--; > }while (i!=0); > > x--; > > }while (x!=0) was machen diese do/while schleifen? wenn die nur verzögern sollen kannst du auch <util/delay.h> einbinden und dann _delay_ms() oder _delay_us() verwenden. ne Stufe besser wäre nen Timer mit Interrupt zu verwenden (und den Pin im Interrupt zu toggeln), oder wenn es vom Timing mit den Vorteilern passt kannst du auch mit einem Timer den Pin als 50/50 PWM Ausgang benutzen. toggeln kannst du indem du PINB1/PORTB1 einliest und dann PORTB1 auf das Gegenteil setzt. Timer hat auch den Vorteil dass du später z.b. ein Poti einlesen kannst und die Taktdauer dynamisch ändern kannst. edit: avrdude ... -U lfuse:w:<0xHH>:m gilt natürlich nur für die low Fuse, für high muss da hfuse:w... stehen
:
Bearbeitet durch User
K. S. schrieb: > fast genauso wie du den Programmierst, statt ... nimmtst du die > Parameter für Controller/Programmer usw. Die Werte für die Fuses hat er im Programmtext stehen. Aber auch von da aus muss man sie programmieren. > avrdude ... -U lfuse:w:<0xHH>:m In diesem Falle gänge das dann auch mit -U lfuse:w:program.elf. Oder eben manuell -U lfuse:w:0xed Wenn man mit dem Atmel Studio programmiert, muss man meiner Erinnerung nach irgendwo ein Häkchen setzen, damit nicht nur der Flash programmiert wird, aber sie können das auch aus dem ELF-File heraus. > hier kannst du die Fuses berechnen lassen/kontrollieren Die hatte ich ja oben schon vorgerechnet.
Stefanus F. schrieb: > Du musst die Fuses mit deinem Programmieradapter einstellen. Wenn du nur > die Kommandos zum Flashen des Programms verwendet hast, sind die Fuses > immer noch unverändert. > > Welche Hard- und Software benutzt du denn dazu? martin schrieb: > Wie stelle ich das ein? Das kann ich Dir immer noch nicht sagen, weil du meine Frage nach der Hard- und Software nicht beantwortet hast. Deine Verzögerungs-schleifen erscheinen mir fragwürdig: Hast du dich vergewissert, dass sie (korrekter Systemtakt vorausgesetzt) exakt so lange dauern, wie sie sollen? Das hängt doch sehr stark davon ab, welchen Maschinencode der Compiler daraus erzeugt, was wiederum von den Optimierungseinstellungen und der Version des Compilers abhängt. Ausserdem denke ich, dass der Compiler die Schleifen komplett entfernen darf, weil sie keinen Effekt auf RAM und I/O Register haben. Dass er leere Schleifen oft (unerwartet) entfernt ist hier geradezu ein Klassiker. Für solche Zwecke gibt es die include Datei https://www.nongnu.org/avr-libc/user-manual/group__util__delay.html, benutze sie.
Hallo, danke erstmal für die weiteren Antworten. Ich benutze CodeBlocks. Ich habe jetzt, wie man im Anhang sieht, ein neues Tool erstellt. Wenn ich es auf den usbtiny übertragen will kommt die Fehlermeldung, die ich euch auch in den Anhang kopiert habe. Im main.c habe ich nichts mehr definiert, muss ich das denn? Habt bitte Geduld, bin ein totaler Anfänger :) Danke und schönen Abend Martin
Hänge mal den Parameter -B20 an, um den Programmiervorgang zu verlangsamen.
Habe -B20 bei Parameters angehängt. Die Fehlermeldung kommt aber immer noch.
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.