Hi, ich habe eine Frage zu Timer-Prescaler. Bei dem ATTiny25 ist der CLKDIV8 standardmäßig aktiviert. Wenn ich den deaktiviere und F_CPU=8000000UL setze, läuft der Controller mit 8 MHz. Wenn ich ihn aktiviert lassen und F_CPU auf 1000000UL setze, läuft der dann mit 1 MHz oder mit 8 MHz? Das wäre wichtig für die Auswahl meines Prescalers. Sorry wenn die Anfängerfrage ein wenig dumm erscheint.
Hi, F_CPU informiert den Compiler lediglich, daß Du den MC auf die angegebene Frequenz gestellt hast. Gruß Andreas
Timerfrage schrieb: > Das wäre wichtig für die Auswahl meines Prescalers. Wieso...? Ich glaube, da unterliegst du einem Irrtum. Wie CLKDIV8 steht, kann dir doch völlig wurscht egal sein, wenn du den Prescaler selber setzt. F_CPU solltest du dann allerdings auf den korrekten Wert einstellen.
Ok Danke. Ich hab den CLKDIV8 deaktiviert und F_CPU auf 8 MHz gesetzt. Zum Testen hab ich jetzt ein ATTiny841 genommen, um mir per UART die Timerwerte ausgeben zu lassen. Ich bin ein wenig verwirrt weil: Ich speise an den INT0 ein Rechtecksignal mit 10 HZ und reagiere auf die fallende Flanke. ich messe am INT0 von fallender Flanke zur fallenden Flanke. Die Zeit muss 100ms betragen. mit einem Prescaler von 1024, beträgt meine Timerfrequenz noch 7812,5 kHz, demnach müsste der Timer doch alle 128us eins höher zählen. Bei 100ms also 781 Inkremente. Der Timerwert solle dann doch bei 16 sein und der Overflow bei 3. Ich bekomme allerdings einen Timerwert von 213 und einen Overflow von 1. Was genau habe ich nicht verstanden?
Mach das nicht so kompliziert. Lass eine LED an einem beliebigen Port mit einem Delay, ja mit Delay, von einer Sekunde blinken. Dann erkennt jeder mit blossem Auge, ob die LED mit 125ms, 1s oder 8s blinkt. Je nachdem, ob du alles richtig eingestellt hast oder ein Irrtum in der einen anderen Richtung vorliegt.
Timerfrage schrieb: > Wenn ich den deaktiviere und F_CPU=8000000UL setze, läuft der Controller > mit 8 MHz. In etwa. Und es ist unwichtig, was du in F_CPU angibst, der Controller interessiert sich für diesen Scheiss exakt garnicht, er erfährt davon nämlich auch rein garnix. Allerdings ist es für deinen Compiler relativ sinnvoll, dass du den korrekten Takt in F-CPU angibst, denn viele der von dir raubkopierten C-Fragmente verlassen sich darauf, dass diese Angabe der Realität entspricht. Blöd nur, wenn du zur Laufzeit den Takt wechselt, was beim Tiny841 (und nicht nur bei dem) ja ziemlich problemlos möglich und garnicht so selten auch sinnvoll ist. Dann fällt diese ganze C-Gülle einfach mal nur voll auf die Nase, denn dann gibt es keinen programmweit gültigen Wert für F_CPU mehr... > Ich speise an den INT0 ein Rechtecksignal mit 10 HZ und reagiere auf die > fallende Flanke. ich messe am INT0 von fallender Flanke zur fallenden > Flanke. Die Zeit muss 100ms betragen. mit einem Prescaler von 1024, > beträgt meine Timerfrequenz noch 7812,5 kHz, demnach müsste der Timer > doch alle 128us eins höher zählen. Jepp. Genauso ist das. > Bei 100ms also 781 Inkremente. Fast. Genau 781,25. Er wird also mal 781 und mal 782 Incremente zählen. Im Mittel werden diese Fälle im Verhältnis 4:1 auftreten. > Der > Timerwert solle dann doch bei 16 sein und der Overflow bei 3. Wie kommst du denn darauf? Wenn man mal einen 8Bit-Timer annimmt (und die impliziert, dass der bei 0 startet) würde er 3 mal überlaufen (das stimmt) und der Zählerstand sollte 13 oder 14 sein (nicht 16). > Ich > bekomme allerdings einen Timerwert von 213 und einen Overflow von 1. Dann stimmt sicher irgendwas in deiner Software nicht. Der beobachtete Wert weisst allerdings nicht direkt auf einen typischen Fehler hin. Deswegen kann man in Ermangelung von Code nichtmal raten, was du falsch gemacht hast. Da musst du schon deinen Code posten.
Thomas E. schrieb: > Mach das nicht so kompliziert. > > Lass eine LED an einem beliebigen Port mit einem Delay, ja mit Delay, > von einer Sekunde blinken. Dann erkennt jeder mit blossem Auge, ob die > LED mit 125ms, 1s oder 8s blinkt. Je nachdem, ob du alles richtig > eingestellt hast oder ein Irrtum in der einen anderen Richtung vorliegt. Das hilft mir nicht wirklich weiter. Bei 1000ms Delay blinkt die LED im Sekundentakt, soweit alles gut. c-hater schrieb: >> Bei 100ms also 781 Inkremente. > > Fast. Genau 781,25. Er wird also mal 781 und mal 782 Incremente zählen. > Im Mittel werden diese Fälle im Verhältnis 4:1 auftreten. > >> Der >> Timerwert solle dann doch bei 16 sein und der Overflow bei 3. > > Wie kommst du denn darauf? Wenn man mal einen 8Bit-Timer annimmt (und > die impliziert, dass der bei 0 startet) würde er 3 mal überlaufen (das > stimmt) und der Zählerstand sollte 13 oder 14 sein (nicht 16). Stimmt natürlich ;) Hier der Code:
1 | #define F_CPU 8000000UL
|
2 | #include <avr/io.h> |
3 | #include <util/delay.h> |
4 | #include <avr/interrupt.h> |
5 | |
6 | #define BAUD 9600UL
|
7 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
|
8 | |
9 | volatile uint8_t iOverflow = 0; |
10 | volatile uint8_t active = 0; |
11 | |
12 | void UART_init(void) |
13 | {
|
14 | UBRR0 = UBRR_VAL; |
15 | |
16 | UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); |
17 | UCSR0B |= (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); |
18 | REMAP |= (1 << U0MAP); |
19 | }
|
20 | |
21 | void Start_Timer() |
22 | {
|
23 | //TCCR0B = (1<<CS02); // Prescaler 256
|
24 | TCCR0B |= (1<< CS00) | (1<<CS02); // Prescaler 1024 |
25 | TIMSK0 |= (1<<TOIE0); |
26 | }
|
27 | |
28 | ISR(INT0_vect) |
29 | {
|
30 | if (active == 0) |
31 | {
|
32 | Start_Timer(); |
33 | active = 1; |
34 | }
|
35 | |
36 | UDR0 = TCNT0; |
37 | UDR0 = iOverflow; |
38 | iOverflow = 0; |
39 | TCNT0 = 0; |
40 | }
|
41 | |
42 | ISR (TIMER0_OVF_vect) |
43 | {
|
44 | iOverflow++; |
45 | }
|
46 | |
47 | int main(void) |
48 | {
|
49 | DDRA = 0b00100000; |
50 | PORTA = 0b00000000; |
51 | |
52 | UART_init(); |
53 | sei(); |
54 | |
55 | MCUCR |= (1<<ISC01); |
56 | GIMSK |= (1<<INT0); |
57 | |
58 | while(1) |
59 | {
|
60 | //PORTA |= (1<<PINA5);
|
61 | //_delay_ms(1000);
|
62 | //PORTA &= ~(1<<PINA5);
|
63 | //_delay_ms(1000);
|
64 | }
|
65 | }
|
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.