Hallo, ich möchte mit dem ARduino Uno zu beginn eine LED Toggeln lassen. Hier gibt es aber schon das Problem, welches ich nicht verstehe. ich habe zunächst #define F_CPU 16000000UL (ist der Quarz auf dem Arduino) in der while-schleife lasse ich mit _delay_ms(1000); ungefähr eine Sekunde warten und danach die LED an PB5 Togglen. Das Problem ist, dass die LED nur alle 2 Sekunden ihren Status wechselt. Aber das _delay_ms benötigt doch nur F_CPU oder? Mark
_delay_ms berücksichtig nicht eventuell parallel laufende Interrupts. Es dauert also immer mindestens die angegebene Zeit. Allerdings wären 50% Interruptlast schon heftig.
Evtl. läuft der MC mit den internen 8Mhz. Wenn du die Möglichkeit hast, lies doch mal die Fuses aus. Du kannst auch mal F_CPU auf 8000000UL ändern und schauen, obs dann passt - das wäre der Beweis.
Matthias S. schrieb: > Evtl. läuft der MC mit den internen 8Mhz. Wenn du die Möglichkeit > hast, > lies doch mal die Fuses aus. Du kannst auch mal F_CPU auf 8000000UL > ändern und schauen, obs dann passt - das wäre der Beweis. genau so war es auch. alle Fuses waren auf 0x00 (wurde mir zumindes im Atmel Studio so angezeigt). allerdings passt das auch nicht wirklich. wenn ich jetzt einen Timer initialisiere
1 | ... |
2 | // Timer 0 |
3 | TCCR0A = (1 << WGM01); // CTC Modus |
4 | TCCR0B = (1 << CS01) | (1 << CS00); // clk/64 -> = 125kHz |
5 | OCR0A = 125-1; // -> 1ms Interrupt |
6 | |
7 | // Overflow Interrupt allow |
8 | TIMSK0 |= (1 << OCIE0A); |
9 | ... |
10 | |
11 | |
12 | |
13 | |
14 | ISR (TIMER0_COMPA_vect){
|
15 | unsigned int millisekunde = 0; |
16 | unsigned int sekunde = 0; |
17 | |
18 | millisekunde++; |
19 | if(millisekunde == 1000){
|
20 | millisekunde = 0; |
21 | sekunde++; |
22 | TOGGLEBIT(PORTB, 5); |
23 | if(sekunde == 60){
|
24 | sekunde = 0; |
25 | } |
26 | } |
27 | } |
und die LED in der Interrupt Routiene Toggle (dort warte ich 1000 Aufrufe ab, damit ich eine Sekunde habe), dann ist die ungefähr doppelt so schnell. Wenn ich aber OCR0A auf 250 hochsetze, passiert auch nichts anderes.
unsigned int millisekunde = 0; unsigned int sekunde = 0; Da fehlt eigentlich static? Dürfte so überhaupt nicht funktionieren, da bei jedem Funktionseintritt auf 0 gesetzt wird.
H.Joachim S. schrieb: > Da fehlt eigentlich static Das hatte/habe ich aber im code drinn. Muss wohl beim übertragen verloren gegangen sein. also ich hatte stehen
1 | static unsigned int millisekunde = 0; |
2 | static unsigned int sekunde = 0; |
Mark schrieb: > // Overflow Interrupt allow > TIMSK0 |= (1 << OCIE0A); Du willst einen Compare Match Interrupt, enablest aber den Overflow Interrupt .....
Frickelfritze schrieb: >> // Overflow Interrupt allow >> TIMSK0 |= (1 << OCIE0A); > > Du willst einen Compare Match Interrupt, Das ist nur ein schreibfehler im Kommentar. Im Datenblatt steht: OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
Tipp: Keine Kommentare im Quelltext, ist ja schon schlimm. Aber falsche, sind die Hölle. (dann besser keine)
Mark schrieb: > genau so war es auch. alle Fuses waren auf 0x00 (wurde mir zumindes im > Atmel Studio so angezeigt). Dann funktioniert auch der Bootloader nicht, wie programmierst du deinen Arduino ? Mark schrieb: > Wenn ich aber OCR0A auf 250 hochsetze, passiert auch nichts anderes. Das kann schon mal nicht sein. Nimm deine Variablen aus der ISR heraus, deklariere die als volatile und probiere es nochmal.
Marc V. schrieb: > Nimm deine Variablen aus der ISR heraus, deklariere die als volatile Wenn die Variablen nur in der ISR verwendet werden ist das beides unnötig.
Mark schrieb: > TCCR0B = (1 << CS01) | (1 << CS00); // clk/64 -> = 125kHz 16Mhz / 64 = 250KHz !! 8Mhz / 64 = 125KHz Tatsächlich kommt in meinem Testablauf der Interrupt mit 2 KHz daher. Mein Arduino 328 läuft mit 16 MHz.
Frickelfritze schrieb: > Wenn die Variablen nur in der ISR verwendet werden ist > das beides unnötig. Wenn die Variablen als volatile deklariert werden, sind die Global. Auch wenn die Variablen in der ISR als static deklariert werden, sind die nur in der ISR sichtbar. Beim debugging kann volatile ganz nützlich sein, oder ?
Marc V. schrieb: > Beim debugging kann volatile ganz nützlich sein, oder ? Aber das behebt in keiner Weise sein Problem so wie du es suggerierst: Marc V. schrieb: > und probiere es nochmal.
Frickelfritze schrieb: > Aber das behebt in keiner Weise sein Problem so wie > du es suggerierst: Sein Problem besteht darin, dass er Codeschnipsel zeigt, danach behauptet, dass das was drin ist in seinem Code ganz anders aussieht, dass seine Kommentare falsch sind, dass seine Aussagen, wie z.B: Mark schrieb: > genau so war es auch. alle Fuses waren auf 0x00 (wurde mir zumindes im > Atmel Studio so angezeigt). Sicher, mit 0x00 funktioniert deine MEGA problemlos, vor allem geht programmieren über ISP klaglos... > Das hatte/habe ich aber im code drinn. Muss wohl beim übertragen > verloren gegangen sein. Ja, irgendwie rausgefallen und gleich beide... EDIT: Mit OCR0A auf 249 und 16MHz funktioniert das Ganze bei mir ohne Probleme.
Mark schrieb: > zu beginn eine LED Toggeln passt doch : 1. Durchlauf toggeln -> LED von aus nach ein 1s warten 2. Durchlauf toggeln -> LED von ein nach aus 1s warten 3. Durchlauf toggeln -> LED von aus nach ein 1s warten ... dauert halt 2s .... MfG von der Spree
Frank S. schrieb: > ... > dauert halt 2s .... > > MfG von der Spree Nö, passt nicht, denn der TE schreibt ja ausdrücklich: Mark schrieb: > Das Problem ist, dass > die LED nur alle 2 Sekunden ihren Status wechselt. Lies also nochmal das erste Posting.
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.