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

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 31 maja 2025, o 12:46


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 15 ] 
    Autor Wiadomość
    PostNapisane: 20 lut 2018, o 17:16 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    Dzień dobry potrzebuje przykładu kodu z komentarzami. Jak ustawić wejścia INT2 i INT3 atmega64a, tak by generowały dwa przerwania na zboczu narastającym.

    Czy w niebieskiej książce Pana Mirka, jest to opisane?

    Dodatkowo przerwania które zostaną wygenerowane musiały by wykonać 6 różnych instrukcji, w odstępach co 150ms.
    Został mi wolny timer2.

    Przepraszam za trywialne pytania i że liczę na gotowca ale naprawdę mam z tym problem, rzadko coś programuje.
    Problemem jest też dla mnie dokumentacja mikro kontrolera i konfiguracja jego sprzętów.
    Z każdym przykładem umiem więcej i pomału się uczę. Mam nadzieję że nikt na mnie nie będzie zły i uzyskam pomoc.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 20 lut 2018, o 18:18 
    Offline
    Użytkownik

    Dołączył(a): 19 paź 2014
    Posty: 357
    Lokalizacja: stolyca pyrlandii :)
    Pomógł: 18

    Tak na szybko Ci powiem, że temat przerwań jest opisany w BB w rozdziale 4.5 "Multipleksowanie LED"


    Autor postu otrzymał pochwałę


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

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    55555 napisał(a):
    Problemem jest też dla mnie dokumentacja mikro kontrolera i konfiguracja jego sprzętów.
    Niestety ale opanowanie obcowania z notami pdf to podstawa więc musisz się przemóc i poćwiczyć - poprostu się pobawić i posprawdzać jak działa jaka opcja - bez tego będzie Ci ciężko opanować AVR-y.
    Co do atmegi64A to w nocie masz dział Interrupts a w nim opis poszczególnych przerwań oraz poddział Register Description a w nim rozpisane rejestry w których takie przerwania się konfiguruje. I tak
    - w rejestrach EICRA i EICRB konfigurujesz sposób wyzwalania czyli u Ciebie zbocze narastające. Z tabeli Interrupt Sense Control wynika że trzeba ustawić oba bity ISCn0 i ISCn1 na "1" dla danego przerwania, a tak się składa że zarówno INT2 jak i INT3 swoje bity ISC ma w rejestrze EICRA więci:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    następne co musisz zrobić to zezwolić na przerwanie dla tych dwóch intów co zrobisz ustawiając jedynki w rejestrze EIMSK – External Interrupt Mask Register czyli:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Powyższe ustawienia oczywiście przed pętlą główną programu. Następnie również przed pętlą główną ale po poprzednich ustawieniach włączasz globalne zezwolenie na przerwania:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Od tego momentu procek będzie wykonywał przerwania od INT2 i INT3 ale oczywiście pod warunkiem że w programie nie zabraknie procedur obsługi tych przerwań czyli:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    oczywiście procedury obsługi przerwań umieszczasz poza ciałem głównego programu, najlepiej pod kodem głównego programu. I tu radzę zapamiętać: włączeniu jakiegokolwiek przerwania MUSI toważyszyć umieszczenie w programie obsługi tego przerwania - procedura może być nawet pusta, ale musi być. Kompilator nie wywali Ci błędu przy jej braku ale procek poprostu stanie.
    A i oczywiście na samym początku musisz zainkludować pliki biblioteczne od obsługi przerwań:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
    bez tego pojawią się pchełki z warningami...

    Jak widzisz sama aktywacja przerwań jest banalnie prosta ;), a noty wbrew pozorom są dosyć przejrzyste choć niekiedy zawierają drobne błędy, a ilość stron może przytłaczać (nota atmegi64A ma 505 stron) ale jest spis treści z hiperlinkami więc poruszanie się po nocie jest wygodne.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 mar 2018, o 16:29 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    A jak zrobić by raz wywołane przerwanie od int, wykonało kilka różnych instrukcji w konkretnych odstępach czasu? Tak by nie blokować programu.

    Startować jakiś timer od zera z pojawieniem się przerwania i zwiększać licznik po odliczeniu jakiegoś czasu od timera.
    W programie głównym, warunek że jeśli licznik ma wartość x to rób to jak licznik ma wartość y to coś innego.
    Przepełnienie licznika stop timera. Czy to dobra metoda?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 mar 2018, o 16:45 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    możesz uaktywnić jeden z liczników sprzętowych i ustawić przerwanie od przepełnienia lub porównania. W obsłudze tego przerwania wstawiasz coś takiego:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

    natomiast w pętli while możesz np:
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    czyli od momentu wystąpienia przerwania od int zostanie coś wykonane co 10 przerwań timera.
    Oczywiście sam licznik programowy soft_licznik musisz zadeklarować globalnie z przedrostkiem volatile.
    Wartości dobierasz sobie wedle uznania, równie dobrze możesz soft_licznik inicjować wartością 5 zamiast 50 a przerwanie od timera rzadziej wywoływać.
    Zamiast switch/case możesz dać ify, licznik może być inkrementowany zamiast dekrementowany - możliwości jest wiele ;)


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 mar 2018, o 09:51 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    Właśnie tak chciałem to zrobić, mogę poprosić o skonfigurowany timer2, atmegqa64 dla kwarcu 8Mhz?
    Tak by timer zwiększał licznik co 50ms. Cały cykl trwa 900ms.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 mar 2018, o 18:18 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Timer2 jest 8-bitowy i przy taktowaniu 8MHz NIE DA się go ustawić tak by generował przerwanie co 50ms - za małe możliwości podziału.
    Ten timer ma max preskaler 1024 i 8-bitową pojemność czyli 8000000/1024/256=30,51Hz czyli przerwanie co około 33ms max. Jeśli zależy Ci na tych 50ms to zostaje użyć timer1 lub timer3 - oba są 16-bitowe więc podział mają dużo większy bo 8000000/1024/65536 = 0,12Hz czyli przerwanie maksymalnie można nawet co 8,3s ustawić.
    Ewentualnie jak już te większe timery masz zajęte to możesz reagować na większe wartości licznika programowego, czyli timer ustawić by tykał co 25ms, a zadania wykonywać co 6 zmian licznika programowego czyli tak jak w założeniu 6x25 = 150ms

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


    Autor postu otrzymał pochwałę


    Ostatnio edytowano 12 mar 2018, o 18:12 przez xentis, łącznie edytowano 2 razy

    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 7 mar 2018, o 21:12 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    W procedurze obsługi przerwania timera2 kompilator zmusił mnie do postawienia ";" na końcu
    Przy TCCR2 jest literówka "\" zamiast "|"

    i jeszcze TIMSK |= (1<<CIE2); generuje u mnie "error: 'CIE2' undeclared (first use in this function)" i tutaj nie wiem o co chodzi :(



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 7 mar 2018, o 22:19 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Wszystko się zgadza: w 8 linijce literówka (znaki | oraz \ są na jednym klawiszu - bynajmniej u mnie), w 10 linijce zjadło mi się "O" powinno być OCIE2, natomiast w przerwaniu jak najbardziej zagubił się średnik. Ech tak to jest - przyzwyczajenie do wygodnego Eclipse, który pilnuje wszystkiego, daje znać o sobie.
    Poprawiłem kod w poście wyżej - teraz powinno być dobrze.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 16:32 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    Linijka TIMSK |= (1<<OCIE2); sprawia że wszystko wisi, wyłączenie jej sprawia że program znowu działa, ale oczywiście licznik nie chodzi. Gdzie może leżeć przyczyna?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 18:14 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    55555 napisał(a):
    Linijka TIMSK |= (1<<OCIE2);

    Ta linijka odpowiada za włączenie przerwania od porównania licznika. Masz w programie procedurę obsługi tego przerwania ISR(TIMER2_COMP_vect)? Bo jej brak właśnie takie objawy wywołuje...


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 18:31 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

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


    To jest moja procedurka.

    zmienne zadeklarowane jako volatile uint8_t



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 20:08 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    ok "vect" wydaje mi się że musi być pisane małymi literami czyli TIMER2_COMP_vect.
    Reszta wydaje się być OK.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 21:04 
    Offline
    Użytkownik

    Dołączył(a): 30 mar 2016
    Posty: 30
    Pomógł: 0

    Pomogło, działa :D



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 mar 2018, o 21:21 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1035
    Lokalizacja: Trójmiasto
    Pomógł: 190

    a czym pobudzasz te INT-y?
    Druga sprawa to masz jakiegoś leda w układzie - jakiegokolwiek, od tak do debugowania. Jeśli nie wiesz czy przerwania od intów się wykonują to poprostu w przerwaniu od intów możesz zrobić zapalanie diody - będziesz widział że przerwanie zadziałało jeśli nigdzie indziej w programie nie ma zapalania tej diody.
    Poza tym jeśli przerwanie od licznika mieli tylko liczniki które i tak stoją po dobiciu do zera, to jeśli masz warunki od stanu tych liczników i po wyzwoleniu inta warunki się wykonują to samo to wskazuje że przerwanie od intów zadziałało bo inaczej liczniki by nie ruszyły.
    Co do pytania na wstępie - jest jeden mały szczegół - jeśli pobudzasz te przerwania przyciskami mechanicznymi to zauważ że taki przycisk podczas pozornie pojedynczego naciśnięcia prawie na pewno wygeneruje kilka, jeśli nie kilkanaście przerwań od int.
    Jeśli pojedyncze pobudzenie ma zainicjować tylko pojedynczą ciągłą sekwencję to w przerwaniu od inta na samym początku musiałbyś wyłączyć zezwolenie na to przerwanie przez co zapobiegniesz powtórnemu zbyt wczesnemu jego wywołaniu. Ponowne odblokowanie tego przerwania możesz zrobić np w warunku else od licznika który dobije do zera.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Autor postu otrzymał pochwałę


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

    Strefa czasowa: UTC + 1


    Kto przegląda forum

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


    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