Skocz do zawartości

Wielozadaniowość w C


Krawi92

Pomocna odpowiedź

Witam, chciałbym aby ktoś podpowiedział, jak jako początkujący podejść do tego tematu, wykonywania kilku procesów w tle. Np: robię sobie prosty wiatrak,sterowany PWM, może kręcić się wolno,srednio,maksymalnie,wlaczyc,wylaczyc. Zrobiłem to na klawiszach i zwykłej instrukcji IF. Chciałem, żeby servo mi też go obracało. No i tu się zaczyna właśnie problem.  Wiem, że temat bardzo często wałkowany, czytam że takie rzeczy robi się w przerwaniach itp. Piszą też o maszynach stanu ale trochę ciężko mi przejść przez ten gąszcz informacji.  Pytanie, czy na tak poczatkowym etapie jestem w stanie to wg zrobić.

Link do komentarza
Share on other sites

Można to zrobić przy użyciu timera:

#include <avr/io.h>
#include <avr/interrupt.h>
  
  volatile uint8_t timer1;
  volatile uint8_t timer2;
  volatile uint8_t timer3;
  
int main(void){
 //konfiguracja timera
  TCCR0 |= (1<<WGM01);//ctc
  TCCR0 |= (1<<CS00)|(1<<CS00);// start t/1024
  OCR0 = 40;
  TIMSK |= (1<<OCIE0);
  
  sei();
  

  
for(;;){
  if(!timer1){
    //zadania
  timer1 = 100;
  }
  
  if(!timer2){
  //zadania
  timer2 = 50;
  }
  
  if(!timer3){
  
    timer3 = 10;
  }
  
}
}

// Przerwanie: zegar systemu

ISR(TIMER0_COMP_VECT){
if(timer1) timer1--;
if(timer2) timer2--;
if(timer3) timer3--;
}

Potem zależnie od interwałów wykonywać zadania, musisz pamiętać aby przy takim podejściu rozważnie używać funkcji _delay_

Edytowano przez _LM_
  • Lubię! 1
Link do komentarza
Share on other sites

I tak np: aby coś zrobić gdy klawisz naciśnięty, potrzebujesz kolejnej zmiennej

uint8_t czasSW;

później już w pętli np dla timera3 sprawdzasz

  if(!timer3){
  
    if(!SWPIN && licznikSw < 6){
    	licznikSw ++;
      if(licznikSw == 4)
        // tu zadanie po naciśnięciu
    
    } else if(SWPIN) licznikSw = 0; // przygotowanie do nast naciśnięcia
     timer3 = 10;
  }   
    

Oczywiście musisz sobie przygotować funkcje przycisków itd... W ten sposób możesz dzielić sobie program na kolejne zadania, np wyświetlanie czegoś na lcd, czy kręcenie serwem. Następnym naturalnym krokiem jest wykorzystanie wskaźników na funkcje, dzięki czemu można je przechowywać w tablicach co drastycznie zmniejsza ilość if - ów w programie 😉 ale na to już potrzebowałbym nieco czasu aby przygotować przykład. Myślę że teraz byłby dobry moment abyś pokazał swój program, możemy spróbować coś z nim zrobić.

Edytowano przez _LM_
Link do komentarza
Share on other sites

2 godziny temu, Krawi92 napisał:

trochę ciężko mi przejść przez ten gąszcz informacji.

Wielki mi gąszcz, trzy krzaczki na krzyż i to bez kolców

Tutaj masz bardzo ładny przykład maszyny stanów - pewnie przypadkiem pominąłeś ucząc się z kursu Arduino, prawda?

 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Wstawiam wersję dla AtMegi328 - sprawdzoną działającą, możesz sprawdzić podłączając do portu C 1...3 diody led a do PB1 przycisk.

#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t timer1,timer2,timer3;

uint8_t swCount;

int main(void){

	DDRC|= (1<<PC1)|(1<<PC2)|(1<<PC3); // wyjscia
	PORTB|=(1<<PB1); // przycisk


	TCCR0A |= (1 << WGM01);					// tryb CTC
	TCCR0B |= (1 << CS02) | (1 << CS00);	// preskaler = 1024
	OCR0A = (F_CPU / 1024UL) / 100UL;		// 100ms - 100Hz
	TIMSK0 |= (1 << OCIE0A);				// przerwanie Compare Match
		// przerwanie Compare Match
sei();
	for(;;){

		if(!timer1){ // proces 1
			PORTC^= (1<<PC1);
			timer1 = 200;
		}



		
		
		if(!timer2){ // proces 2
			PORTC^= (1<<PC2);
			timer2 = 20;
		}

		
		
		if(!timer3){ // proces 3

			if(!(PINB & (1<<PB1)) && swCount < 30){

				if(++swCount == 5)PORTC^= (1<<PC3);

			}else if(PINB & (1 << PB1))swCount = 0;


			timer3 = 5;
		}


	}
}

ISR(TIMER0_COMPA_vect){

	if(timer1)timer1--;
	if(timer2)timer2--;
	if(timer3)timer3--;
}

 

Link do komentarza
Share on other sites

Jest taki temat na tym forum "Proste podświetlanie schodów na Arduino. Prośba o pomoc w stworzeniu programu".Jest tam mój program,w ramach pomocy, oraz załącznik a w nim genialna biblioteka Timers.Przeczytaj moje rozwiązanie i zastosuj.Poczytaj o bibliotece Timers a wszystko się stanie jasne.

Link do komentarza
Share on other sites

Albo jako tako spróbuj zrobić miganie 3 diodkami (każda w inny sposób) korzystając z _delay_ms(1) <to sugestia, bo z tego co pamiętam mówiłeś, że czytałeś książkę Kardasia, on nawet jakieś filmy na ten temat nagrywał i wspominał o takim ćwiczeniu>

Link do komentarza
Share on other sites

Jestem w trakcie czytania, narazie tak jednym tchem przeczytałem, żeby zobaczyc co i jak. Teraz od początku już na spokojnie czytam. Jeśli chodzi i miganie diodami to migalem 3 diodami niezależnie(1 w pętli głównej, dwie w oparciu o timery sprzętowe). 

Link do komentarza
Share on other sites

Jeszcze tylko dodam, że z jednego timera sprzętowego możesz zrobić (w przybliżeniu) dowolną liczbę timerów programowych czyt.
ustawiasz jakikolwiek timer na np. 1ms i w obsłudze przerwania:

if (timer1)
  timer1--;
if (timer2)
  timer2--;
...

a ile czasu mają odmierzać to ustawisz sobie już w pętli głównej zwykle

Edytowano przez BananWszyscy
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.