_delay_ms (IDE: Code::Blocks unter Linux) läuft zu schnell

#3699335
Lesenswert?

Hallo,

ich bin neuerdings Linux-Nutzer und möchte in Zukunft Code::Blocks zum 
Programmieren von AVRs verwenden. Ich glaube, das aufgeblähte Atmel 
Studio werde ich nicht sehr vermissen.

Zum Flashen benutze ich AVR8-Burn-o-mat in Kombination mit AvrDude.
Ich verwende LIBC in Version 1.8.0.

Hat eine Weile gedauert, bis ich alles installiert hatte, aber jetzt 
läuft es.
Als ersten Test habe ein kleines Blinkprogramm erstellt. Es sollte 
mittels _delay_ms eine LED mit 1Hz blinken.
Leider tut es das nicht. Sobald die eingestellte Zeit ca. 67ms 
überschreitet, bleibt es bei 67ms.
D.h.
_delay_ms(50) macht eine Wartezeit von 50ms,
_delay_ms(60) macht eine Wartezeit von 60ms,
_delay_ms(70) und mehr macht eine Wartezeit von 67ms.

Es wird der interne RC-Oszillator mit Teiler 8 verwendet. Ich habe das 
extra nochmal mittels "Takt nach draußen" (CLKO-Pin) kontrolliert. Der 
Controller läuft mit 1Mhz. Dies ist auch so als FCPU definiert.
Wenn ich absichtlich FCPU auf 2MHz stelle, ist die Wartezeit verdoppelt. 
Es funktioniert also alles wie es soll. Außer eben diese doofe 
Begrenzung bei 67ms.

Hat jemand eine Idee, was ich noch untersuchen könnte?

Ich dachte, solche Anfängerprobleme wie zu schnelle Warteschleifen habe 
seit Jahren ich hinter mir... Denkste. ;-)

Danke
Third-Eye
Gast #3699425
Lesenswert?

Als Tipp, via Timer ISR:
1
/* 1 ms Timer Interrupt */
2
ISR(TIMER0_COMP_vect) 
3
{
4
  
5
    tick2++; 
6
    /* Rest gelöscht , der hier nicht interessiert*/
7
}
8
//
9
//For longer Delays
10
//
11
void Delay1ms(unsigned int time)
12

13
{
14
  if (time == 0 )
15
      return;
16
  tick2=0;
17

18

19
  while (time){
20

21
    if ( time < 10 ){
22
        if ( tick2 > 0 ){
23
          time--;
24
          tick2=0;
25
        }
26
    } else {
27

28
        if ( tick2 > 9 ){
29
          time -= 10;
30
          tick2 = 0;
31
        }
32
     } // else
33
   }// while
34
  
35
}
#3700546
Lesenswert?

Den Satz
"The maximal possible delay is 262.14 ms / F_CPU in MHz."
habe ich gelesen.
Es steht aber weiter auch:
"When the user request delay which exceed the maximum possible one, 
_delay_ms() provides a decreased resolution functionality. In this mode 
_delay_ms() will work with a resolution of 1/10 ms, providing delays up 
to 6.5535 seconds (independent from CPU frequency)."

Und so kenne ich die Funktion bisher auch. Ich mache immer gern ein 
Power-On-Delay mit _delay_ms(1000) am Anfang der Mainschleife.

Meine 67ms wären ca. 1/4 von 262ms. Ergibt aber irgendwie auch keinen 
Sinn.

Danke für den Tipp mit dem Timer. Aber ich verwende die Delays wirklich 
nur für das eben Genannte und derartige primitive Sachen.
Ich wollte nur verstehen, warum es nicht funktioniert, wie gedacht.
Ich komme immer noch nicht drauf...

Ich habe gelesen, dass es einen Bug in der LIBC in Version 1.7 gab, aber 
ich verwende, wie erwähnt, 1.8.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren