ATMega162 - Messung interne Taktfrequenz

Gast #3092283
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
#3092288
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.
#3092319
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.
Gast #3092493
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.
Angehängte Dateien:
#3092545
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.
Gast #3092770
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

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