mikrocontroller.net

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


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
struct portBit {
   volatile uint8_t * DdrRegister;
   volatile uint8_t * PortRegister;
   volatile uint8_t   Pin;
   volatile uint8_t   DimValue;
   volatile uint8_t   DimDir;
   volatile uint8_t   PwmPointer;
};

volatile struct portBit led[] =
  {
    {&DDRB, &PORTB, 1<<PB0, 1, 1, 0},     //  0   --1
    {&DDRB, &PORTB, 1<<PB1, 0, 1, 0},    //  1
    {&DDRB, &PORTB, 1<<PB2, 1, 1, 4},    //  2  --5
    {&DDRB, &PORTB, 1<<PB3, 0, 1, 0},    //  3
    {&DDRB, &PORTB, 1<<PB4, 0, 1, 0},    //  4
    {&DDRB, &PORTB, 1<<PB5, 0, 1, 0},    //  5
    {&DDRD, &PORTD, 1<<PD7, 1, 1, 1},    //  6  --2d
    {&DDRD, &PORTD, 1<<PD6, 1, 1, 2},   //  7    --3
    {&DDRD, &PORTD, 1<<PD5, 0, 1, 0},   //  8
    {&DDRD, &PORTD, 1<<PD4, 0, 1, 0},   //  9
    {&DDRC, &PORTC, 1<<PC0, 1, 1, 3},   //  a  --4
    {&DDRC, &PORTC, 1<<PC1, 1, 1, 7},   //  b  --8
    {&DDRC, &PORTC, 1<<PC2, 1, 1, 5},   //  c  --6
    {&DDRC, &PORTC, 1<<PC3, 0, 1, 0},   //  d
    {&DDRC, &PORTC, 1<<PC4, 0, 1, 0},   //  e
    {&DDRD, &PORTD, 1<<PD0, 0, 1, 0}    //  f
  };
    
uint8_t pwmtable_8D[32]  PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,
                                    13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,
                                    91, 108, 128, 152, 181, 215, 255};



ISR(TIMER0_OVF_vect)
{ 
  static uint8_t Tim0Cnt;
  static uint8_t nextLed;
  uint8_t aktu;
  uint8_t DimValue;
  uint8_t i;
  
  Tim0Cnt++;
  if(Tim0Cnt >= nextLed)
  {
 
//Update LedOutput
    aktu = 255;
    for (i=0; i<CHANNEL_SIZE; i++)
    {
      DimValue = led[i].DimValue;
      if (DimValue > Tim0Cnt)
        *(led[i].PortRegister) |= led[i].Pin;
      else
        *(led[i].PortRegister) &= ~led[i].Pin;
      
      if ((DimValue > Tim0Cnt) && (DimValue < aktu))
        aktu = DimValue;
    };
 // calc nextLed
    if (Tim0Cnt == 255)
      nextLed = 0;
    else 
      nextLed = aktu;
  }
}
int main (void)
{
uint8_t i;
uint8_t j;
uint8_t DimValue;

  cli();
  IO_Init();
  Tim0_Init();
  
  sei();
  // Main Loop
  while (1)
  {
    for (j=0; j<=31; j++)
    {
      DimValue = pwmtable_8D[j];
    
      for(i=0; i<CHANNEL_SIZE; i++)
      {
        led[i].DimValue = DimValue;
      }
      _delay_ms(500);
    }
  }
  return 0;
}

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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>uint8_t pwmtable_8D[32]  PROGMEM =

Das musst du mit pgm_read_byte() auslesen.

So geht es nicht

      DimValue = pwmtable_8D[j];

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.