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



Teraz jest 28 mar 2024, o 14:09


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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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 ]
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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

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