Forum: Compiler & IDEs Funktion gleichzeit ausführen


von Sebastian (Gast)


Lesenswert?

Hallo,

folgendes, ich will ein Programm das mehrere Ausgänge gleichzeit 
anschaltet und diese Ausgänge dann zufällig "flackern" lässt, meine 
Frage ist jetzt wie ich meine Funktion gleichzeitig für mehrere Ausgänge 
starten kann, im moment schalten sie nacheinander. Ich bin leider noch 
Anfänger ;)

Grüße aus Berlin

1
#include <avr/io.h>          
2
#include <avr/delay.h>
3
#include <stdlib.h>
4
5
6
void delay_ms(int ms)
7
{
8
  int t;
9
  for(t=0; t<=ms; t++)
10
  _delay_ms(1);
11
}
12
13
14
void startpin_B(int pid)
15
{
16
  PORTB   &= (1<<pid);                     
17
  delay_ms(10);
18
  PORTB  |=  (1<<pid);
19
  delay_ms(10);
20
  PORTB  &= ~(1<<pid);
21
  delay_ms(15);
22
  PORTB  |=  (1<<pid);
23
  delay_ms(20);
24
  PORTB  &= ~(1<<pid);
25
  delay_ms(50);
26
  PORTB  |=  (1<<pid);
27
  delay_ms(20);
28
  PORTB  &= ~(1<<pid);
29
  delay_ms(100);
30
  PORTB  |=  (1<<pid);
31
32
}
33
 
34
int main (void) {            
35
 
36
37
 
38
 
39
  DDRB    =  0xFF;                      
40
  startpin_B(PB0);
41
  startpin_B(PB1);
42
  startpin_B(PB5);
43
44
 
45
   while(1) {                
46
    
47
  
48
  
49
   }                         
50
 
51
   return 0;                 
52
}

von Karl H. (kbuchegg)


Lesenswert?

Die kurze Antwort lautet: Gar nicht

Die etwas längere Antwort lautet: Du musst dein Programm umschreiben, so 
dass 1 Funktion beide Ausgaben in einem Aufwasch macht.

Ein Programm ist nicht etwas, wo man Enzelteile in einen Topf schmeisst 
und alles funktioniert parallel weiter so wie bisher.

In deinem Fall führt der WEg über die Erkentniss, dass man durchaus 
mittels

  PORTB |= ( 1 << PB0 ) | ( 1 << PB5 );

2 Ausgänge 'gleichzeitig' schalten lassen kann und das geht dann auch 
für noch mehr Ausgänge.

von Valentin B. (nitnelav) Benutzerseite


Lesenswert?

Du kannst einfach mehrere Portpins gleichzeitig zuweisen.
Also statt
1
void startpin_B(int pid)
2
{
3
  PORTB   |= (1<<pid);                     
4
  delay_ms(10);


einfach

1
void startpin_B(uint8_t pid1, uint8_t pid2)
2
{
3
  PORTB   |= (1<<pid1) | (1<<pid2);                     
4
  delay_ms(10);

schreiben.
Die Umstellung auf uint8_t sorgt übrigens nur dafür, dass der Compiler 
auch wirklich 8-bit für deine Variablen nutzt. Je nach System kann ein 
int auch mal 16-bit lang sein.

Mit freundlichen Grüßen,
Valentin Buck

von Sebastian (Gast)


Lesenswert?

Ok, danke für die Antworten erstmal!

Das Problem ist nur das ich dann wieder nicht weiter komme, mein 
nächster Schritt wäre ja gewesen es so umzuschreiben das die Ausgänge 
auch zu unterschiedlichen Zeiten an / aus gehen, also mit wenigen ms 
unterschied, so schalten ja alle gleich.

von Falk B. (falk)


Lesenswert?

@  Sebastian (Gast)

>nächster Schritt wäre ja gewesen es so umzuschreiben das die Ausgänge
>auch zu unterschiedlichen Zeiten an / aus gehen, also mit wenigen ms
>unterschied, so schalten ja alle gleich.

So kann man das machen.

1
#include <avr/io.h>          
2
#include <avr/delay.h>
3
#include <stdlib.h>
4
5
int main (void) {            
6
  uint8_t cnt=0;
7
  uint8_t data[8] = {0xFF, 0x01, 0x04, 0x5A, 0x66, 0xAB, 0x11, 0xCC};
8
9
  DDRB    =  0xFF;                      
10
 
11
   while(1) {
12
     PORTB = data[cnt];
13
     cnt++;
14
     if (cnt == 8) cnt=0;               
15
     _delay_ms(10);
16
   }                         
17
 
18
   return 0;                 
19
}

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Ok, danke für die Antworten erstmal!
>
> Das Problem ist nur das ich dann wieder nicht weiter komme, mein
> nächster Schritt wäre ja gewesen es so umzuschreiben das die Ausgänge
> auch zu unterschiedlichen Zeiten an / aus gehen, also mit wenigen ms
> unterschied, so schalten ja alle gleich.

Dachte ich mir schon, dass sowas kommen wird :-)

Dann musst du auf den kleinsten gemeinsamen Nenner gehen und deinen 
internen Zeitgeber auf diesen kleinsten gemeinsamen Nenner einstellen 
und entsprechende Zähler dafür benutzen.

Ist wie bei einer Uhr.
Wenn du alle 20 Sekunden das Licht ein/aus schalten willst und alle 15 
Sekunden die Tür auf/zu, dann brauchst du einen Zeitgeber der alle 5 
Sekunden 'tick' macht.
Mit den Fingern der linken Hand zählst du für das Licht bei jedem 
'tick': 1, 2, 3, 4 und schaltest das Licht um und mit den Fingern der 
rechten Hand zählst du 1, 2, 3 und bedienst die Tür.

Voila: Auch wenn du nur 1 Zeitgeber hast, folgt das Licht seinem 20 
Sekunden Rhythmus und die Tür ihrem 15 Sekunden Rhythmus.

von Sebastian (Gast)


Lesenswert?

Wow! Danke!
Das ist ja wirklich einfacher als gedacht, habe wohl zu kompliziert 
gedacht, aber das macht ja wirklich Sinn.

Dankeschön an alle :)

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.