if Verschachtelung

Gast #3363443
Lesenswert?

Hallo,

mein Programm bleibt in der ersten if Abfrage hängen die LED blinkt aber 
wenn die Spannung <= 7400 geht es nicht mehr in die andere if Abfrage.

Wo is der Logikfehler? (und ja vor dem PC schon klar ;-))
1
int VoltageMonitoring (void)
2
{
3
 __disable_interrupt();
4

5
  uint16_t WandleWertIn16Bit (uint8_t Address)
6
  {
7
    uint16_t Wert;
8
    uint8_t  lowByte, highByte;
9
    smb_start_wait(AdresseSlave_1+SMB_WRITE);
10
    smb_write (Address);
11
    smb_rep_start(AdresseSlave_1+SMB_READ);
12

13
    lowByte = smb_readAck();
14
    highByte = smb_readNak();
15
    smb_stop();
16

17
    Wert = ( highByte << 8 ) | lowByte;
18

19
    return Wert;
20
  }
21

22
uint16_t Akkuspannung;
23
Akkuspannung = WandleWertIn16Bit(0x09);
24

25
    if (Akkuspannung <=  7800)
26
    {
27
      PORTC |=  (1 << PC0 | 1 << PC4 | 1 << PC1 | 1 << PC5 | 1 << PC3 | 1 << PC2);
28
      while (1)
29
      {
30
        Akkuspannung = WandleWertIn16Bit(0x09);
31
        PORTB |= (1 << PB2);  // LED_ROT blinken
32
        _delay_ms(1000);
33
        PORTB &= ~ (1 << PB2);
34
        _delay_ms(50);
35
        PORTB |= (1 << PB1);  
36
        _delay_ms(1000);
37
        PORTB &= ~ (1 << PB1);
38
        _delay_ms(50);
39
      }
40
    }
41
    
42
    else
43
    { 
44
      if (Akkuspannung <= 7400)
45
      {  
46
        while (1)
47
        {  PORTC &=~  (1 << PC0 | 1 << PC4 | 1 << PC1 | 1 << PC5 | 1 << PC3 | 1 << PC2);  
48
          PORTB |= (1 << PB1);  // LED_ROT blinken
49
          _delay_ms(500);
50
          PORTB &= ~ (1 << PB1);
51
          _delay_ms(500);
52
        }
53
      }
54
    }
55
__enable_interrupt(); 
56
}
Gast #3363454
Lesenswert?

>mein Programm bleibt in der ersten if Abfrage hängen die LED blinkt aber
>wenn die Spannung <= 7400 geht es nicht mehr in die andere if Abfrage.


Ja, klar! Wie auch?

Du hast eine while(1) Schleife programmiert!
Gast #3363461
Lesenswert?

wie müsste ich denn die Abfrage gestalten?

es sollte wie folgt logisch ablaufen:

ist die Spannung <= 7800

dann soll die LED erst grün dann rot blinken und noch alle anderen LEDs 
sollen an sein

wenn die Spannung aber <= 7400

ist dann sollen alle LEDs aus sein nur die Statusled soll rot schnell 
blinken.

Wie schreiben ich das in C

switch / case geht ja auch nicht da dort kein Bereichsüberprüfung 
gemacht werden kann.
Gast #3363519
Lesenswert?

hab es jetzt so umgeschrieben funktioniert leider immer noch nicht. Ich 
sehe aber nicht warum..


int VoltageMonitoring (void)
{
 __disable_interrupt();

  uint16_t WandleWertIn16Bit (uint8_t Address)
  {
    uint16_t Wert;
    uint8_t  lowByte, highByte;
    smb_start_wait(AdresseSlave_1+SMB_WRITE);
    smb_write (Address);
    smb_rep_start(AdresseSlave_1+SMB_READ);

    lowByte = smb_readAck();
    highByte = smb_readNak();
    smb_stop();

    Wert = ( highByte << 8 ) | lowByte;

    return Wert;
  }

while (1){
uint16_t Akkuspannung;
Akkuspannung = WandleWertIn16Bit(0x09);

      if (Akkuspannung <=  7800)
      {
        PORTC |=  (1 << PC0 | 1 << PC4 | 1 << PC1 | 1 << PC5 | 1 << PC3 
| 1 << PC2);
        Akkuspannung = WandleWertIn16Bit(0x09);
        PORTB |= (1 << PB2);  // LED_ROT blinken
        _delay_ms(1000);
        PORTB &= ~ (1 << PB2);
        _delay_ms(50);
        PORTB |= (1 << PB1);
        _delay_ms(1000);
        PORTB &= ~ (1 << PB1);
        _delay_ms(50);
      }

      else
        {
          if (Akkuspannung <= 7400)
          {

            PORTC &=~  (1 << PC0 | 1 << PC4 | 1 << PC1 | 1 << PC5 | 1 << 
PC3 | 1 << PC2);
            PORTB |= (1 << PB1);  // LED_ROT blinken
            _delay_ms(500);
            PORTB &= ~ (1 << PB1);
            _delay_ms(500);

          }
        }


     }

__enable_interrupt();
}
#3363534
Lesenswert?

Beginner schrieb:
> wie müsste ich denn die Abfrage gestalten?

Entweder du schaust, dass du nicht schon in den ersten Block fällst wenn 
die Akkuspannung kleiner gleich 7400 ist. Also:

if ((Akkuspannung <= 7800) && (Akkuspannung > 7400))
{
  ...
}
else if (Akkuspannung <= 7400)
{
  ...
}


oder du tauschst die Reihenfolge der if Statements (inkl. dem was 
zwischen den Klammern steht):

if (Akkuspannung <= 7400)
{
  ...
}
else if (Akkuspannung <= 7800) // d.h. 7400 < Akkuspannung <= 7800
{
  ...
}

D.h. ist Akkuspannung <= 7800 endest du in einer der beiden 
Endlosschleifen (von da geht's dann aber nie mehr raus). Ist 
Akkuspannung > 7800 kehrst du aus der Funktion zurück? Ist das das was 
du willst? Wenn ja, dann funktioniert das jetzt zwar, du solltest es 
aber trotzdem nicht tun. Eine Funktion, die manchmal endet und manchmal 
nicht, ist seeeehr hässlich und unbedingt zu vermeinden.


Gruss
Claude
Gast #3363703
Lesenswert?

Normalerweise setzt man nur einen Status für die LED und handelt diesen 
in einem Timer ab.

_delay_ms(500); ist nur eine Notlösung, warum wirst du erkennen wenn der 
Controller noch etwas Anderes machen soll...

und die uint16_t Akkuspannung; muss nicht in der while(1) sein.

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