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



Teraz jest 28 gru 2024, o 06:53


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 
Autor Wiadomość
PostNapisane: 2 maja 2014, o 23:24 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 19 wrz 2013
Posty: 6
Pomógł: 0

Witam

Po kilku testowych programach zabrałem się za pisanie swojego pierwszego projektu, którym jest czasowy wyzwalacz aparatu (interwalometr). Układ działa na zasadzie zmiany stanu przekaźnika, który jest podłączony do wyzwalacza migawki.

Przedstawiony poniżej kod jest jedynie fragmentem całości, odpowiadającym jedynie za samo włączenie funkcji wykonywania zdjęć w określonych odstępach. Funkcja ta powinna się włączać/wyłączać przyciskiem podłączonym między pinem PB0 a masą i trwać aż do ponownego wciśnięcia przycisku.

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


Problem polega na tym, że w powyższym programie nie wiem jak wykorzystać funkcję przerwań. Program nie działa jak należy - wpada w nieskończoną pętlę i nie da się wyłączyć funkcji przekaźnik(). Jest to moje pierwsze spotkanie z przerwaniami.



Ostatnio edytowano 3 maja 2014, o 11:13 przez Julass, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 maja 2014, o 23:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 sty 2013
Posty: 426
Pomógł: 36

Dodaj:
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: 2 maja 2014, o 23:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 208
Lokalizacja: Kraków
Pomógł: 16

Tak na szybko, nie sprawdzałem całości
W funkcji przekaznik masz delaya. A nastepnie ladujesz te funcje do przerwania. Oj nie ładnie, wszystko się zaczyna sypać po takim czymś.

Obsługa klawiatury też jest zrobiona jak na mój gust dziwnie. Z częstotliwością obiegu pętli głównej sprawdzasz przycisk.
I jezeli byl przycisniety to odbrazu zerujesz pressed, by w kolejnej petli znowu ja ustawic.

Opowiedz nieco o tym przerwaniu, co je wywoluje?



Ostatnio edytowano 3 maja 2014, o 00:08 przez Juffre, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 00:06 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 19 wrz 2013
Posty: 6
Pomógł: 0

kaka0204 wydaję mi się, że w przypadku wejścia nie muszę tego robić. Ale dla bezpieczeństwa poprawię.

Juffre, też o tym myślałem. Jak już wspominałem jest to moje pierwsze spotkanie z przerwaniami i jeszcze nie bardzo potrafię z nich korzystać. Zaraz to usuwa, ale nie wiem co mogę wstawić w zamian :(

Początkowo chciałem w przerwaniu umieścić tylko pressed=!pressed, ale miałem problem z drganiem styków. Może cała koncepcja programu jest zła?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 00:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 sty 2013
Posty: 426
Pomógł: 36

Cytuj:
kaka0204 wydaję mi się, że w przypadku wejścia nie muszę tego robić. Ale dla bezpieczeństwa poprawię.

Musisz, musisz :) Jeżeli nie zadeklarujesz jaki stan będzie na danym pinie, to zapewne będzie tam stan nie ustalony (Hi-Z) ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 00:12 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 208
Lokalizacja: Kraków
Pomógł: 16

Ale co wywoluje to przerwanie bo nie rozumiem za bardzo tego. Jak masz to wrzuć schemat układu, będzie nam łatwiej pomóc.

Nie trzeba zerować bitu w rejestrze DDRB. Domyślnie po resecie bity w rejestrach DDRX mają wartość zero zatem są one wejściami. Jedyne o czym trzeba pamiętać to o włączeniu rezystorów podciągających, a za to odpowiadają rejestry PORTX.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 03:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 05 sie 2013
Posty: 1154
Lokalizacja: Lublin / Kraków
Pomógł: 72

Nie potrzebujesz zewnętrznego przerwania do obsługi przycisku.
Nawet jeśli ma przerwać działający proces.
Jeden Timer sprzętowy w trybie CTC + plus przerwanie z tego timera.
Dodatkowo uzyskasz bardzo dokładną podstawę czasu, co przy projekcie, o którym piszesz będzie dodatkowym atutem.
I ani razu nie użyjesz funkcji _delay_ms().

Obecnie sam projektuję dwa bardzo podobne urządzenia.

Na początek:
http://mirekk36.blogspot.com/2012/10/drgania-stykow-to-bajki-wiec-jak-to.html

Wszystkie 3 części. Obowiązkowo :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 12:26 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 19 wrz 2013
Posty: 6
Pomógł: 0

Układ jest pisany pod Atmega8. Chciałbym, aby jeden przycisk włączał i wyłączał pracę przekaźnika, którego praca polega na załączaniu migawki aparatu w określonych odstępach.

W omawianym przeze mnie przykładowym kodzie, przycisk podłączony miałem między masą a pinem PB0. Przekaźnik sterowany był z pinu PC5. Podanie stanu niskiego na ten pin wyzwalało migawkę. Do określenia czasu przerwania między kolejnym wyzwoleniem migawki korzystałem z _delay_ms. Wciśnięcie przycisku powodowało zmianę zmiennej pressed i uruchomienie przerwania INT0. Po uruchomienia przerwania, mimo ponownego wciśnięcia przycisku, program nie wracał do pętli głównej.


sq8dsr teraz rozumiem, że proponowane przeze mnie rozwiązanie było błędne. Rozumiem, że przycisk i przekaźnik mogą pozostać na swoich miejscach. Muszę tylko zmienić sposób pozbywania się drgań styków. Jaką zmianę powinien powodować wciśnięty przycisk? Załączać cały proces czy tak jak poprzednio zmieniać wartość zmiennej? Timer mam wykorzystać do opóźnień między kolejnymi wyzwoleniami migawki. Czy do tego celu mogę skorzystać z 16bitowego Timera1 w trybie CTC (Timer2 mam zarezerwowany do multipleksowania wyświetlacza)? Nie rozumiem jak powinienem skorzystać z przerwania? Co ma ono zawierać? Możesz napisać na jakiej zasadzie działa przerwanie w twoim projekcie?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 13:37 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 05 sie 2013
Posty: 1154
Lokalizacja: Lublin / Kraków
Pomógł: 72

Wystarczy Ci jeden timer :)
Zresztą 16 bitowy Timer1 marnotrawiony do takich rzeczy to grzech :P

Twój problem wynika z tzw. liniowego podejścia do programowania. Najpierw zadaj sobie pytanie co robi kluczowa dla Twojego projektu funkcja _delay_ms(). Ano nie robi ona NIC. To jest jej istotą. Robienie niczego. Zatrzymuje pracę procesora na określony czas. I tyle. Oczywiście wejście w przerwanie spowoduje wyskoczenie z tej funkcji i obsługę przerwania, ale po zakończeniu obsługi przerwania procesor wróci do wykonywania _delay_ms() czyli do nierobienia nic.
Nie da się w ten sposób zakończyć pracy tej funkcji. Procesor po obsłużeniu przerwania wraca w to miejsce na którym przerwał i nic na to nie można poradzić.

Trzeba podejść inaczej. Zerwać z liniowym pisaniem programu. Mechanizm wygląda tak:

1. Uruchamiamy sobie Timer sprzętowy w trybie CTC ( w AT8 najlepiej chyba będzie Timer2)
2. Włączamy przerwanie typu Compare dla tego timera. Tak by wykonywało się np. co 1 ms. (bit OCIE2x w rejetrze TIMSK)
3. Włączamy przerwania globalne - sei()
4. Deklarujemy sobie globalną zmienną typu uint16_t np. Timer_programowy i zaopatrujemy ją w specyfikator volatile
5. W procedurze obsługi przerwania zwiększamy te zmienną o jeden za każdym razem - Timer_programowy++;
6. W pętli głównej programu kontrolujemy "wątki" przez użycie warunku IF np.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czy widzisz co się teraz będzie działo?
Program startuje. Przelatuje przez pętlę główną while(1). I widzi warunek. Czy Timer_programowy jest równy 5000? Nie, oczywiście, że nie jest bo jest równy zero (zmienna globalna jest inicjalizowana zerem). Nie zapala więc diody.
Ale nagle nadchodzi przerwanie od Timera2 (sprzętowego). Co się dzieje w jego procedurze? Zwiększa się wartość zmiennej Timer_programowy. Teraz wynosi ona już 1. Ale warunek w pętli głównej dalej jest niespełniony.
Po wystąpieniu 5000 przerwań zmienna uzyska wartość 5000 i warunek się spełni. Dioda się zaświeci. A skoro przerwania występują co 1 ms to stanie się to dokładnie 5 sekund po uruchomieniu programu.

Może wydaje Ci się to dziwne, i pokręcone. Ale to bardzo uproszczony przykład, zobacz:
1. W żadnym miejscu program nie czeka.
2. W pętli głównej możesz w ten sposób sprawdzać dziesiątki najróżniejszych warunków.
3. Możesz powołać sobie dowolną ilość zmiennych podobnych do timer_programowy i każda będzie sterowała innym procesem.
4. To samo przerwanie możesz użyć do multipleksowania wyświetlaczy.

Najpierw oswój się z tym mechanizmem. Obsługa klawiszy to następny krok.
Przyciski można obsłużyć też timerem. Po prostu rośnięcie zmiennej odmierza czas. I służy do niwelacji drgań styków i nie tylko.
Dlatego przeczytaj poradnik Mirka o drganiach styków. OK ?


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 22:40 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 19 wrz 2013
Posty: 6
Pomógł: 0

No i pięknie. Wydaję mi się, że już to rozumiem. Jutro spróbuję napisać stosowny kod i dam znać.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 23:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 mar 2013
Posty: 739
Lokalizacja: Poznań
Pomógł: 84

@sq8dsr za takie wytłumaczenie tematu
jak bym mógł to bym wcisnął "POMÓGŁ",
no ale to w gestii kogoś innego leży :)

Ja tylko mogę podziękować
Super dzięki



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 23:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 05 sie 2013
Posty: 1154
Lokalizacja: Lublin / Kraków
Pomógł: 72

Zaba napisał(a):
Ja tylko mogę podziękować
Super dzięki

Cieszę się, że się przydało. W sumie o to chodzi w tym forum. Jeden problem, zagadnienie może dać wiedzę wielu ludziom dlatego trzeba się pytać. :)
W końcu to nie jakaś tam Anoda czy katoda :P



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: 12 ] 

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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO