ATmega8 mit Quarz 2MHz

Gast #5737055
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.
Gast
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!
Moderator Persönliche Seite
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.
Gast
> 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.
Beitrag #5737374 wurde von einem Moderator gelöscht.
Gast
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
Gast
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?
Gast
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
Moderator Persönliche Seite
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.
Gast
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.
Gast
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
Angehängte Dateien:

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.