Skocz do zawartości

[C] Odliczanie czasu inaczej niż _delay_x()


Pomocna odpowiedź

Witam, mam w programie mojego robota kawałek który musi zwiększać wartość zmiennej co 1 sekunde od 0 do 5, gdy dojdzie do 5 wykonać kawałek programu i przypisać tej zmiennej 0 (dalej podlicza). Działa poprzez takie coś jak

int i=0;
i++;
_delay_ms(1000);
if(i==5){
cośtam;
i=0;
}

lecz ten delay sprawia, że cały program ma przerwę na 1 sekundę co chwilę.. wie ktoś jak to rozwiązać? timerem? aktualnie używam timera do regulacji PWM rotacji silników, wrzuciłby ktoś kawałek programu, żeby pokazać jakie inicjacje itp użyć? Dzięki z góry!

Link to post
Share on other sites

Inaczej co chcesz tym osiągnąć ? Bo zasadniczo każde opóźnienie, ma za zadanie zatrzymać program w danym miejscu na jakiś czas.

Pewnym, wyjątkiem jest sytuacja w której podczas takiego czasowego zatrzymania, musimy coś sprawdzać w tle, lub np. przetwarzamy spore ilości danych, i między kolejnymi cyklami ich zbierania w czasie wykonujemy już jakieś wstępne obliczenia.

Ogólnie nazwijmy to dynamiczny Delay, stosuje się w systemach czasu rzeczywistego (system operacyjny), lub wielowątkowych, gdzie chcemy wykonywać "rownolegle" kilka wątków/operacji.

W mini sumo mogłoby to mieć zastosowanie podczas procedury STARTu, kiedy odmierzając 5 sek do startu, skanujesz już otocznie robota, próbując określić pozycje przeciwnika, ale to i tak mocno teoria na wyrost.

jeżeli chcesz tylko odmierzać czas w systemie, to dowolny Timer, który będzie ci zgłaszał przerwania, co 1ms. Po 1000 przerwań mas 1 sek. Proponuję ci 1ms jako podstawę, bo to wygodna jednostka bazowa, do wielu procesów. Przerwanie 1000 razy na sekundę to nie jest dla procesora jakaś straszna wartość. No chyba że wystarczy ci 1/100 sekundy, czyli 10ms.

Link to post
Share on other sites

ogolnie jest taka sprawa ze mam cos z wyswietlaczem, ze jak jest na nim menu glowne i klikne np kalibracje, to w puste miejsca sie pojawiaja te litery ktore byly w menu glownym albo jak wartosc odczytu jest >1000 a potem spadnie ponizej 1000 to pokazuje potem np 9842 i musze co pare sekund wykonywac program ktory lewa i gorna linijke wyswietlacza zastepuje " " (8 odstepow, mam 2x8 lcd), i wtedy jest taki ulamkowy refresh i te nadwyzki znikaja

Link to post
Share on other sites

Wyświetlacz jest zapewne sprawny a problem tkwi w programie.Co do tego odczytu, to po wysłaniu liczby na wyświetlacz wyślij od razu pusty znak i to załatwi tą sprawę a co do tych literek to pokaż program.

Link to post
Share on other sites

z programu nie wynika nic złego w sumie:


if(bit_is_clear(PINC,7)){
m++;
_delay_ms(250);
}
if(bit_is_clear(PINC,6)){
m--;
_delay_ms(250);
}

if(m==0){
LCD_GoTo(0, 0);
LCD_WriteText("Kalibruj");
LCD_GoTo(0, 1);
LCD_WriteText("Wcisnij>");
}

if(m==1){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS1");
LCD_GoTo(2, 1);
LCD_WriteText(trans1);
}
if(m==2){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS2");
LCD_GoTo(2, 1);
LCD_WriteText(trans2);
}
if(m==3){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS3");
LCD_GoTo(2, 1);
LCD_WriteText(trans3);
}
if(m==4){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS4");
LCD_GoTo(2, 1);
LCD_WriteText(trans4);
}
if(m==5){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS5");
LCD_GoTo(2, 1);
LCD_WriteText(trans5);
}
if(m==6){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS6");
LCD_GoTo(2, 1);
LCD_WriteText(trans6);
}
if(m==7){
LCD_GoTo(0, 0);
LCD_WriteText("TRANS7");
LCD_GoTo(2, 1);
LCD_WriteText(trans7);
}
if(m==8){
LCD_GoTo(0, 0);
LCD_WriteText("DALMIERZ");
LCD_GoTo(2, 1);
LCD_WriteText(dalmierz);
}
if(m==9){
LCD_GoTo(0,0);
LCD_WriteText("Dal:");
LCD_GoTo(4, 0);
LCD_WriteText(dalmierz);
	if(t1>=700){
	LCD_GoTo(0, 1);
	LCD_WriteText("H");
	}
	else if(t1<700){
	LCD_GoTo(0, 1);
	LCD_WriteText("L");
	}
	if(t2>=500){
	LCD_GoTo(1, 1);
	LCD_WriteText("H");
	}
	else if(t2<500){
	LCD_GoTo(1, 1);
	LCD_WriteText("L");
	}
	if(t3>=440){
	LCD_GoTo(2, 1);
	LCD_WriteText("H");
	}
	else if(t3<440){
	LCD_GoTo(2, 1);
	LCD_WriteText("L");
	}
	if(t4>=600){
	LCD_GoTo(3, 1);
	LCD_WriteText("H");
	}
	else if(t4<600){
	LCD_GoTo(3, 1);
	LCD_WriteText("L");
	}
	if(t5>=520){
	LCD_GoTo(4, 1);
	LCD_WriteText("H");
	}
	else if(t5<520){
	LCD_GoTo(4, 1);
	LCD_WriteText("L");
	}
	if(t6>=480){
	LCD_GoTo(5, 1);
	LCD_WriteText("H");
	}
	else if(t6<480){
	LCD_GoTo(5, 1);
	LCD_WriteText("L");
	}
	if(t7>=500){
	LCD_GoTo(6, 1);
	LCD_WriteText("H");
	}
	else if(t7<500){
	LCD_GoTo(6, 1);
	LCD_WriteText("L");
	}
}

       if(m>=10) m=0;
if(m<0) m=9;

i kawałek co odświeża z delayem:

if(k==30){
LCD_GoTo(0, 0);
LCD_WriteText("        ");
LCD_GoTo(0, 1);
LCD_WriteText("        ");
k=0;
}
k++;
_delay_ms(50);
Link to post
Share on other sites
if(bit_is_clear(PINC,7)){
   m++;
   _delay_ms(250);
   }
if(bit_is_clear(PINC,6)){
   m--;
   _delay_ms(250);
   }

if(m==0){
   LCD_GoTo(0, 0);
   LCD_WriteText("Kalibruj");
   LCD_GoTo(0, 1);
   LCD_WriteText("Wcisnij>");
   }

if(m==1){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS1  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans1);
   }
   if(m==2){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS2  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans2);
   }
   if(m==3){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS3  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans3);
   }
   if(m==4){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS4  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans4);
   }
   if(m==5){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS5  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans5);
   }
   if(m==6){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS6  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans6);
   }
   if(m==7){
   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS7  ");
   LCD_GoTo(2, 1);
   LCD_WriteText(trans7);
   }
   if(m==8){
   LCD_GoTo(0, 0);
   LCD_WriteText("DALMIERZ");
   LCD_GoTo(2, 1);
   LCD_WriteText(dalmierz);
   }
   if(m==9){
   LCD_GoTo(0,0);
   LCD_WriteText("Dal:    ");
   LCD_GoTo(4, 0);
   LCD_WriteText(dalmierz);
       if(t1>=700){
       LCD_GoTo(0, 1);
       LCD_WriteText("H");
       }
       else if(t1<700){
       LCD_GoTo(0, 1);
       LCD_WriteText("L");
       }
       if(t2>=500){
       LCD_GoTo(1, 1);
       LCD_WriteText("H");
       }
       else if(t2<500){
       LCD_GoTo(1, 1);
       LCD_WriteText("L");
       }
       if(t3>=440){
       LCD_GoTo(2, 1);
       LCD_WriteText("H");
       }
       else if(t3<440){
       LCD_GoTo(2, 1);
       LCD_WriteText("L");
       }
       if(t4>=600){
       LCD_GoTo(3, 1);
       LCD_WriteText("H");
       }
       else if(t4<600){
       LCD_GoTo(3, 1);
       LCD_WriteText("L");
       }
       if(t5>=520){
       LCD_GoTo(4, 1);
       LCD_WriteText("H");
       }
       else if(t5<520){
       LCD_GoTo(4, 1);
       LCD_WriteText("L");
       }
       if(t6>=480){
       LCD_GoTo(5, 1);
       LCD_WriteText("H");
       }
       else if(t6<480){
       LCD_GoTo(5, 1);
       LCD_WriteText("L");
       }
       if(t7>=500){
       LCD_GoTo(6, 1);
       LCD_WriteText("H");
       }
       else if(t7<500){
       LCD_GoTo(6, 1);
       LCD_WriteText("L");
       }
   LCD_GoTo(7, 1); //kasuje ostatnie miejsce 
   LCD_WriteText(" ");
   }

       if(m>=10) m=0;
   if(m<0) m=9; 

Poprawiłem z grubsza, te argumenty bez "" w funkcji LCD_WriteText() to pewnie wcześniej zdefiniowane tablice więc musisz poprawić je sam.

Musisz sam czyścić wyświetlacz jeśli nie nadpiszesz całej linijki.

Np było napisane:

   LCD_GoTo(0, 0);
   LCD_WriteText("Kalibruj"); 

a następnie

   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS1"); 

to powstanie coś jak TRANS1uj.

Wystarczy że każdy wyraz uzupełnisz pustymi miejscami do 8 czyli zamiast tego ma być:

   LCD_GoTo(0, 0);
   LCD_WriteText("TRANS1  "); 
  • Lubię! 1
Link to post
Share on other sites

Można rozwiązać to jak kolega Propaganja proponuje ale wprowadzanie stringów o większej niż wymagana długość dosyć skutecznie wcina pamięć. Fakt, że przy długości 8 znaków nie jest źle, ale co jeśli by to był wyświetlacz 2x40? Zastanów się nad jakaś konkretną obsługą wyświetlacza. Nie widziałem jak wyglądają u ciebie funkcje do obsługi wyświetlacza, ale dobrym rozwiązaniem jest rysowanie w bufforze a potem dopiero przeniesienie to raz na jakiś czas na wyświetlacz. Dużo w takim wypadku zyskujesz ponieważ operacje na bufforze w pamięci są znacznie szybsze niż wypisywanie tego od razu na wyświetlacz. Dodatkowo tylko w jednym miejscu będziesz miał obsługę wyświetlacza, a sekcja będzie miała prawie zawsze taki sam czas wykonywania. Takie rozwiązanie daje dużo możliwości o czym pisze Pan mirekk36 na swoim blogu.

Link to post
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

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.