ATmega8 Clock Problem

OP #5084742
Lesenswert?

Hallo zusammen,
habe eine simple Anfängerfrage mit der ich mich schon viel zu lange 
beschäftige. Da mein Programm nicht wie erwartet funktioniert hat, habe 
ich den Fehler eingekreist und festgestellt, dass meine Clock nicht so 
arbeitet, wie ich erwartet habe.
Daher habe ich mir folgendes Progrämmchen geschrieben, um die Frequenz 
zu überprüfen:
1
#define F_CPU 1000000
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
int main(void){
7
    DDRD |= (1<<DDD5);
8
    while(1){
9
        PORTD ^= (1<<PD5);
10
        _delay_ms(1000);
11
    }
12
}

Gebaut habe ich es mit:
1
$ avr-gcc -Os -mmcu=atmega8 -std=gnu99 main.c -o main.o
2
$ avr-objcopy -O ihex main.o main.hex
Dann die Fuses des ATmega8 auf 1MHz internal Osc.
1
$ avrdude -p m8 -c usbasp -U lfuse:w:0xe1:m -U hfuse:w:0xd9:m
Und abschließend das Programm geflasht:
1
$ avrdude -p m8 -c usbasp -U flash:w:main.hex
Ich benutze das AtmelEvalBoard von Pollin, einen Atmega8-16PU und einen 
USBASP programmer mit der fischl-firmware.

Die LED blinkt auch artig, ABER sie blinkt exakt vier mal so schnell wie 
sie soll. Statt 1000ms delay habe ich ein delay von exakt 250ms (auf die 
ms genau am Oszilloskop nachgemessen).
Auch wenn ich den externen Quarz mit 16MHz benutze (lfuse:0xcf und 
hfuse:0xd9) und das F_CPU define auf 16000000 anpasse, habe ich exakt 
das selbe verhalten (250ms delay, statt 1000ms).

Dieses Phänomen hatte ich noch nie. Ein zweiter Atmega8 verhält sich 
exakt genauso.

Ich habe keine Idee mehr, woran das jetzt liegen könnte, bzw was ich 
falsch mache (habe bestimmt schon 2 Jahre kein AVR mehr programmiert und 
bin ziemlich eingerostet ... wollte jetzt wieder anfangen und jetzt 
sowas).

Ich hoffe ihr könnt mir helfen.

Vielen Dank euch schonmal.
Besten Gruß
t0mM3k
Gast #5084790
Lesenswert?

Hi

>Meine Gedanken gehen in die gleiche Richtung, nur müsste dann nicht das
>Delay eher 1/8tel statt der gemessenen 1/4tel Sekunde dauern?
>Der Faktor 2 stört hier 'noch etwas'.

Ein Takt besteht aus 2 Halbwellen.

MfG Spess
#5084797
Lesenswert?

Hi

spess53 schrieb:
> Ein Takt besteht aus 2 Halbwellen.

Das kann Es aber nicht sein - bei 1MHz besteht der Takt ebenfalls aus 
zwei Halbwellen und dort müsste das delay passen, da als Makro und 
vorgegebenem Systemtakt entsprechend oft 'auf der Stelle getreten' wird.

Klar kann man jetzt das Programm so hinfrickelt, daß die gewünschte 
Wartezeit passt, auch wenn der Code was Anderes vermuten lassen würde - 
aber 'schön' ist Das nicht.

Oder von was hängt "delay" noch ab, außer von der angegebenen 
Taktfrequenz?

MfG

Jay W. schrieb:
> DDRD |= (1<<DDD5);
>               ^--Da ist ein Fehler. Übertragungsfehler oder echter

Müsste Das nicht einen Fehler erzeugen? DDD5 ist wohl zumindest nicht 
'von Haus aus' definiert so Mal annehm
Gast #5084803
Lesenswert?

Hi

>Das kann Es aber nicht sein - bei 1MHz besteht der Takt ebenfalls aus
>zwei Halbwellen und dort müsste das delay passen, da als Makro und
>vorgegebenem Systemtakt entsprechend oft 'auf der Stelle getreten' wird

Bei richtigem Takt würde dein Programm eine Frequenz von 0,5 Hz und 
nicht 1Hz erzeugen.

MfG Spess
#5084822
Lesenswert?

Hi

Der TE schrieb aber, daß das delay auf dem Oszi gemessen nur 1/4 der 
erwarteten Zeit beträgt - ich gehe davon aus, daß 'die Wartezeit bis 
Pegelwechsel' gemeint ist - halt ein delay und nicht die Periodendauer - 
und Da macht 1/4tel keinen Sinn.
Bei 1/8tel bin ich genau bei Dir (bei 8-fachem auch, dann aber 'in die 
andere Richtung'), nur 1/4tel kann nicht, oder der µC läuft mit 4MHz 
oder der delay-Timer läuft schneller, als erwartet - worauf ich mit 
meinem

Patrick J. schrieb:
> Oder von was hängt "delay" noch ab, außer von der angegebenen
> Taktfrequenz?

hin wollte.

MfG
OP #5084974
Lesenswert?

Hallo zusammen,
erstmal Danke für die zahlreichen Antworten.

spess53 schrieb:
> Wie sind deine Fuse-Einstellungen? Ich würde auf 8MHz Tippen.

Das hatte ich in meiner Frage bereits geschrieben. Für 1MHz intern habe 
ich die Fuses auf lfuse:0xe1 und hfuse:0xd9 gestellt. Um den 16MHz Quarz 
zu nutzen dann lfuse:0xcf und hfuse:0xd9

Jay W. schrieb:
> DDRD |= (1<<DDD5);
>               ^--Da ist ein Fehler. Übertragungsfehler oder echter

Was ist daran falsch? DDD5 ist ist in avr/iom8.h definiert (hier ein 
Auszug:)
1
/* DDRD */
2
#define DDD7  7
3
#define DDD6  6
4
#define DDD5  5
5
#define DDD4  4
6
#define DDD3  3
7
#define DDD2  2
8
#define DDD1  1
9
#define DDD0  0

spess53 schrieb:
> Bei richtigem Takt würde dein Programm eine Frequenz von 0,5 Hz und
> nicht 1Hz erzeugen.

Damit hier keine Verwirrung entsteht, habe ich extra die exakten delays 
angegeben und nicht die frequenzen. Ich wollte eine Frequenz von 0,5Hz 
und erhalte aber 2Hz.

Jay W. schrieb:
> Könnte es sein, dass der TO eine alte avr-libc verwendet? Ich habe da
> etwas gelesen:
> "Die _delay_ms() und die _delay_us aus avr-libc 1.7.0 sind fehlerhaft.
> _delay_ms () läuft 4x schneller als erwartet."

Das klingt genau nach meinem Fehler. Komisch ist nur, dass ich meine 
avr-libc über den Paketmanager installiert habe und regelmäßige Updates 
meines Systems mache.
1
 $ aptitude show avr-libc
liefert mir jedenfalls die info, dass ich Version: 1:1.8.0+Atmel3.4.4-1 
installiert habe.

Aber ich werde hier mal nachforschen, da ich noch eine alte 
Arduino-Bibliothek auf dem System liegen habe. Könnte sein, dass mein 
Pfad so gesetzt ist, dass hier die falsche Bibliothek genutzt wird und 
nicht die aus dem Systemverzeichnis.

Danke erstmal für die vielen hilfreichen Hinweise. Ich werde heute Abend 
wieder berichten.
Besten Gruß

t0mM3k

*EDIT
Danke Jay W. genau das war der Fehler. Da ich zuletzt mit einem AVR32 
experimentiert habe, hatte ich das AVR32-Studio installiert. Dieses kam 
mit einer AVR Bibliothek von 2010. Da das AVR32-Studio in PATH vor 
meinen Systemordnern kam, hat er hier diese Version verwendet. 1000 Dank 
für diese Info.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren