Hallo, ich hab hier nen Arduino von Watterott mit nem 328 und programmier ihn in C. Auf dem Schaltplan den ich hab ist jedoch ein Mega8 eingezeichnet. Grummel. Gibt's irgendwo nen besseren Plan? Auf dem Plan läuft ein Mega8 mit 16Mhz. Das Quarz auf meinem Board scheint etwa Baugröße 0804 zu sein, jedenfalls ist es so klein, daß ich nichts darauf lesen kann. Hab versucht, mit meinem Rigol mir den Quarztakt anzuschauen; nichts feststellbar, null Pegel. Ist die Eingangskapazität an meinem Präzisionsgerät zu groß...? Punkt 1) Haben alle Arduinos, also auch der aktuelle Watterott-Arduino, einem 16 MHz Quarz? Es würde zumindest Sinn machen... Punkt 2) Wenn ich eine LED per T1-Interrupt umschalten lasse, stelle ich fest daß die Taktfrequenz nicht stimmen kann. // Arduino Hardware läuft vermutlich mit 16MHz #define F_CPU 16000000UL //hab's mit _delay_ms(1000) getestet, damit stimmt's wohl. Verläßlich? // TCNT1H and TCNT1L – Timer/Counter1 TCNT1 = 0x8000; // TCCR1B – Timer/Counter1 Control Register B // CS12 CS11 CS10 untere 3 bits // 1 0 0 Takt/256 TCCR1B = 0b00000100; Kurze Rechnung: xFFFF- x8000= x7FFF x7FFF/256 = ca 128 128 => 1/128sek Umschaltzeit Die in der ISR umgeschaltete LED geht jedoch ca 2x/sek an und aus, dh. irgendwas ist viiiel zu langsam. Nach einigem hin und her habe ich todesmutig versucht die Fuses für den Osc zu ändern. Ich werde aus meiner Anzeige aber nicht schlau draus. Hab hier AVR Studio5, das ist eingestellt: BODLEVEL = 2V7 RSTDISBL = [ ] DWEN = [ ] SPIEN = [X] WDTON = [ ] EESAVE = [X] BOOTSZ = 256W_3F00 BOOTRST = [X] CKDIV8 = [ ] CKOUT = [ ] SUT_CKSEL = EXTFSXTAL_16KCK_14CK_65MS EXTENDED = 0xFD (valid) HIGH = 0xD6 (valid) LOW = 0xF7 (valid) Und nu?
Joachim schrieb: > hab's mit _delay_ms(1000) getestet, damit stimmt's wohl. Verläßlich? Welche Compileroptimierung? > Hab hier AVR Studio5, das ist eingestellt: Ist das auch programmiert?
Welche Compileroptimierung? Unter 'Optimisation' finde ich nur: Optimize for size -Os Angehakt ist noch: Pack Structure members together (-fpack-struct) Allocate only as many bytes as needed by enum types (-fshort-enums) Wundert mich, daß so wenig Optionen eingetragen sind. Ich hab unter AVR Studio 5 unter Properties -> Toolchain -> AVR/GNU C Compiler -> Optimisation geschaut. Vielleicht gibt's ja noch anderswo Eintragungen. >Ist das auch programmiert? Hmm. Eigentlich schon. Das hier bekomm ich ja angezeigt: BODLEVEL = 2V7 RSTDISBL = [ ] DWEN = [ ] SPIEN = [X] WDTON = [ ] EESAVE = [X] BOOTSZ = 256W_3F00 BOOTRST = [X] CKDIV8 = [ ] CKOUT = [ ] SUT_CKSEL = EXTFSXTAL_16KCK_14CK_65MS EXTENDED = 0xFD (valid) HIGH = 0xD6 (valid) LOW = 0xF7 (valid) Ich werd wohl noch rausknobeln müssen was die Fuses so sagen.
Offensichtlich scheint das mit den Fuses zu stimmen. Wenn ich die Gegenprobe mache und auf internen Osc umschalte (von 16MHz extern auf 8MHz intern) blinkt meine LED nur noch mit halber Geschwindigkeit. Soweit also ok. Trotzdem ist meiner Ansicht nach die Geschwindigkeit mindestens 1000x zu niedrig. Der relevante Teil in main: // Timer Interrupt probieren // T1, 16-bit Timer PRR = 0 ; //sicherstellen, daß er eingeschaltet ist // TCCR1A – Timer/Counter1 Control Register A TCCR1A = 0b00000000; // untere 4 bits alle 0 // TCCR1B – Timer/Counter1 Control Register B // CS12 CS11 CS10 untere 3 bits // 0 0 0 off // 0 0 1 direkter Takt // 1 0 0 Takt/256 // 1 0 1 Takt/1024 // auch andere möglich TCCR1B = 0b00000100; // 16MHz/256 = 62,5KHz // TCCR1C – Timer/Counter1 Control Register C TCCR1C = 0b00000000; // TCNT1H and TCNT1L – Timer/Counter1 TCNT1 = 0x8000; //TIFR1 – Timer/Counter1 Interrupt Flag Register //Bit 0 – TOV1: Timer/Counter1, Overflow Flag //TIMSK1 – Timer/Counter1 Interrupt Mask Register TIMSK1 = 0b00000001; //erlauben // Interrupts aktivieren sei(); // Langeweile-Schleife in main: while (1) { PORTD ^= (1<<PD5); // LED grün _delay_ms(1000); } Die ISR-Routine: ISR(TIMER1_OVF_vect) { cli(); PORTB ^= (1<<PB0); // blinkt ca 2x pro Sekunde, sollte aber vieeel mehr sein static uint8_t i = 0; TCNT1 = 0x8000; /* i++; if (i == 100) { PORTB ^= (1<<PB0); i=0; }; */ sei(); } Ist irgendwo noch ein Vorteiler versteckt?
Hi
>// blinkt ca 2x pro Sekunde, sollte aber vieeel mehr sein
Nein. Passt.
16MHz/256 = 62,5 kHz
62,5kHz/$8000 = 0,524 Hz
MfG Spess
Ich werde den Rest des Tages mit Schämen verbringen. Danke an euch.
Hi
Ich schrieb:
>62,5kHz/$8000 = 0,524 Hz
Ist natürlich Mist
-> 62,5kHz/$8000 = 1,9Hz
MfG Spess
Tja. Wir sind noch nicht fertig... 1. Ich kann machen was ich will, eine Änderung des Wertes TCNT1 = 0x8000; bewirkt genau gar nichts. Wie ist das möglich? ISR(TIMER1_OVF_vect) { cli(); PORTB ^= (1<<PB0); // blinkt ca 1x alle 2 sek TCNT1 = 0x1000; sei(); } Es scheint als ob der Zähler immer wieder bei x0000 losläuft um bei xFFFF einen Interrupt auszulösen. Es gibt noch die Register TOP und MAX, die werde ich aber bei einem simplen LED-blinken mittels Timer ja wohl nicht brauchen - hoffe ich. Jetzt kommt's aber noch dicker: sei(); hat keinen Einfluß. in einem alten Thread habe ich gelesen, daß der GCC je nach Einstellung den Code "optimiert". Ein Bug? Wie kann ich einstellen daß so etwas nicht passiert ohne 20 Seiten Dok zu lesen? Mein Senf: Also man kann über MPLAB und PICs ja sagen was man will... aber so ein Mist ist mir mit dem Compiler C18 in 5 Jahren in der default-Einstellung nicht einmal passiert...
Hi >1. Ich kann machen was ich will, eine Änderung des Wertes >TCNT1 = 0x8000; >bewirkt genau gar nichts. Wie ist das möglich? Falsches Programm geflasht? >Jetzt kommt's aber noch dicker: sei(); hat keinen Einfluß. cli und sei haben in einer Interruptroutine eh nichts zu suchen. Das passiert automatisch. Das Auslösen eines Interrupts bewirkt ein cli und das reti am Ende ein sei. MfG Spess
>Das Auslösen eines Interrupts bewirkt ein cli und >das reti am Ende ein sei. Das hab ich zuerst auch geglaubt. Der Gegenbeweis lieferte das Abschalten des Int-Freigabebits in TIMSK1. Dann blieb er auch tatsächlich stehen, andernfalls nicht. Irgendwie passt das alles gar nicht zusammen. Siehe auch hier: Beitrag "Schwerer Bug in AVR-GCC 4.1.1"
Joachim schrieb: > Hab versucht, mit meinem Rigol mir den Quarztakt anzuschauen; nichts > feststellbar, null Pegel. Ist die Eingangskapazität an meinem > Präzisionsgerät zu groß...? Mit 1:1 Tastkopf darfst du keinem Quarz zu Leibe rücken, mit 10:1 sollte aber was zu sehen sein. Wobei der Low-Power-Oszillator empfindlicher ist als der Full-Swing-Oszillator. Wäre natürlich besser, am Ausgang des internen Inverters zu messen als am Eingang. Die Eingangskapazität der üblichen passiven kapazitiven 10:1 Tastköpfe ist ziemlich unabhängig davon, ob auf dem DSO nun Rigol oder Agilent draufsteht.
Hi >Das hab ich zuerst auch geglaubt. >... >Siehe auch hier: >Beitrag "Schwerer Bug in AVR-GCC 4.1.1" Berührt mich eigentlich wirklich, da ich Assembler benutze. Und da klappt das wunderbar. MfG Spess
In die falsche Richtung gedacht. Da der Zähler ja aufwärts bis 0x0000 zählt bewirkt ein kleinerer Wert eine größere Zeit. Uff.
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.