Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 3 lut 2026, o 17:54


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 19 ] 
Autor Wiadomość
PostNapisane: 8 lis 2015, o 09:53 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Tworzę sobie minutnik w celach edukacyjnych, lecz napotkałem pewien problem którego jakoś nie potrafię przeskoczyć.

1. Napisałem sobie funkcję która jest odpowiedzialna za wybieranie liczby minut i koncepcja jest taka, aby po wybraniu tej liczby przekazać ją do funkcji minutnik, która już zlicza do zera. Jednak program zatrzymuje się na wybieraniu liczb i dalej nie rusza (delaya dałem po to aby był czas na wprowadzenie danych - tymczasowo zamiast przycisku start).
2. Jeśli wywołam funkcję minuty ale wpiszę np tak minuty(15); to owszem ta liczba zostaje przekazana do funkcji minuty, ale nie zmniejsza się . Doradźcie coś bo już nie mam pomysłu.

main.c

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


funkcje.c

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 10:07 
Offline
Użytkownik

Dołączył(a): 05 lut 2014
Posty: 252
Lokalizacja: obok Częstochowy
Pomógł: 14

:shock:
Może wyprowadź wywołania tych funkcji do pętli głównej w main.c.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 10:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Chodzi o deklaracje ? Bo jeśli tak to sa one w pliku def.h

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 10:45 
Offline
Użytkownik

Dołączył(a): 05 lut 2014
Posty: 252
Lokalizacja: obok Częstochowy
Pomógł: 14

Mam na myśli wywoływanie funkcji. Na początek chociaż samą funkcję minutnik(); wrzuć do while(1) w pliku main.c.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 11:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Wrzuciłem funkcję minutnik do maina, lecz teraz nie działa wybieranie minut, a sam minutnik zlicza tylko sekundy. Nie wiem, moze coś źle z funkcjami robię ?

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 12:21 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

Tak w ogóle to powinieneś zastanowić się jak właściwie ma działać Twój program.
I porównać to z tym jak działa w tej chwili.
Musisz pamiętać o tym, że procesor jest bardzo szybki ;-)
Wybieranie czasu minutnika nie działało i nadal nie działa.
a Tobie tylko się wydawało, że coś ustawiasz.
Na początku programu wywołujesz funkcję do ustawiania minut, ale...
musiałbyś już mieć w tym momencie wciśnięty przycisk, żeby cokolwiek się stało.
Nim zdążysz go wcisnąć program już z powrotem jest w głównym "nurcie" i odpoczywa
sobie aż minie delay.
Kolejny problem to funkcji odliczania do zera.
Jak wrzuciłeś do głównej pętli to jasne jest, że za każdym razem niezależnie jaki parametr
prześlesz będzie liczył tylko te "sekundy".


Autor postu otrzymał pochwałę

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 lis 2015, o 14:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Dzięki MirkoT :) Dzięki Twoim wskazówkom udało mi się rozwiązać ten problem, funkcje ładnie działają. Dużo mi pomógł symulator Atmel Studio. We funkcji ustaw_czas dodałem obsługę przycisku start/stop, i dzięki sprawdzeniu warunku funkcja poprawnie zwraca ustawioną wartość :)

Tak wygląda teraz kod :

main.c:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


funkcje.c

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 lis 2015, o 12:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

A takie pytanie: jak zrobić żeby zmienna którą przekazuję do funkcji była od razu pomniejszona o jeden ? Wybieram liczbę minut załóżmy 13 naciskam przycisk start, program przechodzi do wykonywania funkcji minutnik, ale zlicza od 13:59 zamiast 12:59 . Próbowałem zrobić to tak :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i w pętli głównej main :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W obu przypadkach zmienna minuty zmniejsza się o jeden dopiero wtedy jak wykona się instrukcja for, a przecież przed funkcją for zmniejszam tą zmienną.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 lis 2015, o 14:47 
Offline
Użytkownik

Dołączył(a): 10 lip 2015
Posty: 334
Pomógł: 32

A próbowałeś użyć predekrementacji? Chodzi mi o "--sekundy".



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 lis 2015, o 15:31 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

HomoChemicus napisał(a):
A próbowałeś użyć predekrementacji? Chodzi mi o "--sekundy".

To akurat nic nie pomoże ze względu na budowę funkcji odliczającej napisanej przez kolegę.

Jeszcze raz trzeba przemyśleć algorytm. ;-)
Trzeba po prostu wyświetlanie minut wywoływać po każdej zmianie zmiennej min ;-)

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 lis 2015, o 23:32 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Wydaje mi się że w tym warunku jest wywoływana funkcja wyświetlania minut po każdej zmianie zmiennej min, chyba że źle rozumuję :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 lis 2015, o 08:18 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

owszem tu jest.
Ale na początku funkcji minutnik nie masz ;-)
A tam przecież też dekrementujesz zmienną min, prawda?

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 lis 2015, o 18:18 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Dodałem na początku funkcji minutnik wyświetlanie zmiennej i od razu zaskoczyło, nie myślałem że to takie proste :)
Bawiłem się trochę kodem i próbowałem ogarnąć obsługę przycisku w przerwaniu, który odpowiada za zatrzymywanie i kontynuowanie odliczania. Przycisk działa, ale tylko czasami. W sensie że muszę parę razy nacisnąć żeby się zatrzymał albo wznowił, a za innym razem od razu zaskoczy. Mam świadomość, że to pewnie chodzi o drgania styków. Czytałem bloga Mirka i zastosowałem w przerwaniu jeden z kodów który jest w tym artykule , ale własnie ten kod jakoś mi nie działa.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jedynie co zmieniłem w mirkowym kodzie to sposób zapisu warunków, ponieważ zastosowałem makra:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Jeszcze jedno co mnie nurtuje, to jak mógłbym zrealizować zmianę wartości minut w czasie gdy uruchomiony jest timer? Próbowałem to zrobić też w przerwaniu. Powołałem zmienną zmienną "x" z atrybutem volatile i w zależności który klawisz był wciśnięty dekrementowało lub inkrementowało zmienną "x" o 1. Nie działało to w ogóle. Może dlatego, że zmienna "x" jest użyta w funkcji "minuty" ? Jesli to jest problemem to jak zrobić, żeby przekazywać do funkcji wartośc która uległa zmianie w przerwaniu ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lis 2015, o 00:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Pomoże ktoś ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lis 2015, o 06:43 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sie 2013
Posty: 3797
Lokalizacja: Grudziądz
Pomógł: 143

Kolego zobacz masz w kodzie delay ms 100 i 250 i 500 w różnych sytuacjach blokujesz prace uC przez delay nie robi on nic innego jak jest zawieszony na zadany czas. Wlasnie przez te delaye raz ci przycisk zadziala a raz nie.

Przy drganiach stykow widzialbys jak przycisk np zatrzymuje i startuje czas i dzialal by on zawsze. A tak przez te delay musisz sie wstrzelic z przyciskiem wtedy gdy uC nie jestczawieszony.

Postaraj sie zrobic timer programowy by zastapic te delaye a wtedy wszystko zacznie ci pieknie dzialac.

Rozpocznij prace nad timer i pytaj.

Namazane ze smarta.

_________________
Usługi druku przestrzennego - www.drumik.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lis 2015, o 14:15 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

Obsługę przycisku umieściłeś w przerwaniu. Wg mnie to nie jest dobry pomysł. Tzn. nie w tej formie.
Najpierw powinieneś zrozumieć jak działa ta obsługa przycisku i dlaczego umieszczenie jej w przerwaniu, wywoływanym co kilka ms, nie jest dobrym pomysłem.

Jeśli przycisk jest wciśnięty to zostaje spełniony ten warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Program zrobi to co ma zrobić i ustawia zmienną key_lock na jeden.

Po puszczeniu przycisku, z każdym przerwaniem, zmienna jest zwiększana o jeden w tej linii
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

W tym czasie przycisk jest nieaktywny. Aby znów był aktywny zmienna key_lock musi osiągnąć wartość równą zero. Jeśli przerwanie było by wywoływane np. co 4ms to przycisk będzie nieaktywny na czas ok. jednej sekundy.

Poza tym zastanawiam się jaką częstotliwością taktujesz procka. Bo jeśli jest to np. 8MHz to przerwania wywoływane są z częstotliwością ponad 2,5kHz. Jest ci aż tyle potrzebne do multipleksowania? No chyba, że w ustawieniach Timera2 OCR2 miało mieć wartość 38 a nie 3.

W programie masz delaye, pętle while, pętle for, których są delaye. To wszystko sprawia, że cała pętla główna działa w sposób blokujący. Jedynie przerwanie działa w swoim rytmie bo mimo, że procek co chwilę "wisi" w jakimś delayu przerwanie i tak się wykonuje.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2015, o 16:49 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 kwi 2013
Posty: 67
Lokalizacja: Rzeszów
Pomógł: 0

Dziękuję za odpowiedzi:) No chyba czas pożegnać się z delayami i ogarnąc obsługe timerów programowych. Procka taktuję częstotliwością 1 MHz, więc przerwanie wykonuje się z częstotliwością ~200 Hz . No i właśnie ja, myślałem że przerwania działają w inny sposób, w sensie że najpierw wykona się kod (obsługa przycisku ), i dopiero po wykonaniu wychodzi z przerwania i kontynuuje program. Nie wiem czy dobrze rozumiem, ale w przerwaniu jedna instrukcja wykonuje się tak jakby co jeden impuls zegarowy ? Coś w tym stylu: impuls -> instrukcja, impuls -> instrukcja , i dotąd aż ilość impulsów osiągnie wartość wpisaną do OCR (uwzględniając preskaler) ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2015, o 19:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sie 2013
Posty: 3797
Lokalizacja: Grudziądz
Pomógł: 143

Kolego potraktuj go kwarcem 8 MHz albo 16MHz albo jakimś innym ale 1MHz to trochę mało :)

Prosta obsługa timera programowego:

w timerze ustawiasz sobie zmienną

np uint8_t licz;

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



nad int main void deklarujesz sobie zmienną

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


a w pętli głównej używasz if'a:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Zakładając że twój tick timera to 10 ms czyli czas_led_tog zmniejszy swoją wartość co 10 ms a że ma 10 ticków to 10 x 10 to 100 ms co oznacza że co 100 milisekund led ci mrugnie :) i jest niezależny od reszty programu brak delay brak zawieszania się procesora ...

teraz postaraj się tę podpowiedz przenieść na twój kod i zastąpić delay'e timerem programowym

następnie spróbuj użyć timera do przycisku ... po prostu pozbądź się delay;

_________________
Usługi druku przestrzennego - www.drumik.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2015, o 23:06 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

Krystek napisał(a):
No i właśnie ja, myślałem że przerwania działają w inny sposób, w sensie że najpierw wykona się kod (obsługa przycisku ), i dopiero po wykonaniu wychodzi z przerwania i kontynuuje program. Nie wiem czy dobrze rozumiem, ale w przerwaniu jedna instrukcja wykonuje się tak jakby co jeden impuls zegarowy ? Coś w tym stylu: impuls -> instrukcja, impuls -> instrukcja , i dotąd aż ilość impulsów osiągnie wartość wpisaną do OCR (uwzględniając preskaler) ?

Troszkę inaczej to działa niż myślisz.
Licznik TCNT2 zlicza impulsy taktujące procesor podzielone przez dzielnik preskalera. Co 1024 impulsy taktujące zwiększana jest wartość licznika TCNT2. Jeśli wartość licznika zrówna się z wartością OCR2 to zostaje ustawiona flaga przerwania Compare Match i procesor przechodzi do obsługi funkcji tego przerwania. Jednocześnie licznik TCNT2 zostaje wyzerowany i zaczyna liczyć od początku.
Po wejściu do funkcji obsługi przerwania program przejdzie od początku funkcji do jej końca. A nie co przerwanie jedna instrukcja.

Jak to będzie wyglądało w przypadku obsługi przycisku? Jeśli przycisk jest wciśnięty to w trakcie pierwszego przerwania wykona się ten fragment kodu
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Po puszczeniu przycisku przez 255 przerwań będzie się wykonywać ten fragment
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

I przez ten czas (około 1s) pierwszy if a tym samym przycisk będą nieaktywne.

Tak jak pisałem wcześniej obsługę przycisku można zrobić w przerwaniu ale nie tym sposobem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 19 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO