Hallo zusammen! Ich habe erst angefangen Mikrocontroller zu bedienen und habe meine ersten Erfahrungen gemacht. Ich programmiere in C mit dem AVR Studio. Nun mein Problem: Ich will einen Timer programmieren mit dem mega 8. Mit dem steuere ich eine LED an die im Sekundentakt ein- und ausschalten soll. Die Frequenz habe ich bei den Configuration Options auf 8000000 Hz gestellt. Doch statt nach einer Sekunde zu blinken benötigt er etwa 8 Sekunden. Was habe ich falsch? Hier der Code: #include <avr/interrupt.h> #include <stdlib.h> #include <avr/io.h> volatile static uint32_t count = 0; ISR(TIMER1_OVF_vect) { count++; } int main (void) { TCCR1B |= (1<<CS10); TIMSK |= (1<<TOIE1); sei(); DDRC |= (1<<2); PORTC |= (1<<2); while(1) { if (count < 122) PORTC &= ~(1<<2); if (count >= 122) PORTC |= (1<<2); if (count > 244) count = 0; }return 1; } Diese 122 errechnen sich aus 8000000 Hz Taktfrequenz / 65536(da 16-Bit Timer) = ca. 122. Was habe ich mir falsch überlegt? Grüsse Alex
Vielleicht hast du die Fuses des Controllers beim Programmieren falsch gesetzt und er läuft entgegen deine Annahme mit dem internen RC Oszillator, der hat etwa 1 MHz. Das würde den Faktor 8 erklären können. Grüße, Peter
Wie gesagt, Fuses kontrollieren. Für sowas ist eigentlich der CTC-Mode besser geeignet:
1 | #define F_CPU 8000000
|
2 | #define IRQS_PER_SECOND 100
|
3 | #define PRESCALE 8
|
4 | |
5 | void timer1_init(void) |
6 | {
|
7 | // Mode #4 für Timer1 (Manual S. 97)
|
8 | // und Prescale=8
|
9 | TCCR1A = 0; |
10 | TCCR1B = (1 << WGM12) | (1 << CS11); |
11 | |
12 | // PoutputCompare für gewünschte Timer1 Frequenz
|
13 | OCR1A = (unsigned short) ((unsigned long) F_CPU / IRQS_PER_SECOND / PRESCALE -1); |
14 | |
15 | // OutputCompare-Interrupt A für Timer 1
|
16 | TIMSK |= (1 << OCIE1A); |
17 | }
|
Dann reicht auch eine 8-Bit Variable zum Zählen die immer von 1 bis 100 (oder 0 bis 99) läuft. Mit einer 32-Bit Variablen musst du sicherstellen, daß der Zugriffe darauf atomar sind, d.h. nicht von einem Interrupt unterbrochen werden können. Mit einem PRESCALE von 256 bekommt man auch 1 IRQ/Sekunde hin, aber für viele Anwendungen sind 100 IRQs/s genehm (Taster entprellen, etc)
> Die Frequenz habe ich bei den Configuration Options auf > 8000000 Hz gestellt. Andere haben ja schon auf dein Problem hingewiesen. Möchte das nur etwas vertiefen. Es gibt nur eine Möglichkeit beim Mega8 die Taktfrequenz zu verändern und das ist über die Fuses. Die werden aber vom Programmer nicht eigenmächtig angerührt, sondern die Umstellung musst du explizit machen. Aber sei vorsichtig, es passiert ganz schnell, dass man sich da aus dem Controller aussperrt. Lieber alles 3-mal kontrollieren, ehe man die Fuses neu stellt. http://www.mikrocontroller.net/articles/AVR_Fuses Die Angabe in den Configuration Options hat informellen Charakter. Du informierst die Entwicklungsumgebung, und damit auch dein Program, darüber, wie schnell dein µC getaktet ist.
Das verwirrt mich jetzt aber ein bisschen. Ich verwende schon den internen Takt, aber ich habe gemeint, dass er bei 16Mh liegt?! Oder ist das der höchstwert mitdem man ihn takten darf oder wie soll ich das verstehen? Danke für die vielen und schnellen Antworten! Denke das wird es sein. Werde es jetzt testen. Grüsse Alex
Alex wrote: > Das verwirrt mich jetzt aber ein bisschen. Ich verwende schon den > internen Takt, aber ich habe gemeint, dass er bei 16Mh liegt?! Wo hast du denn diesen Wert her? Auslieferungszustand ist: 1Mhz, interner Takt so wie es im Datenblatt des Prozessors beschrieben ist. Und dein Testprogramm bestätigt das ja auch eindrucksvoll. > Oder ist > das der höchstwert mitdem man ihn takten darf oder wie soll ich das > verstehen? Atmel sichert zu, dass bei 16Mhz der Prozessor noch einwandfrei funktioniert. Man kann auch höher gehen, nur kann es dann sein, dass einige Teile des Chips nicht mehr mitspielen. Zb. das EEPROM.
Aha, danke. Das habe ich z.B. von hier: http://www.roboternetz.de/wissen/index.php/Atmel_Controller_Mega8 Da habe ich einfach angenommen, dass das der interne Takt ist... Grüsse Alex
Alex wrote: > > Da habe ich einfach angenommen, dass das der interne Takt ist... Hol dir von Atmel das Datenblatt deines Prozessors. Das wirst du sowieso brauchen. Und im Zweifel gilt immer das Datenblatt und nicht das was auf einigen Webseiten steht.
> Das habe ich z.B. von hier: > http://www.roboternetz.de/wissen/index.php/Atmel_Controller_Mega8 > > Da habe ich einfach angenommen, dass das der interne Takt ist... Was da steht ist der maximale Taktrate, für den der ATmega8 spezifiziert ist. Akkerdingst steht nicht dabei, was die Angabe aussagt. Ist also nutzlos, wenn man nicht eh schon weiß, was das steht... Werksseitig kommt der ATmega8 mit 1MHz inernem RC-Oszillator.
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.