-
        

Ergebnis 1 bis 10 von 10

Thema: Schleifen parallel abarbeiten ???

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    18.08.2005
    Beiträge
    86

    Schleifen parallel abarbeiten ???

    Anzeige

    Hallo zusammen, noch eine Frage ;o) zum parallelen Abarbeiten von Schleifen.

    Bei mir liegt folgende Struktur vor:

    schleife(immer wiederholend)
    {
    schleife_A()...

    schleife_B()
    }

    Wie macht man es, das die Schleifen A und B parallel durchgearbeitet werden können.

    Danke und Grüße

    popi

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    nimm 2 micro......

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Was passiert denn in den beiden Schleifen? Generell ist ein AVR natürlich kein Parallelrechner, aber ein rudimentäres Multitasking-System ließe sich wohl verwirklichen. Sind in den beiden Schleifen Warteschleifen enthalten? Dann solltest du diese entfernen und stattdessen die Timer nutzen und während der Pausen die zweite Aufgabe erledigen lassen....

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    18.08.2005
    Beiträge
    86
    Das klingt gut... es sind tatsächlich Warteschleifen drin...

    Aber wie soll ich sie entfernen.

    Mein Programm nutzt alle Timer um mehrere LEDs anzusteuern.


    Hier der code (oder ein Teil daraus):

    DDRB = (1<< DDB4) | (1<< DDB5) | (1<< DDB7) | (1<< DDB6);
    PORTB = (1<< PB4) | (1<< PB5) | (1<< PB7) | (1<< PB6);
    OCR0,OCR2,OCR1A,OCR1B = 0x00;
    TCCR0 = (1 << WGM00) | (1<< COM01) | (1<< CS00);
    TCCR2 = (1 << WGM20) | (1<< COM21) | (1<< CS20);
    TCCR1A = (1 << WGM10) | (1 << WGM11) | (1<< COM1A1) | (1<< COM1B1);
    TCCR1B = (1<< CS10);

    while(x==2)
    {
    while(OCR0 <= 0x60) {for (i=0;i<300;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
    while(OCR2 <= 0x40) {for (i=0;i<300;i++) asm volatile("NOP"); OCR2 = OCR2 + 1;}
    while(OCR1A <= 0xA0) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1A = OCR1A + 1;}
    while(OCR0 >= 0x40) {for (i=0;i<100;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}
    while(OCR2 >= 0x10) {for (i=0;i<100;i++) asm volatile("NOP"); OCR2 = OCR2 - 1;}
    while(OCR1A >= 0x10) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1A = OCR1A - 1;}


    while(OCR0 <= 0xCF) {for (i=0;i<200;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
    while(OCR1B <= 0xA0) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1B = OCR1B + 1;}
    while(OCR1A <= 0xA0) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1A = OCR1A + 1;}
    while(OCR0 >= 0x10) {for (i=0;i<100;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}
    while(OCR1B <= 0x05) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1B = OCR1B - 1;}
    while(OCR1A >= 0x10) {for (i=0;i<100;i++) asm volatile("NOP"); OCR1A = OCR1A - 1;}


    Danke und Grüße

    popi

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Kannst du das Konzept, das dahintersteht, mal in ein paar Worten erklären? Auf den ersten Blick scheint mir die Methode ziemlich abstrus... du zählst die Compare-Register hoch, bis sie einen bestimmten Wert erreicht haben? Was willst du damit ansteuern?

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    18.08.2005
    Beiträge
    86
    Das mag wirklich wirre aussehen, hast recht. (ist es auch) )

    Aber ich habe erst gestern richtig angefangen, ein Programm in einen Controller zu schieben und dieses zu starten.

    Der Timer 0 und 2 steuern eine rot/gelb Led an, die aussieht, als würde ein Streichholz brennen. Daher diese wirren Additionen und Subtraktionen.

    Timer 1 Ausgang A und B sollen das gleiche tun, da bin ich aber noch dran, denn das mit dem B-Kanal funktioniert noch nicht wirklich.

    Grüße

    popi

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Mal nen anderer Ansatz für dein Problem: Einen Timer auf ein möglichst kurzes Intervall einstellen, und in der ISR entweder über genügend lange (und verschiedenlange) Tabellen oder mit Zufallszahlen die PWM-Ausgänge (oder gleich Software-PWM, wenn die Kanäle nicht reichen) ansteuern...

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    18.08.2005
    Beiträge
    86
    Uwe, ich muss bis nächste Woche für den Schulabschluss ein Programm fertigkriegen und ganz davon zu schweigen, das es unmöglich ist (aber ich muss es schafen) und ich leider nicht wirklich viel Ahnung habe, was ich hier tue, würdest Du mir mit kleinen Routinen helfen können.
    Ich würde Dir auch was bezahlen, hauptsache ich kriege keine 5.

    Das wäre echt nett!

    Was sagst Du dazu?

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Du kannst doch die Schleife über alle OCRs machen und jeder eine eigene Variable verpassen, die zählt, ob der Wert verändert werden soll.

    Also, so könnte man das machen, indem man die inneren Schleife auflöst. Du kannst dir jetzt das Hirn zerrauchen und überlegen, was das alles soll und was es tut und das Zeug kommentieren. Denn wenn du was abgibst, das du nicht blickst, gibt's bestimmt auch ne 5

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    
    #define NUM_OCRS 2
    
    typedef struct
    {
    	uint8_t countdown;
    	void volatile * const preg;
    	const uint8_t size;
    	uint16_t zielwert;
    } ocr_count_t;
    
    
    void loop();
    void tick (ocr_count_t*);
    
    ocr_count_t ocr_counters[NUM_OCRS] =
    {
    	{ 0, &OCR2,  sizeof (OCR2) },
    	{ 0, &OCR1A, sizeof (OCR1A) }
    };
    
    
    void tick (ocr_count_t * poc)
    {
    	if (poc->countdown != 0)
    	{
    		poc->countdown--;
    		return;
    	}
    	
    	poc->countdown = rand();
    		
    	if (1 == poc->size)
    	{
    		uint8_t * pocr = (uint8_t*) poc->preg;
    		uint8_t ocr = * pocr;
    		uint8_t ziel = poc->zielwert;
    		
    		if (ocr == ziel)
    		{
    			ziel = rand();
    			poc->zielwert = ziel;
    		}
    			
    		if (ocr < ziel)					ocr++;
    		if (ocr > ziel)					ocr--;
    		
    		*pocr = ocr;
    	}
    	
    	if (2 == poc->size)
    	{
    		uint16_t volatile * pocr = (uint16_t volatile *) poc->preg;
    		uint16_t ocr = * pocr;
    		uint16_t ziel = poc->zielwert;
    		
    		if (ocr == ziel)
    		{
    			ziel = rand();
    			poc->zielwert = ziel;
    		}
    			
    		if (ocr < ziel)					ocr++;
    		if (ocr > ziel)					ocr--;
    		
    		*pocr = ocr;
    	}
    }
    
    void loop()
    {
    	uint8_t i;
    	
    	while (1)
    	{
    		for (i=0; i < sizeof (ocr_counters) / sizeof (ocr_count_t); i++)
    			tick (& ocr_counters[i]);
    
    		_delay_loop_1 (42);
    	}
    }
    Disclaimer: none. Sue me.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    18.08.2005
    Beiträge
    86
    ja, Du hast rechts... nur durch probieren kann man lernen...

    Bin ja dabei und lerne durch Eure Beispiele.
    Wenn man den Code nicht selbst programmiert, blickt man nicht durch, wie ich z.B. bei Deinem Beispiel ;o)

    Aber habe ihn kopiert und in meine "Formelsammlung" unter dem Punkt "ungeklärt" abgelegt...

    Ich bleib erst mal bei den Zeilen, die ich erstellt habe, denn durch eine vermischung der PWM Schleifen untereinander hab ich ein zufriedenes Ergebniss erzielt. Natürlich muss man justieren, dachte ich, und erhöhte den internen Quarz von 4 auf 8 MhZ... und es klappte ;o)

    Als nächstes muss ich das Empfangen von Daten über UART auswerten... Also in den EEPROM packen nach dem Empfangen.

    Da komme ich bestimmt noch mal auf Dich/Euch zu, vielleicht schon morgen ;o)

    Grüße

    popi

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •