Funktion gleichzeit ausführen

Gast #2096178
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
}
#2096194
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.
Persönliche Seite #2096196
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
Gast #2096200
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.
#2096219
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
}
#2096222
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.

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