Skocz do zawartości

[C] Odliczanie czasu inaczej niż _delay_x()


ElectroBeginner

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 do komentarza
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 do komentarza
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 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

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 do komentarza
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 do komentarza
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 do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.