mikrocontroller.net

Forum: Compiler & IDEs Funktion gleichzeit ausführen


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

#include <avr/io.h>          
#include <avr/delay.h>
#include <stdlib.h>


void delay_ms(int ms)
{
  int t;
  for(t=0; t<=ms; t++)
  _delay_ms(1);
}


void startpin_B(int pid)
{
  PORTB   &= (1<<pid);                     
  delay_ms(10);
  PORTB  |=  (1<<pid);
  delay_ms(10);
  PORTB  &= ~(1<<pid);
  delay_ms(15);
  PORTB  |=  (1<<pid);
  delay_ms(20);
  PORTB  &= ~(1<<pid);
  delay_ms(50);
  PORTB  |=  (1<<pid);
  delay_ms(20);
  PORTB  &= ~(1<<pid);
  delay_ms(100);
  PORTB  |=  (1<<pid);

}
 
int main (void) {            
 

 
 
  DDRB    =  0xFF;                      
  startpin_B(PB0);
  startpin_B(PB1);
  startpin_B(PB5);

 
   while(1) {                
    
  
  
   }                         
 
   return 0;                 
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Valentin Buck (nitnelav) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst einfach mehrere Portpins gleichzeitig zuweisen.
Also statt
void startpin_B(int pid)
{
  PORTB   |= (1<<pid);                     
  delay_ms(10);


einfach

void startpin_B(uint8_t pid1, uint8_t pid2)
{
  PORTB   |= (1<<pid1) | (1<<pid2);                     
  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

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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.

#include <avr/io.h>          
#include <avr/delay.h>
#include <stdlib.h>

int main (void) {            
  uint8_t cnt=0;
  uint8_t data[8] = {0xFF, 0x01, 0x04, 0x5A, 0x66, 0xAB, 0x11, 0xCC};

  DDRB    =  0xFF;                      
 
   while(1) {
     PORTB = data[cnt];
     cnt++;
     if (cnt == 8) cnt=0;               
     _delay_ms(10);
   }                         
 
   return 0;                 
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.