Forum: Mikrocontroller und Digitale Elektronik ATMega162 - Messung interne Taktfrequenz


von Mike (Gast)


Lesenswert?

Hallo zusammen,

ich multiplexe ein 4x7 LED Display am ATMega162 mit folgenden Werten:

// Timer initialisieren -> LED-Anzeige: 8 MHz  256  30 = 1040 Hz
TCCR0 = (1<<WGM01) | (1<<WGM00);  // Fast PWM
TCCR0 |= (1<<CS02);    // Vorteiler = 256
OCR0 = 30;      // Compare-Wert = 30

In den Fuses habe ich "Divide Clock by 8 internally" deaktiviert.

Die 8 MHz habe ich dem Datenblatt entnommen.

Ich würde eine Frequenz von ca. 1 kHz erwarten - trotzdem flackert das 
Display sichtlich. Bei Vorteiler 64 sieht es flüssig aus.

Problem lässt sich also "umgehen", aber irgendwie spricht das Phänomen 
gegen 8 MHz (oder ist ein Fehler im Programm?)

Kann ich (über ein Testprogramm o. ä.) irgendwie messen, wie der interne 
Takt tatsächlich/genau ist?

VG Mike

von Karl H. (kbuchegg)


Lesenswert?

> Kann ich (über ein Testprogramm o. ä.) irgendwie messen,
> wie der interne Takt tatsächlich/genau ist?

Da du sowieso nur 'Kategorien' hast, brauchst du auch nur 'Kategorie' 
feststellen. Also 1Mhz oder 8Mhz
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
#define LED_DDR  DDRD
7
#define LED_PORT PORTD
8
#define LED_PIN  PD0
9
10
int main()
11
{
12
  LED_DDR |= (1<<LED_PORT);
13
14
  while( 1 ) {
15
    LED_PORT |= (1<<LED_PORT);
16
    _delay_ms( 1000 );
17
    LED_PORT |= ~(1<<LED_PORT);
18
    _delay_ms( 1000 );
19
  }
20
}

wenn dein µC tatsächlich auf 8Mhz läuft, dann ist eine Led am Testport 
(die #define entsprechend einstellen) 1 Sekunde am leuchten und 1 
Sekunde aus. Das kannst du mit freiem Auge erkennen. Denn wenn dein µC 
in Wirklichkeit mit 1Mhz läuft, dann ist die LED 8 Sekunden ein und 8 
Sekunden aus. Und den Unterschied kann ein Blinder greifen.

Nur dann, wenn der Wert bei F_CPU mit der tatsächlich am µC 
eingestellten Taktfrequenz übereinstimmt, dann ist die LED 1s ein und 1s 
aus. Aufs Herz genau kannst du damit natürlich nichts feststellen, aber 
um 1, 2, 4 oder 8 Mhz voneinander unterscheiden zu können, reicht es 
locker.

von Mike (Gast)


Lesenswert?

super, danke für den Tip! - probier ich morgen früh aus.

von Thomas E. (thomase)


Lesenswert?

Karl Heinz Buchegger schrieb:
1
//Na ja
2
/*
3
#define LED_DDR  DDRD
4
#define LED_PORT PORTD
5
#define LED_PIN  PD0
6
7
int main()
8
{
9
  LED_DDR |= (1<<LED_PORT);
10
11
  while( 1 ) {
12
    LED_PORT |= (1<<LED_PORT);
13
    _delay_ms( 1000 );
14
    LED_PORT |= ~(1<<LED_PORT);
15
    _delay_ms( 1000 );
16
  }
17
}
18
*/
19
//Besser so:
20
21
#define LED_DDR  DDRD
22
#define LED_PORT PORTD
23
#define LED_PIN  PD0
24
25
int main()
26
{
27
  LED_DDR |= (1<<LED_PIN);
28
29
  while( 1 ) {
30
    LED_PORT |= (1<<LED_PIN);
31
    _delay_ms( 1000 );
32
    LED_PORT |= ~(1<<LED_PIN);
33
    _delay_ms( 1000 );
34
  }
35
}

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Thomas Eckmann schrieb:
> Karl Heinz Buchegger schrieb:
>
> //Na ja

:-)
Ist halt das Problem wenn man Code mal auf die Schnelle runtertippt.
Man macht Fehler.

Den
>     LED_PORT |= ~(1<<LED_PIN);
haben wir beide übersehen

     LED_PORT &= ~(1<<LED_PIN);

Danke für die Korrektur.

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

Karl Heinz Buchegger schrieb:
> Den
>
>>     LED_PORT |= ~(1<<LED_PIN);
>
> haben wir beide übersehen

Den hatte ich sogar selbst gefunden, unglaublich ;-)

Also ich habe das gerade getestet: Die LED blinkt jede Sekunde, d. h. 
der Takt müsste 8 MHz sein. Aber wie kann es da sein, dass das 4x7 LED 
Display flackert? Stimmt die Rechnung oben 8 MHz  256  30 = 1.025 Hz?

Der Code sollte ansonsten auch ok sein (siehe Anlage). Hatte ich mit 
einem ATtiny2313 bereits getestet - der hatte m. W. 4 MHz, und es hat 
nicht geflackert...

Warum ich es so genau nehme: ich baue einen IR-Sender und da sollte die 
Sendefrequenz natürlich halbwegs passen.

von Mike (Gast)


Lesenswert?

PS: im oben angehängten Code hatte ich den Vorteiler schon auf 64 
geändert - dann ist das Flackern weg. Das Problem tritt auf bei:

TCCR0 |= (1<<CS02), was ein Vorteiler von 256 sein müsste.

von Karl H. (kbuchegg)


Lesenswert?

Siehe Tabelle 47 auf Seite 100 vom Mega162 Datasheet
http://www.atmel.com/Images/doc2513.pdf

Beim Fast-PWM Modus ist der TOP Wert fix 0xFF.
d.h. deine Rechnnung muss lauten

   8000000/256/256 = 122

das durch 4, weil du 4 Anzeigen hast und du landest bei knapp 30.
Dass das flackert, wundert mich nicht.

Was du hast, das ist ein Interrupt jedesmal wenn der Timer auf der 30
steht, aber der Timer zählt nach wie vor von 0 bis 255, d.h. der
zeitliche Abstand zwischen den ISR-Aufrufen ist nach wie vor 256
Timerticks.

Du musst schon ein wenig ins Datenblatt sehen, was die einzelnen Modi
genau machen. Das ist bei jedem µC und bei jedem Timer ein wenig anders.
Da darf man sich auf nichts verlassen sondern muss jedesmal mit dem
Datenblatt kontrollieren, wenn man ein Programm von einem µC auf einen
anderen überträgt.

von Mike (Gast)


Lesenswert?

Hallo Karl-Heinz,

vielen Dank für die Unterstützung! Da muss ich noch genauer im 
Datenblatt hinschauen, hast Recht - ich hatte sogar genau diese Seite 
gestern angeschaut, aber den TOP-Wert übersehen, sorry. Wollte gestern 
Abend (zu) schnell Ergebnisse ;-)

Der CTC-Mode müsste aber das machen, was ich mir vorstelle, oder?
--> bis 30 zählen, dann Interrupt, Counter geht automatisch auf Null, 
und dann wieder von vorne

Also wenn ich's teste, sieht es gut (= flackert nicht) - aber ob das 
dann die errechneten 8000000/256/30 = 1041, seh ich natürlich mit bloßem 
Auge nicht

VG Mike

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.