Forum: Mikrocontroller und Digitale Elektronik For schleife verhält sich seltsam


von Martin (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein Problem mit einer For Schleife, die sich anders verhält, 
als wenn ich sie "ausrolle". Zunächst einmal mein Code:
1
struct portBit {
2
   volatile uint8_t * DdrRegister;
3
   volatile uint8_t * PortRegister;
4
   volatile uint8_t   Pin;
5
   volatile uint8_t   DimValue;
6
   volatile uint8_t   DimDir;
7
   volatile uint8_t   PwmPointer;
8
};
9
10
volatile struct portBit led[] =
11
  {
12
    {&DDRB, &PORTB, 1<<PB0, 1, 1, 0},     //  0   --1
13
    {&DDRB, &PORTB, 1<<PB1, 0, 1, 0},    //  1
14
    {&DDRB, &PORTB, 1<<PB2, 1, 1, 4},    //  2  --5
15
    {&DDRB, &PORTB, 1<<PB3, 0, 1, 0},    //  3
16
    {&DDRB, &PORTB, 1<<PB4, 0, 1, 0},    //  4
17
    {&DDRB, &PORTB, 1<<PB5, 0, 1, 0},    //  5
18
    {&DDRD, &PORTD, 1<<PD7, 1, 1, 1},    //  6  --2d
19
    {&DDRD, &PORTD, 1<<PD6, 1, 1, 2},   //  7    --3
20
    {&DDRD, &PORTD, 1<<PD5, 0, 1, 0},   //  8
21
    {&DDRD, &PORTD, 1<<PD4, 0, 1, 0},   //  9
22
    {&DDRC, &PORTC, 1<<PC0, 1, 1, 3},   //  a  --4
23
    {&DDRC, &PORTC, 1<<PC1, 1, 1, 7},   //  b  --8
24
    {&DDRC, &PORTC, 1<<PC2, 1, 1, 5},   //  c  --6
25
    {&DDRC, &PORTC, 1<<PC3, 0, 1, 0},   //  d
26
    {&DDRC, &PORTC, 1<<PC4, 0, 1, 0},   //  e
27
    {&DDRD, &PORTD, 1<<PD0, 0, 1, 0}    //  f
28
  };
29
    
30
uint8_t pwmtable_8D[32]  PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,
31
                                    13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,
32
                                    91, 108, 128, 152, 181, 215, 255};
33
34
35
36
ISR(TIMER0_OVF_vect)
37
{ 
38
  static uint8_t Tim0Cnt;
39
  static uint8_t nextLed;
40
  uint8_t aktu;
41
  uint8_t DimValue;
42
  uint8_t i;
43
  
44
  Tim0Cnt++;
45
  if(Tim0Cnt >= nextLed)
46
  {
47
 
48
//Update LedOutput
49
    aktu = 255;
50
    for (i=0; i<CHANNEL_SIZE; i++)
51
    {
52
      DimValue = led[i].DimValue;
53
      if (DimValue > Tim0Cnt)
54
        *(led[i].PortRegister) |= led[i].Pin;
55
      else
56
        *(led[i].PortRegister) &= ~led[i].Pin;
57
      
58
      if ((DimValue > Tim0Cnt) && (DimValue < aktu))
59
        aktu = DimValue;
60
    };
61
 // calc nextLed
62
    if (Tim0Cnt == 255)
63
      nextLed = 0;
64
    else 
65
      nextLed = aktu;
66
  }
67
}
68
int main (void)
69
{
70
uint8_t i;
71
uint8_t j;
72
uint8_t DimValue;
73
74
  cli();
75
  IO_Init();
76
  Tim0_Init();
77
  
78
  sei();
79
  // Main Loop
80
  while (1)
81
  {
82
    for (j=0; j<=31; j++)
83
    {
84
      DimValue = pwmtable_8D[j];
85
    
86
      for(i=0; i<CHANNEL_SIZE; i++)
87
      {
88
        led[i].DimValue = DimValue;
89
      }
90
      _delay_ms(500);
91
    }
92
  }
93
  return 0;
94
}

Es geht um die "j" schleife in main. Wenn ich diese so stehen lasse, 
führt dies zu mehreren kurzen Blinkpulsen an den LED, die leider nichts 
mit einem dem gewünschten hochdimmen der LED zu tun hat.

Wenn ich nun die äußere Schleife weglasse und stattdessen 32 mal den 
inneren Teil hinschreibe und manuell das "j" in DimValue = 
pwmtable_8D[j] durch die Werte 0..31 ersetze, funktioniert mein Code 
einwandfrei.

Hat jemand eine Idee, woran das liegen könnte? Aus meiner Sicht sollten 
beide Codedarstellungen zum gleichen Resultat führen (mal die paar Takte 
differenz in der Verarbeitungszeit außenvor gelassen).

Was könnte der Compiler da komisches mit meinem Code machen? Oder was 
gibt es für Seiteneffekte, die mir da reinspucken können?

Ein Compilieren mit -O0 hat leider auch keinen erfolg gebracht...

Viele Grüße,
Martin

von holger (Gast)


Lesenswert?

>uint8_t pwmtable_8D[32]  PROGMEM =

Das musst du mit pgm_read_byte() auslesen.

So geht es nicht

      DimValue = pwmtable_8D[j];

von Stefan E. (sternst)


Lesenswert?

Und noch als Ergänzung: mit "ausgerollter" Schleife funktioniert es, 
weil der Optimierer die Ausdrücke mit konstantem Index direkt durch die 
Werte ersetzt (z.B. "pwmtable_8D[30]" wird direkt durch "215" ersetzt), 
es also zur Laufzeit gar keine Array-Zugriffe mehr gibt.

von Martin (Gast)


Lesenswert?

Vielen Dank, das wars! Ärgerlich, dass das ausschreiben geklappt hat, 
sonst hätte ich vielleicht eher einen Anhaltspunkt gefunden, woran es 
liegt :-)


Eine kleine Frage habe ich noch:
Wird der Code langsamer, wenn ich Tabellen in den Programmspace 
auslager? wenn das so ist, dann würde ich das erst dann manchen, wenn 
ich an sehe, dass ich mit meinem Platz nicht hinkomme.
Da ich in diesem Fall z.Zt. nur diese eine Tabelle habe, macht das 
wahrscheinlich nicht den riesen Unterschied, was den Speicher angeht, 
aber ggf einen Unterschied bezüglich der Laufzeit.

Vielen Dank noch einmal für die schnelle Hilfe!

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.