Forum: Mikrocontroller und Digitale Elektronik If Bedingung


von Knipex W. (spektrometer)


Lesenswert?

Hallo,

ist es in C möglich mehrere UND Bedingungen hintereinander zu setzen?
Im Internet finde ich immer nur Beispiele mit zweien.
Ich habe mir das wie folgt gedacht:
1
if ((g_counter==ONE_H_WAIT) && (bit_is_clear(PINB,PB5)) &&(bit_is_clear(PINB,PB2)))
  {
    PI_ON;          // Pi einschalten
    g_counter = 0;
  }

von Peter II (Gast)


Lesenswert?

Knipex W. schrieb:
> ist es in C möglich mehrere UND Bedingungen hintereinander zu setzen?

ja, warum auch nicht.

> Ich habe mir das wie folgt gedacht:
sieht gut aus. warum testet du es nicht einfach?

von Oliver S. (oliverso)


Lesenswert?

Knipex W. schrieb:
> Im Internet finde ich immer nur Beispiele mit zweien.

Dank deines Beitrags findet man ab heute auch ein Beispiel mit dreien ;)

Oliver

von Falk B. (falk)


Lesenswert?

@  Knipex Wurst (spektrometer)

>ist es in C möglich mehrere UND Bedingungen hintereinander zu setzen?

Ja, denn C ist nicht BASCOM. In C kann man praktisch unbegrenzt viele 
Bedingungen in einen logischen Ausdruck schreiben.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Vielleicht sollte man dabei noch erwaehnen, dass bei so einem Konstrukt, 
wenn die erste Bedingung false ergibt, die nachfolgenden nicht mehr 
ausgewertet werden. Hier also konkret:
Wenn g_counter tatsaechlich nicht gleich ONE_H_WAIT ist, werden die 
bit_is_clear() Funktionen danach nicht mehr aufgerufen. Sollte man sich 
also nicht drueber wundern.

Gruss
WK

von Knipex W. (spektrometer)


Lesenswert?

Danke! Ich habe es getestet und es funktioniert nicht.
Ich habe ein kleines Timer Programm geschrieben, welches zu 
verschiedenen Zeiten Ausgang PB1 durchschalten soll. Das Programm 
funktionert bis auf den letzten Teil. Nach 1h bzw 24h wird PB1 nicht 
aktiv. Die Bedingungen sind jedoch erfüllt.

Sehr ihr vielleicht den Fehler?
Ich verwende den ATtiny45.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 32768UL //32kHz
4
5
#define SEC_P_INT  (8)
6
#define PI_ONTIME  (3*60/SEC_P_INT)   // 3 Minuten AN
7
#define ONE_H_WAIT  (60*60/SEC_P_INT)  // 1 Stunde AN
8
#define TWO_H_WAIT  (2*ONE_H_WAIT)     // 2 Stunden AN
9
#define DAY_WAIT  (24*ONE_H_WAIT)    // 24 Stunden AN
10
11
#define PI_ON    PORTB |= (1<<PB1)  // Definiere PIN 1 AN
12
#define PI_OFF    PORTB &= ~(1<<PB1) // Definiere PIN 1 AUS
13
14
15
int16_t g_counter = 0;   // Counter auf 0 setzen und Länge bis 65535
16
//int8_t g_batt_ok  = 1;   // Batterie geladen von Signal durch ICL7665
17
18
int main(void)
19
{
20
21
  DDRB |= (1 << PB1);   //  PB1 als Ausgang definieren
22
  
23
  DDRB &= ~(1 << PB0);  //  PB0 als Eingang definieren
24
  
25
  DDRB &= ~(1 << PB2);  //  PB2 als Eingang definieren
26
  
27
  DDRB &= ~(1 << PB5);  //  PB0 als Eingang definieren
28
  
29
  
30
  
31
  // Timer 0 konfigurieren@
32
  TCCR1 = (1<<CS13) | (1<<CS11) | (1<<CS10); // Prescaler auf 1024 setzen S. 90 Datasheet
33
  
34
  // Overflow Interrupt erlauben
35
  TIMSK |= (1<<TOIE1);
36
  
37
  // Global Interrupts aktivieren
38
  sei();
39
  
40
  
41
  
42
                  
43
  
44
  
45
  PI_OFF;  // Erstes Einschalten
46
      
47
    
48
  
49
  while(1)
50
  {
51
    
52
  
53
    if ((bit_is_clear(PINB,PB0)) && (bit_is_clear(PINB,PB2)))      // Wenn PB0 gedrückt und Batterie nicht leer
54
    {
55
      
56
      PI_ON;            // PIN 1 AN
57
      
58
      g_counter = 0;
59
    } // if
60
  } // while
61
} // main
62
63
#ifndef TIMER1_OVF_vect
64
65
#define TIMER1_OVF_vect TIMER1_OVF0_vect
66
#endif
67
68
#include <stdint.h>
69
70
71
72
ISR (TIMER1_OVF_vect)
73
{
74
  
75
  g_counter++;  // counter hochzählen lassen
76
  
77
  if (g_counter==PI_ONTIME)  // Wenn Counter = 3 Min
78
  PI_OFF;          // Pi ausschalten
79
  
80
  if ((g_counter==ONE_H_WAIT) && (bit_is_clear(PINB,PB5)) && (bit_is_clear(PINB,PB2)))  // Wenn Counter bei 60 Min und Pin PB5 AN und Batterie geladen
81
  {
82
    PI_ON;          // Pi einschalten
83
    g_counter = 0;
84
  }
85
  
86
  if ((g_counter==DAY_WAIT) && (bit_is_set(PINB,PB5)) && (bit_is_clear(PINB,PB2)))  // Wenn Counter bei 60 Min und Pin PB5 AUS und Batterie geladen
87
  {
88
    PI_ON;          // Pi einschalten
89
    g_counter = 0;
90
  }
91
  
92
  
93
}

von Thomas E. (picalic)


Lesenswert?

Meist wird es noch etwas übersichtlicher, wenn man es dann auf mehrere 
Zeilen verteilt, z.B.:
1
if ((g_counter==ONE_H_WAIT) 
2
   && (bit_is_clear(PINB,PB5)) 
3
   && (bit_is_clear(PINB,PB2))) 
4
{...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und noch übersichtlicher wird es, wenn man die überflüssigen Klammern 
um den Aufruf von "bit_is_clear" weglässt.

von tomske (Gast)


Lesenswert?

Im Programm wird an verschiedenen Stellen g_counter auf 0 gesetzt. Bist 
Du sicher, dass dadurch die Vergleiche mit den ONE_H_WAIT, DAY_WAIT usw. 
noch passen?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Knipex W. schrieb:
> Sehr ihr vielleicht den Fehler?
1
  if ((g_counter==ONE_H_WAIT) && (bit_is_clear(PINB,PB5)) && (bit_is_clear(PINB,PB2)))  // Wenn Counter bei 60 Min und Pin PB5 AN und Batterie geladen
2
  {
3
    PI_ON;          // Pi einschalten
4
    g_counter = 0;    // ******   BOOOM  *****
5
  }
6
  
7
  if ((g_counter==DAY_WAIT) && (bit_is_set(PINB,PB5)) && (bit_is_clear(PINB,PB2)))  // Wenn Counter bei 60 Min und Pin PB5 AUS und Batterie geladen
8
  {

 Wie soll er jemals DAY_WAIT erreichen ?

von Knipex W. (spektrometer)


Lesenswert?

Mit der if-Bedingung in der while Schleife möchte ich per Taster einen 
Reset durchführen können. Danach soll der Timer wieder auf 0 sein.

Also jedes mal wenn g_counter=o gesetzt wird, ist es so gewollt.
Ob dadurch Probleme mit der ONE_H_WAIT und DAY_WAIT entstehen ist ja die 
Frage...

von Knipex W. (spektrometer)


Lesenswert?

>  Wie soll er jemals DAY_WAIT erreichen ?

Wenn bei ONE_H_WAIT   " (bit_is_clear(PINB,PB5)) " nicht erfüllt ist 
läuft der Timmer ja weiter bis ONE_DAY_WAIT

von Fabian D. (fabian_d)


Lesenswert?

g_counter sollte als volatile deklariert werden.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Knipex W. schrieb:
> Wenn bei ONE_H_WAIT   " (bit_is_clear(PINB,PB5)) " nicht erfüllt ist
> läuft der Timmer ja weiter bis ONE_DAY_WAIT

 Ja, dann mach doch mal deine Abfrage anders, so ist es unubersichtlich
1
  if (bit_is_clear(PINB,PB2)) {
2
    if ((g_counter==ONE_H_WAIT) && (bit_is_clear(PINB,PB5))) {
3
      ...
4
    }
5
    if ((g_counter==DAY_WAIT) && (bit_is_set(PINB,PB5))) {
6
      ...
7
    } 
8
  }

von Peter II (Gast)


Lesenswert?

Fabian D. schrieb:
> g_counter sollte als volatile deklariert werden.

warum sollte er das?

Damit der code größer wird?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Marc V. schrieb:
> Ja, dann mach doch mal deine Abfrage anders, so ist es unubersichtlich

 Oder, für Masochisten:
1
  if ((bit_is_clear(PINB,PB2)) && ((g_counter==ONE_H_WAIT) && bit_is_clear(PINB,PB5)) || (g_counter==DAY_WAIT) && (bit_is_set(PINB,PB5)))) {
2
          PI_ON;          // Pi einschalten
3
          g_counter = 0;
4
  }
 Klammern nicht gezahlt, Fehler garantiert ;)

: Bearbeitet durch User
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.