Forum: Mikrocontroller und Digitale Elektronik warum wird _delay_ms() nicht ausgeführt


von Johannes (Gast)


Lesenswert?

Guten Abend,
Ich bin dabei mir eine Software PWM zu bauen.
Beim herumprobieren bin ich auf einen (mir unerklärlichen) Fehler 
gestoßen.

Und zwar wird _delay_ms(1000); in der main Funtkion nicht ausgeführt. 
Bzw bleibt der µC hier hängen!?

Hier der Code:
1
#define F_CPU 16000000UL
2
#define PWMPORT PORTB
3
#define PWMDDR  DDRB
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <avr/interrupt.h>
8
9
unsigned volatile int pwmMaxWert = 100;
10
unsigned int aktuellerStand = 0;
11
unsigned volatile int sollWert[] = {0, 0, 0, 0};
12
13
void init()
14
{
15
  PWMDDR = 0xFF;    
16
}
17
18
void timerInit()
19
{
20
  TCCR0 |= (1<<CS00); /*Prescaler 0*/
21
  TIMSK |= (1<<TOIE0); /*Gibt das Timer0 Overflow Interrupt frei (inkl. Routine)*/
22
  sei();  /*enabled allgemeine Interrupts*/
23
}
24
25
ISR(TIMER0_OVF_vect)
26
{
27
  for (int i = 0; i < 4; i++)
28
  {
29
    if (aktuellerStand < sollWert[i])
30
      PWMPORT |= (1<<i);
31
    if (aktuellerStand > sollWert[i])
32
      PWMPORT &= ~(1<<i);
33
    if (aktuellerStand > pwmMaxWert)
34
      aktuellerStand = 0;
35
  }  
36
  aktuellerStand++;
37
}
38
39
int main(void)
40
{
41
  init();
42
  timerInit();
43
  
44
  while(1)
45
  {  
46
    _delay_ms(1000);
47
    sollWert[0] = 100;
48
    sollWert[1] = 0;
49
    sollWert[2] = 100;
50
    sollWert[3] = 0;    
51
  }
52
}

Die Hardware passt, wenn ich ein einfaches Programm schreib welches mir 
nacheinander die Ports setzt, dann funktioniert alles.
von Daniel H. (Gast)


Lesenswert?

gib statt 1000ms mal 255ms ein...
von Floh (Gast)


Lesenswert?

delay_ms hat eine Maximalwartezeit.
Schau mal in die Headerdatei delay.h rein.
von Peter II (Gast)


Lesenswert?

Floh schrieb:
> delay_ms hat eine Maximalwartezeit.
nein hat es schon lange nicht mehr.

http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

The maximal possible delay is 768 us / F_CPU in MHz.

If the user requests a delay greater than the maximal possible one, 
_delay_us() will automatically call _delay_ms() instead. The user will 
not be informed about this case.
von Thomas (Gast)


Lesenswert?

... und da steht dann soetwas wie:
"The maximal possible delay is 262.14 ms / F_CPU in MHz."
von Thomas (Gast)


Lesenswert?

.... und weiter:
"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)."
von (prx) A. K. (prx)


Lesenswert?

Wie verhält sich das Programm denn?
von Johannes (Gast)


Lesenswert?

ja bei 1000ms ändert sich nur die genauigkeit.
aber selbst wenn ich das programm im simulator anschaue, führt er die 
Funktion nicht aus.
von Johannes (Gast)


Lesenswert?

Ja real passiert dass, dass er die anfangswerte zuweisst, und dann bei 
dem _delay_ms hängen bleibt und danach nichts mehr ausführt in der main 
methode.
von (prx) A. K. (prx)


Lesenswert?

Wie oft wird der Interrupt denn ausgeführt? Wenn der Prozessor zu nichts 
Anderem mehr kommt, als ISRs auszuführen, dann können aus den 1000ms 
nämlich leicht Minuten werden.
von Johannes (Gast)


Lesenswert?

Danke für den Tipp, das könnte gut sein!
und wie könnte ich dem entgegen kommen? in dem ich den prescaler erhöhe?
von (prx) A. K. (prx)


Lesenswert?

Ja.
von Jürgen (Gast)


Lesenswert?

Indem du den Delay Mist nicht verwendest.
von (prx) A. K. (prx)


Lesenswert?

PS: Ausserdem könnte Unrolling die ISR ungemein beschleunigen. Entweder 
macht das der Compiler mit -O2 oder -O3 von selbst - oder du zu Fuss.

Soll heissen: Die 4 Fälle in der ISR nicht als Schleife programmieren, 
sondern einzeln. Dynamische Shifts sind AVRs sehr unangenehm, auch 
Array-Indizes sind nicht so billig wie sie aussehen.
von Johannes (Gast)


Lesenswert?

Alles klar, danke für die Antworten, werd mich mofgen gleich mal um die 
Optimierung
 kümmern. Ich nehm stark an dass der uC die gNze Zeit nur mit der ISR 
beschäftigt ist.
Danke für die Antworten.
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
Noch kein Account? Hier anmelden.