Forum: Compiler & IDEs Über einen µC Laufzeit messen und über RS232 ausgeben


von Roman (Gast)


Angehängte Dateien:

Lesenswert?

Guten Tag,

ich komme mit meinem Programm nicht mehr weiter.

Es soll ein 8 Kanal Laufzeitmesser werden der über RS232 die Laufzeit an 
den PC sendet. Genauichkeit +/-5 Minuten abweichung am Tag sind 
tolerierbar.

Testweise habe ich derzeit nur 2 Kanäle im Programm.

Die Funktion ist simpel.
Es wird ein Starttaster gedrückt um die Messung zu starten.
Eine Status LED zeigt an ob die Messung läuft.
Wenn am Eingang die Spannung von 5V ausfällt wird die Zeit über RS232 an 
den PC gesendet.

Das Funktioniert auch "fast" alles wunderbar.
Das Problem ist das der Timer nicht sofort aufhört sondern noch die 60 
Sekunden nachzählt bis er sich auf 0 zurücksetzt.

Ein Auszug aus dem Terminal Programm:

#1 Laufzeit_1 0:00:01:44 Spannung am Eingang fällt auf 0V, Ausgabe 
korrekt
#2 Laufzeit_1 0:00:00:51 hier müsste der Timer wieder mit 0 anfangen.
#3 Laufzeit_1 0:00:00:58 aber er zählt die Sekunden von Zeile 1 mit 
"44"weiter
#4 Laufzeit_1 0:00:00:01 die Minute wird hingegen nicht mehr 
hochgezählt.

Er hat nur zum Teil die Zeit richtig zurückgesetzt nur die Sekunden 
zählen nach.


Die Programmierung ist etwas "durchwachsen" und unübersichtlich dies 
bitte ich zu entschulden, da ich mich erst vor einigen Montaten mit "C" 
und µC von Atmel beschäftige.


Ich bin für jede Hilfe dankbar. :-)

von spontan (Gast)


Lesenswert?

>   if (PINB &(1<<PINB0)) // Kanal 1 5V fallen aus
>
>   if (PINB &(1<<PINB2)) // Kanal 1 5V fallen aus

Findet sich beides im Programm. Was gilt wirklich?

von Christian (Gast)


Lesenswert?

if (PINB &(1<<PINB2)) // Kanal 1 5V fallen aus
        {
          Kanal_1=0;
          tage=0, stunden=0, minuten=0, sekunden=0;
        }
      if (PINB &(1<<PINB3)) // Kanal 2 5V fallen aus
        {
          Kanal_2=0;
          tage_1=0, stunden_1=0, minuten_1=0, sekunden_1=0;

        }


Ich denke du musst nicht nur den Sekundenzähler zurücksetzen sondern 
auch die variable timer die du in der ISR verwendest.

von Christian (Gast)


Lesenswert?

if (sekunden!=timer)
      {
        sekunden=timer;

Da beschreibst du die Variable sekunden nämlich wieder mit dem Wert, der 
noch in timer steht. und das ist nicht Null.

von Roman (Gast)


Lesenswert?

if (PINB &(1<<PINB0)) // Kanal 1 5V fallen aus
bezieht sich auf die Ausgabe auf RS232

if (PINB &(1<<PINB2)) // ist der Starttaster


Sorry, Kommentar falsch im Programmcode.

von Roman (Gast)


Lesenswert?

Christian schrieb:
> if (PINB &(1<<PINB2)) // Kanal 1 5V fallen aus
>         {
>           Kanal_1=0;
>           tage=0, stunden=0, minuten=0, sekunden=0;
>         }
>       if (PINB &(1<<PINB3)) // Kanal 2 5V fallen aus
>         {
>           Kanal_2=0;
>           tage_1=0, stunden_1=0, minuten_1=0, sekunden_1=0;
>
>         }
>
> Ich denke du musst nicht nur den Sekundenzähler zurücksetzen sondern
> auch die variable timer die du in der ISR verwendest.
1
      if (PINB &(1<<PINB2)) // Kanal 1 Starttaster
2
        {
3
          Kanal_1=0;
4
          tage=0, stunden=0, minuten=0, sekunden=0;
5
          timer=0;
6
        }
7
      if (PINB &(1<<PINB3)) // Kanal 2 Starttaster
8
        {
9
          Kanal_2=0;
10
          tage_1=0, stunden_1=0, minuten_1=0, sekunden_1=0;
11
          timer=0;
12
          
13
        }

Das habe ich jetzt damit gemacht.
Neues Problem, es werden alle Timer an allen Eingängen zurückgesetzt 
sobald ein Eingang auf 0V fällt.

Mit meinem Wissenstand kann ich das Problem nur mit Acht 16 Bit Timern 
Timer_1 Timer_2 Timer_n usw lösen, diese hat der Atmega8 natürlich 
nicht.

Man müsste den Timer Kanalunabhänig machen.

von spontan (Gast)


Lesenswert?

Dann mach es doch kanal-unabhängig.

Wie wäre so:

Es gibt nur eine Uhrzeit im System, die immer tage, stunden, min ... 
hochzählt.

Start eines Kanals speichert diese Zeit auf der Variablen für diesen 
Kanal ab.
Stop des Kanals berechnet die Differenz zwischen aktueller Uhrzeit und 
Startzeit.

Geht mit beliebig viel Kanälen.

von meine wenigkeit (Gast)


Lesenswert?

So wie du das machst ist das ja auch extrem umständlich und 
verschwenderisch.
Mach es doch folgenddrmaßen:

Du nimmst einen uint32 zähler als variable. Der zähler zählt immer 
weiter über den hw-timer.
Werden jetzt an einem kanal 5v angelegt setzt du den einen uint32 als 
startwert = zähler
Fällt die spannung auf 0v setzt du den stopwert auf den aktuellen 
zähler.
Die verstichene zeit ist dann stopwert-startwert in was immer der zähler 
als zeitintervall zählt.
Du gibst die zeit aus und fertig ist die laube.

Vorteile: nur ein hw-timer und nur zwei variablen pro kanal zu 
verwalten.
Nachteile: uint32 sind nicht gerade schnell auf dem avr jedoch sollte es 
schnell genug sein.

von Roman (Gast)


Lesenswert?

Danke für die Tipps!

Das erste Testprobramm läuft mit zwei Kanälen gut.

von Roman (Gast)


Angehängte Dateien:

Lesenswert?

Danke nochmal für die Hilfe,

das Programm habe ich jetzt auf 4 Kanäle erweitert.

Funktioniert super. :-)

Jetzt müsste ich das ganze was kleiner bekommen.
Bin schon bei 6734 bytes.

Einige uint32_t muss ich noch was verkleinern und einige if else 
Anweisung in der Sekunden-> Std:Min:sek Zeitumrechnung sind überflüssig.

Noch weitere Ideen wie man es kleiner bekommen könnte?

Geplant sind insgesammt 8 Kanäle.

von Martin V. (oldmax)


Lesenswert?

Hi
Alternative... Zeitzähler in Controller. Wenn du die Frequenz kennst, 
also den Zeitwert, dann kannst du einfach die Zählerdifferenz akt. 
Zähler - Startwert an den PC senden. Der kann auch rechnen und du 
belastest nicht den Controller mit dieser Aufgabe. Denkbar ist auch die 
Differenz im PC zu berechnen.
Also,
Startwert bei Ereignis X mit Zählerwert setzen
Endwert bei Ereignis Y mit Zählerwert setzen
   -> Senden: Kanal, Startwert, Endwert..
Im PC berechnen Endwert - Startwert. Ist Ergebnis negativ, dann max. 
Zählerwert dazu addieren.
Beispiel:
Deine "Counter"-Variable zählst du im Sekundentakt hoch. Bei 16 Bit wäre 
die größte Zahl 65 535, dann beginnt die Zählerei von vorn. Das 
Zeitfenster ist somit 18 Stunden, 12 Minuten und 12 Sekunden. Wenn du 
nur 10 Sekunden Genauigkeit brauchst, dann sind das schon über 180 
Stunden...
OK, angenommen Startwert ist 12301, Endwert ist 46122. Demnach ist 
Zeitwert Endwert-Startwert also 32821 Sekunden.
Es kann aber auch genau umgekehrt sein, das bei der Zeitzählung ein 
Überlauf stattgefunden hat.
Startwert 43113, Endwert 30251. Hier ergibt sich ein Wert von -12882. Da 
das Ergebnis negativ ist addierst du nun den max. Zählwert der Variable 
hinzu, also + 65535 und erhälst 52653
Somit brauchst du nicht unbedingt 32 Bit zum Zählen und belastet auch 
sonst nicht deinen µC. Für den PC ist das auch nix besonderes.
Gruß oldmax

von Karl H. (kbuchegg)


Lesenswert?

Roman schrieb:

> Jetzt müsste ich das ganze was kleiner bekommen.

Funktionen sind schon erfunden wurden.

Wenn du für jeden Kanal einfach den kompletten Code erneut duplizierst, 
ist klar, dass dir das alles axplodiert.


> Einige uint32_t muss ich noch was verkleinern und einige if else
> Anweisung in der Sekunden-> Std:Min:sek Zeitumrechnung sind überflüssig.


Ist sinnvoll.
ABer dein Hauptproblem ist, dass du exzessive Codeduplizierung betreibst 
anstatt dir eine Funktion zu schreiben, der man die Werte für 1 Kanal 
übergibt! Ist doch immer die gleiche Berechnung, nur die Variablen sind 
andere.

von Karl H. (kbuchegg)


Lesenswert?

Da du sowieso printf benutzt

Was soll das
1
>             if (minerg<10)
2
>             {
3
>               printf("0%i:", minerg);
4
>             }
5
>             else
6
>             {
7
>               printf("%i:", minerg);
8
>             }
9
>

das kann printf auch alleine
1
   printf( "%02d:", minerg );

fertig.
Ich muss mich korrigiern. Dein Hauptproblem ist, dass du mit lediglich 
5% Wissen über deine Programmiersprache, dich an ein Projekt wagst.

von Karl H. (kbuchegg)


Lesenswert?

zb den ganzen Teil hier
1
>         hour = (counter_4_end/3600);
2
>         if(counter_4_end%3600 == 0)
3
>         {
4
>           stderg = hour;
5
>           minerg = 0;
6
>           sekerg = 0;
7
>           if (stderg<10)
8
>           {
9
>             printf("0%i:", stderg);
10
>           }
11
>           else
12
>           {
13
>             printf("%i:", stderg);
14
>           }
15
> 
16
>           if (minerg<10)
17
>           {
18
>             printf("0%i:", minerg);
19
>           }
20
>           else
21
>           {
22
>             printf("%i:", minerg);
23
>           }
24
> 
25
>           if (sekerg<10)
26
>           {
27
>             printf("0%i ", sekerg);
28
>           }
29
>           else
30
>           {
31
>             printf("%i ", sekerg);
32
>           }
33
> 
34
>         }
35
> 
36
>         else
37
>         {
38
>           minute = ((counter_4_end - (hour * 3600))/60);
39
>           if((counter_4_end-(hour*3600))%60 == 0)
40
>           {
41
>             minerg = minute;
42
>             sekerg = 0;
43
>             if (minerg<10)
44
>             {
45
>               printf("0%i:", minerg);
46
>             }
47
>             else
48
>             {
49
>               printf("%i:", minerg);
50
>             }
51
> 
52
>             if (sekerg<10)
53
>             {
54
>               printf("0%i ", sekerg);
55
>             }
56
>             else
57
>             {
58
>               printf("%: ", sekerg);
59
>             }
60
> 
61
>           }
62
>           else
63
>           {
64
>             second = (counter_4_end-(hour*3600))%60;
65
>             stderg = hour;
66
>             minerg = minute;
67
>             sekerg = second;
68
>             if (stderg<10)
69
>             {
70
>               printf("0%i:", stderg);
71
>             }
72
>             else
73
>             {
74
>               printf("%i:", stderg);
75
>             }
76
> 
77
>             if (minerg<10)
78
>             {
79
>               printf("0%i:", minerg);
80
>             }
81
>             else
82
>             {
83
>               printf("%i:", minerg);
84
>             }
85
> 
86
>             if (sekerg<10)
87
>             {
88
>               printf("0%i ", sekerg);
89
>             }
90
>             else
91
>             {
92
>               printf("%i ", sekerg);
93
>             }
94
>           }
95
>         }
96
>       }
97
>     }
98
>

kann man in eine Funktion stecken und anders rechnen
1
void printf_time( uint32 time )
2
{
3
  uint8_t sekunde;
4
  uint8_t minute;
5
  uint16_t hour;
6
7
  sekunde = time % 60;
8
  time = time / 60;
9
  minute = time % 60;
10
  hour = time / 60;
11
  
12
  printf( "%04d:%02d:%02d", hour, minute, sekunde );
13
}


und dann ruft man eben die Funktion mit wechselnden Aufrufparametern 
auf, wenn man sie braucht:
1
int main()
2
{
3
....
4
    // KANAL 1
5
    if (PIND &(1<<PIND4)) // Kanal 1 5V fallen aus
6
    {
7
      counter_1_end = timer_1 - counter_1_start;
8
9
      if (Kanal_1 == 0)
10
      {
11
        printf("Laufzeit Kanal 1: ");
12
        PORTC^=(1<<PC0); // Status LED ausschalten
13
14
        printf_time( counter1_end );
15
      }
16
    }
17
18
    // KANAL 2
19
    if (PIND &(1<<PIND5)) // Kanal 2 5V fallen aus
20
    {
21
      counter_2_end = timer_2 - counter_2_start;
22
23
      if (Kanal_2==0)
24
      {
25
        printf("Laufzeit Kanal 2: ");
26
        PORTC^=(1<<PC1); // Status LED ausschalten
27
        Kanal_2 = 1; // Zum testen auf "0"
28
29
        printf_time( counter_2_end );
30
      }
31
    }
32
33
    // KANAL 3
34
    if (PIND &(1<<PIND6)) // Kanal 3 5V fallen aus
35
    {
36
      counter_3_end = timer_3-counter_3_start;
37
38
      if (Kanal_3 == 0)
39
      {
40
        printf("Laufzeit Kanal 3: ");
41
        PORTC ^= (1<<PC2); // Status LED ausschalten
42
        Kanal_3 = 1; // Zum testen auf "0"
43
44
        printf_time( counter_3_end );
45
      }
46
    }
47
    
48
    // KANAL 4
49
    if (PIND &(1<<PIND7)) // Kanal 4 5V fallen aus
50
    {
51
      counter_4_end = timer_4-counter_4_start;
52
      if (Kanal_4 == 0)
53
      {
54
        printf("Laufzeit Kanal 4: ");
55
        PORTC ^= (1<<PC3); // Status LED ausschalten
56
        Kanal_4 = 1; // Zum testen auf "0"
57
58
        printf_time( counter_4_end );
59
      }
60
    }
61
....

und schon ist dein Code nicht mehr 25 Seiten lang, sondern nur noch 2. 
Was ja dann auch der Übersicht im Code zu gute kommt. Und selbst das 
könnte man noch eindampfen, wenn man nicht 2 Millionen einzelne 
Variablen macht, sondern die in Arrays (noch besser wären Strukturen und 
ein Array von Strukturen) zusammenfasst.

Wie gesagt: wer etwas bauen will, muss sein Werkzeug kennen und damit 
umgehen können. Dein Werkzeug ist eine Programmiersprache. Ich sehe aber 
nicht, das du damit umgehen könntest.

1
struct channel
2
{
3
  uint8_t  show;
4
  uint32_t ticks;
5
  uint32_t end;
6
  uint32_t start;
7
  uint8_t  status_led;
8
  uint8_t  eingang;
9
};
10
11
#define ANZAHL_KANAL  4
12
struct channel kanal[ANZAHL_KANAL] =
13
{
14
  { 1, 0, 0, 0, 1<<PC0, 1<<PIND4 },
15
  { 0, 0, 0, 0, 1<<PC1, 1<<PIND5 },
16
  { 0, 0, 0, 0, 1<<PC2, 1<<PIND6 },
17
  { 0, 0, 0, 0, 1<<PC3, 1<<PIND7 }
18
};
19
20
21
int main(void)
22
{
23
  uint8_t i;
24
25
  TIMSK |= _BV(TOIE1);   //aktivieren des Überlaufinterrupts von Timer1
26
  TCCR1B |= (1<<CS12) | (1<<CS10); // Berechnet mit http://evolutec.publicmsg.de/index.php?menu=software&content=prescalertools
27
  TCNT1 = 0xFFFF;     //Zählregister vorladen mit FFFF zum Sofortstart
28
  sei();  //Interrupts aktivieren
29
30
  DDRC|=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(0<<PC4)|(0<<PC5);  // LED 0-3 Stauts LED 4+5 Taster Kanal 1+2
31
  DDRC=0b00001111; //Eingang Taster 1+2 =  Eingang 5V PD1+2 bereits mit RXD TXD belegt
32
  DDRD=0x00; // Eingang Taster 3 = PIND 2 bis PIND 3 Start PIND4-PIND7 Eingang 5V
33
34
35
  initUART();
36
37
  stdout = &mystdout;
38
39
  do
40
  {
41
    if (1) // (sekunden!=timer)
42
    {
43
      for( i = 0; i < ANZAHL_KANAL; i++ )
44
      {
45
        kanal[i].ticks = timer + 1;
46
      }
47
    }
48
    
49
    // Starttaster
50
51
    if (PINC &(1<<PINC4)) // Kanal 1 Starttaster
52
    {
53
      kanal[0].start = kanal[0].ticks;
54
      kanal[0].show = 1;
55
      PORTC |= kanal[0].status_led;
56
    }
57
58
    if (PINC &(1<<PINC5)) // Kanal 2 Starttaster
59
    {
60
      kanal[1].start = kanal[1].ticks;
61
      kanal[1].show = 1;
62
      PORTC |= kanal[1].status_led;
63
    }
64
65
    if (PIND &(1<<PIND2)) // Kanal 3 Starttaster
66
    {
67
      kanal[2].start = kanal[2].ticks;
68
      kanal[2].show = 1;
69
      PORTC |= kanal[2].status_led;
70
    }
71
72
    if (PIND &(1<<PIND3)) // Kanal 4 Starttaster
73
    {
74
      kanal[3].start = kanal[3].ticks;
75
      kanal[3].show = 1;
76
      PORTC |= kanal[3].status_led;
77
    }
78
79
    for( i = 0; i < ANZAHL_KANAL; i++ )
80
    {
81
      if (PIND & kanal[i].eingang)
82
      {
83
        kanal[i].end = kanal[i].ticks - kanal[i].start;
84
85
        if (kanal[i].show)
86
        {
87
          printf("Laufzeit Kanal %d: ", i + 1);
88
          printf_time( kanal[i].end );
89
          printf("\n");
90
          
91
          PORTC ^= kanal[i].status_led; // Status LED ausschalten
92
        }
93
      }
94
    }
95
  }
96
}


und wenn du deine Starttaster noch ein wenig anders anordnen würdest, 
dann könnte man auch die noch einfach mit ins Array reinnehmen und den 
ganzen Programmteil rund um die Starttaster ebenfalls auf 1 Schleife 
eindampfen. Was dann wieder die Möglichkeit eröffnet, alle 3 SChleifen 
zu lediglich einer einzigen for-Schleife zusammenzufassen.

Dann ist dein Code in main() gerade mal 1/2 Bildschirmseite lang :-)

von M. N. (Gast)


Lesenswert?

Roman schrieb:
> Jetzt müsste ich das ganze was kleiner bekommen.
> Bin schon bei 6734 bytes.

Wozu sparsam programmieren, wenn andere µCs mit viel mehr Speicher 
daherkommen? Optimieren ist doch nur etwas für Streber :-)
Ein pinkompatibler ATmega328 mit seinen 32kB Flash erlaubt es Dir, 
sämtliche Schleifen 'auseinander zu rollen'.

von Peter D. (peda)


Lesenswert?

M. N. schrieb:
> Optimieren ist doch nur etwas für Streber :-)

Nö, sondern für die Leute, die noch nach ein paar Monaten im Code 
durchsehen wollen. Oder die leicht Änderungen/Erweiterungen durchführen 
wollen.

Dieser ganze Wust läßt sich für 8 Zeitmesser auf eine Schleife i = 0..7 
reduzieren, die nur eine Funktion aufruft.
Ein Array enthält dann die 8 Zeitspeicher und ein Array die Bitmasken 
für die 16 Eingangspins.

von M. N. (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Ein Array enthält

Wie, soll er noch ein Array kaufen?

Bei A..i gibt es momentan Keramikmeseer. Vielleicht kann man die ja zu 
einem Laufzeitmesser umbauen?

von Roman (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> und wenn du deine Starttaster noch ein wenig anders anordnen würdest,
> dann könnte man auch die noch einfach mit ins Array reinnehmen und den
> ganzen Programmteil rund um die Starttaster ebenfalls auf 1 Schleife
> eindampfen. Was dann wieder die Möglichkeit eröffnet, alle 3 SChleifen
> zu lediglich einer einzigen for-Schleife zusammenzufassen.
>
> Dann ist dein Code in main() gerade mal 1/2 Bildschirmseite lang :-)

Gesagt getan.
1
struct channel
2
{
3
  uint8_t  show;      // Startsperre
4
  uint32_t ticks;      // Systemlaufzeit
5
  uint32_t end;      // Gemessene Zeit
6
  uint32_t start;      // Startzeit der Messung
7
  uint8_t  status_led;  // Status der Messung
8
  uint8_t  eingang;    // Start Taster
9
  uint8_t  spannung;    // Eingangsspannung
10
};
11
12
#define ANZAHL_KANAL  4
13
struct channel kanal[ANZAHL_KANAL] =
14
{
15
{ 1, 0, 0, 0, 1<<PC0, 1<<PIND4, 1<<PINB0},
16
{ 0, 0, 0, 0, 1<<PC1, 1<<PIND5, 1<<PINB1},
17
{ 0, 0, 0, 0, 1<<PC2, 1<<PIND6, 1<<PINB2},
18
{ 0, 0, 0, 0, 1<<PC3, 1<<PIND7, 1<<PINB3}
19
};
20
21
22
int main(void)
23
{
24
  uint8_t i;
25
26
  TIMSK |= _BV(TOIE1);   //aktivieren des Überlaufinterrupts von Timer1
27
  TCCR1B |= (1<<CS12) | (1<<CS10); // Berechnet mit http://evolutec.publicmsg.de/index.php?menu=software&content=prescalertools
28
  TCNT1 = 0xFFFF;     //Zählregister vorladen mit FFFF zum Sofortstart
29
  sei();  //Interrupts aktivieren
30
31
  DDRC|=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3);  // LED 0-3 Stauts LED
32
  DDRB=0x00; // Eingangsspannung 
33
  DDRD=0x00; // Messung starten PIND4-PIND7 Ue=5V
34
35
36
  initUART();
37
38
  stdout = &mystdout;
39
40
  do
41
  {
42
    for( i = 0; i < ANZAHL_KANAL; i++ )
43
    {
44
      {
45
        kanal[i].ticks = timer + 1;
46
      }
47
      
48
      if (PINB & kanal[i].spannung)
49
      {
50
        kanal[i].start = kanal[i].ticks;
51
        kanal[i].show = 1;
52
        PORTC |= kanal[i].status_led; // Status LED an
53
      }
54
55
      if (PIND & kanal[i].eingang)
56
      {
57
58
        kanal[i].end = kanal[i].ticks - kanal[i].start;
59
60
        if (kanal[i].show)
61
        {
62
          printf("Laufzeit Kanal %d: ", i + 1);
63
          printf_time( kanal[i].end );
64
          printf("\n");
65
          
66
          PORTC ^= kanal[i].status_led; // Status LED aus
67
          kanal[i].show=0; // 5V Eingang sperren
68
        }
69
      }
70
    }
71
  }
72
while (1);
73
}

Danke für die großartige Hilfe und Kritiken.

Diese Version ist viel übersichtlicher und mit 2320 Bytes auch 
schlanker, die Erweiterbarkeit ist auch gegeben.

Und wieder etwas dazu gelernt.

von Karl H. (kbuchegg)


Lesenswert?

Jo. So wird das was.
Und die Erweiterung auf 8 Kanäle ist jetzt trivial. :-)

von Peter D. (peda)


Lesenswert?

Die "end" brauchst Du nicht und die "ticks" zählst Du gemeinsam für 
alle:
1
uint32_t ticks;
2
//..
3
      if (PINB & kanal[i].spannung)
4
      {
5
        kanal[i].start = ticks;
6
        kanal[i].show = 1;
7
        PORTC |= kanal[i].status_led; // Status LED an
8
      }
9
      if (PIND & kanal[i].eingang)
10
      {
11
        if (kanal[i].show)
12
        {
13
          printf("Laufzeit Kanal %d: ", i + 1);
14
          printf_time( ticks - kanal[i].start );
15
//..

von Roman (Gast)


Lesenswert?

2266 Bytes

Wenn es so weiter geht wird es ein 3 Zeiler. :-)

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.