Forum: Compiler & IDEs AVR Studio 5 ignoriert Code Zeilen


von Laber K. (laberkeks010)


Lesenswert?

Hallo,
bei mir scheint AVR Studio 5 gewisse Zeilen einfach zu ignorieren. 
Speziell geht es um sie Zeilen 10 bis 13:
1
  if (adc1_Offset == 0x8000)
2
  {
3
    InitWithZero = true;
4
    adc1_Offset = 0x0000;
5
...

Beim debuggen behält ''adc1_Offset '' stehts den Wert 0x8000. Auch 
"InitWithZero" wird nicht auf True gestellt.
Schaut man sich die ensprechende Assembler-Code an, so tauchen die 
beiden Variablen gar nicht auf!!

Was mach ich denn falsch? Oder ist das ein Bug?
HILFE!!? :'(
1
/******************************************************************************/
2
/**///  LoadUpHighSide()
3
/******************************************************************************/
4
uint16_t LoadUpHighSide(void)
5
{  AVR_Func_USART_SendString("\n\nLoadUpHighSide");
6
  static uint16_t adc1_Offset = 0x8000;
7
  uint8_t InitWithZero = false;
8
  
9
  //////  get iAct (i_L) offset  ////////////////////////////////////////////
10
  if (adc1_Offset == 0x8000)
11
  {
12
    InitWithZero = true;
13
    adc1_Offset = 0x0000;
14
    
15
    // first start executed before
16
    while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
17
    ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
18
    adc1_Offset = ADCA_CH1_RES-0x1234;
19
    
20
    for (uint8_t i=1; i<=3; i++)
21
    {
22
      ADCA_CTRLA |= (0b0010<<2);  // ([3210]<<2): channel 1
23
      while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
24
      ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
25
      adc1_Offset += (ADCA_CH1_RES);
26
      adc1_Offset+=10;
27
    }
28
    
29
    adc1_Offset = adc1_Offset>>2;  //div 4
30
    adc1_Offset = adc1_Offset - 512;
31
  }
32
  
33
  //////  ADC1 conversion (iAct,i_L)  ////////////////////////////////////////
34
  ADCA_CTRLA |= (0b0010<<2);
35
  while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
36
  ADCA_INTFLAGS = 0x02;    //clear ADC1 flag
37
  
38
  //////  get values  ////////////////////////////////////////////
39
  uint16_t iSet = 512 - LOADUP_CURRENT_ADC;
40
  uint16_t iAct = (ADCA_CH1_RES >> 2) - adc1_Offset;
41
  
42
  //////  select current sensor  ////////////////////////////////////////////////
43
  #if CURRENT_SENSOR_I_MAX == 50    // sensor range =  -50A ...  +50A
44
    iAct = ( (iAct+512) >> 1 );  // (iL-512)/2 + 512
45
  #elif CURRENT_SENSOR_I_MAX == 100  // sensor range = -100A ... +100A
46
    //  do nothing
47
  #else
48
    #error define 'CURRENT_SENSOR_I_MAX'
49
  #endif
50
  
51
  //////  control current to 2 A  ////////////////////////////////////////////
52
  uint16_t LoadUpPWM = CurrentControl(iSet, iAct, InitWithZero, boost, 0x0000);
53
  LoadUpPWM = LoadUpPWM>>7;
54
  TCF0_CCA = LoadUpPWM;
55
  TCF0_CCC = LoadUpPWM;
56
  
57
  return 0x1234;
58
}


1
  if (adc1_Offset == 0x8000)
2
000004B8  LDS R24,0x21C9    Load direct from data space 
3
000004BA  LDS R25,0x21CA    Load direct from data space 
4
000004BC  SUBI R24,0x00    Subtract immediate 
5
000004BD  SBCI R25,0x80    Subtract immediate with carry 
6
000004BE  BREQ PC+0x03    Branch if equal 
7
000004BF  LDI R20,0x00    Load immediate 
8
000004C0  RJMP PC+0x0030    Relative jump 
9
--- D:\dSeb work\AVRStudio5\LeoCode NightBuild\EM\default/.././main.c ----------
10
    while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
11
000004C1  LDS R24,0x022B    Load direct from data space 
12
000004C3  SBRS R24,0    Skip if bit in register set 
13
000004C4  RJMP PC-0x0003    Relative jump 
14
    ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
15
000004C5  LDI R24,0x02    Load immediate 
16
000004C6  STS 0x0206,R24    Store direct to data space 
17
    adc1_Offset = ADCA_CH1_RES-0x1234;
18
000004C8  LDS R18,0x022C    Load direct from data space 
19
000004CA  LDS R19,0x022D    Load direct from data space 
20
000004CC  SUBI R18,0x34    Subtract immediate 
21
000004CD  SBCI R19,0x12    Subtract immediate with carry 
22
000004CE  LDI R20,0x01    Load immediate 
23
      ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
24
000004CF  LDI R21,0x02    Load immediate 
25
      ADCA_CTRLA |= (0b0010<<2);  // ([3210]<<2): channel 1
26
000004D0  LDS R24,0x0200    Load direct from data space 
27
000004D2  ORI R24,0x08    Logical OR with immediate 
28
000004D3  STS 0x0200,R24    Store direct to data space 
29
      while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
30
000004D5  LDS R24,0x022B    Load direct from data space 
31
000004D7  SBRS R24,0    Skip if bit in register set 
32
000004D8  RJMP PC-0x0003    Relative jump 
33
      ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
34
000004D9  STS 0x0206,R21    Store direct to data space 
35
      adc1_Offset += (ADCA_CH1_RES);
36
000004DB  LDS R24,0x022C    Load direct from data space 
37
000004DD  LDS R25,0x022D    Load direct from data space 
38
      adc1_Offset+=10;
39
000004DF  ADIW R24,0x0A    Add immediate to word 
40
000004E0  ADD R18,R24    Add without carry 
41
000004E1  ADC R19,R25    Add with carry 
42
    for (uint8_t i=1; i<=3; i++)
43
000004E2  SUBI R20,0xFF    Subtract immediate 
44
--- D:\dSeb work\AVRStudio5\LeoCode NightBuild\EM\default/.././main.c ----------
45
000004E3  CPI R20,0x04    Compare with immediate 
46
000004E4  BRNE PC-0x14    Branch if not equal 
47
    adc1_Offset = adc1_Offset>>2;  //div 4
48
000004E5  LSR R19    Logical shift right 
49
000004E6  ROR R18    Rotate right through carry 
50
000004E7  LSR R19    Logical shift right 
51
000004E8  ROR R18    Rotate right through carry 
52
    adc1_Offset = adc1_Offset - 512;
53
000004E9  SUBI R18,0x00    Subtract immediate 
54
000004EA  SBCI R19,0x02    Subtract immediate with carry 
55
000004EB  STS 0x21C9,R18    Store direct to data space 
56
000004ED  STS 0x21CA,R19    Store direct to data space 
57
000004EF  LDI R20,0x01    Load immediate 
58
  ADCA_CTRLA |= (0b0010<<2);
59
000004F0  LDS R24,0x0200    Load direct from data space 
60
000004F2  ORI R24,0x08    Logical OR with immediate 
61
000004F3  STS 0x0200,R24    Store direct to data space

von Karl H. (kbuchegg)


Lesenswert?

Laber Keks schrieb:

>
1
>   if (adc1_Offset == 0x8000)
2
>   {
3
>     InitWithZero = true;
4
>     adc1_Offset = 0x0000;
5
> ...
6
>
>
> Beim debuggen behält ''adc1_Offset '' stehts den Wert 0x8000. Auch
> "InitWithZero" wird nicht auf True gestellt.
> Schaut man sich die ensprechende Assembler-Code an, so tauchen die
> beiden Variablen gar nicht auf!!

IntWithZero schon.

> Was mach ich denn falsch?

Du hast den Optimizer eingeschaltet?

Wozu soll der Compiler hier

>   if (adc1_Offset == 0x8000)
>   {
>     InitWithZero = true;
>     adc1_Offset = 0x0000;

adc1_Offset auf 0 setzen, wenn es gleich darauf hier

>     // first start executed before
>     while(  !(ADCA_CH1_INTFLAGS&0x01)&0x01 );
>     ADCA_INTFLAGS = 0b0010;    //clear ADC1 flag
>     adc1_Offset = ADCA_CH1_RES-0x1234;

sowieso wieder einen anderen Wert bekommt?
Dazwischen gibt es keine Möglichkeit, dass adc1_Offset irgendwie 
ausgewertet werden könnte, d.h. wenn das Programm erst mal hier 
angelangt ist, spielt es keine Rolle, ob adc1_Offset zwischendurch mal 0 
war oder nicht.
Deshalb wird der Optimizer die Zuweisung mit 0x0000 wohl rausgeschmissen 
haben.

von mR.mP3 (Gast)


Lesenswert?

Moin Moin, Hab mich jetz nicht durch deinen Code gekämpft aber,

Ich hatte das Problem auch schonmal das der Code offentsichtlich nicht 
berücksichtigt wurde. Es lag schlicht und einfach am volatile, das dem 
Compiler sagt das die Variable nicht weg optimiert werden soll.

probier es einfach mal aus.

Grüße

von Krapao (Gast)


Lesenswert?

> Schaut man sich die ensprechende Assembler-Code an, so tauchen die
> beiden Variablen gar nicht auf!!

adc1_Offset ist in den Speicheradressen 0x21C9 und 0x21CA beheimatet. 
Dessen Zuweisung
    adc1_Offset = 0x0000;
kann der Compiler wegoptimieren, weil adc1_Offset nicht volatile ist und 
ein paar Zeilen später ein anderer Wert gesetzt wird.
    adc1_Offset = ADCA_CH1_RES-0x1234;

InitWithZero ist eine nicht statische lokale Variable, d.h. der 
Compiler kann versuchen die in einem Register zu halten, und die 
Zuweisung
InitWithZero = true;
kann der Compiler bis max. vor die schliessende Klammer
    adc1_Offset = adc1_Offset - 512;
  }
verzögern. Und genau das macht er.
000004EF  LDI R20,0x01    Load immediate
ist die Zuweisung.

von Laber K. (laberkeks010)


Lesenswert?

SUper! Vielen Dank!
Der Optimierer hat in der Tat zugeschlagen. Hatte die Zeilen auch 
teilweise nur eingetragen um bei Debuggen eine Änderung zu erzwingen.

Werde mir jetzt erstmal eure Antworten noch genau anschauen...

von Klaus (Gast)


Lesenswert?

mR.mP3 schrieb:
> Ich hatte das Problem auch schonmal das der Code offentsichtlich nicht
> berücksichtigt wurde. Es lag schlicht und einfach am volatile, das dem
> Compiler sagt das die Variable nicht weg optimiert werden soll.

NEIN! NEIN! NEIN! Nicht einfach nen volatile irgendwo hinschmeißen, um 
den Optimizer an seiner korrekten arbeit zu hindern. Volatile bitte nur, 
wo der Optimizer durch Interrupts nicht wissen kann, dann eine Variable 
noch gebraucht wird.

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.