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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.