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
> 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.
super, danke für den Tip! - probier ich morgen früh aus.
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.
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.