Forum: Mikrocontroller und Digitale Elektronik ATmega8 mit Quarz 2MHz


von martin (Gast)


Lesenswert?

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

von Sebastian R. (sebastian_r569)


Lesenswert?

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.

von Patrick (Gast)


Lesenswert?

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!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

Autsch, 2 MHz liegt zwischen 0.9-3.0, also diesen Bereich wählen.

von Georg M. (g_m)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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

von martin (Gast)


Lesenswert?

Danke für die vielen Antworten. Werde es versuchen.

Beitrag #5737374 wurde von einem Moderator gelöscht.
von martin (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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?

von martin (Gast)


Lesenswert?

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

von K. S. (the_yrr)


Lesenswert?

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/

von K. S. (the_yrr)


Lesenswert?

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
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von martin (Gast)


Angehängte Dateien:

Lesenswert?

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

von martin (Gast)


Angehängte Dateien:

Lesenswert?

und noch der andere Screenshot

von Stefan F. (Gast)


Lesenswert?

Hänge mal den Parameter -B20 an, um den Programmiervorgang zu 
verlangsamen.

von martin (Gast)


Lesenswert?

Habe -B20 bei Parameters angehängt. Die Fehlermeldung kommt aber immer 
noch.

von Stefan F. (Gast)


Lesenswert?

Zeige deinen Schaltplan und mach gute Fotos vom Aufbau.

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.