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



Teraz jest 26 kwi 2024, o 06:20


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 37 ]  Przejdź na stronę 1, 2  Następna strona
Autor Wiadomość
PostNapisane: 26 kwi 2017, o 08:20 
Offline
Użytkownik

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

Jak coś takiego zrobić? Na wejściu do avr mam sygnał z kontrolki. Jak mruga na wyjściu chcę mieć stan wysoki jak nie mruga niski.
Na pewno jakiś banał. A może nie? Jestem początkujący, będzie mi przerwanie potrzebne do liczenia czasu? I mierzyć jak długo nie było 1 na wejściu. Jeszcze z żadnego przerwania nie korzystałem. Mam czas do poniedziałku.

Może inaczej takie rzeczy się robi?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 09:32 
Offline
Użytkownik
Avatar użytkownika

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

Najprościej sygnał z kontrolki podaj na jedno z wejść pcint i w przerwaniu załączaj wybrane wyjście na czas dłuższy od okresu trwania migania kontrolki. Za każdym razem gdy kontrolka mignie wykona się przerwanie które podtrzyma załączenie wyjścia. Gdy kobtrolja zgaśnie przerwanie przestanie wydłużać czas podtrzymania wyjścia i to się wyłączy.
Najlepiej odpalić timer sprzętowy do odmierzania czasu, utworzyć zmienną globalną z dopiskiem volatile.
Przerwanie od kontrolki będzie ładować jakąś watrość do tej zmiennej, natomiast tykający licznik będzie odejmować pod warunkiem że zmienna większa od zera. I np w pętli gł. warunek jeśli zmienna większa od zera załącz wyjście, jeśli równa zero wyłącz wyjście.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 10:46 
Offline
Użytkownik

Dołączył(a): 22 sty 2014
Posty: 1806
Zbananowany użytkownik

Pomógł: 168

A nie prościej to zrobić na jakimś obwodzie RC i komparatorze? Ja rozumiem że niedługo mikrokontrolery będą nawet w szczotkach do kibelka ale takie rzeczy załatwia się 4 rezystorami, kondensatorem i wzmacniaczem operacyjnym za 50 groszy.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 12:59 
Offline
Użytkownik

Dołączył(a): 10 sty 2017
Posty: 50
Pomógł: 5

Nefarious19 napisał(a):
A nie prościej to zrobić na jakimś obwodzie RC i komparatorze? Ja rozumiem że niedługo mikrokontrolery będą nawet w szczotkach do kibelka ale takie rzeczy załatwia się 4 rezystorami, kondensatorem i wzmacniaczem operacyjnym za 50 groszy.

Jak to jest ćwiczenie na laborkę z mokrokontrolerów to ciężko będzie przekonać prowadzącego do twojego rozwiązania. Miganie diodą też robi się na dwóch tranzystorach kondensatorach i rezystorach. A jednak zabawę z mikroklockami od tego się zaczyna. Kolega xentis dobrze pisze. Ustaw licznik, który w przerwaniu od timera będzie liczył do zera, jak doliczy to gaś wyjście. W przerwaniu zewnętrznym INT0 zapalaj wyjście (nawet jeśli jest zapalone) i ustawiaj ten licznik na wartość początkową. Pętla główna będzie pusta.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 14:29 
Offline
Użytkownik

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

Nefarious19, twoje rozwiązanie niestety odpada, projekt realizuje więcej funkcji. Tą po prostu tak uprościłem.
Nie jest to też ćwiczenie na laborki, jak ja się uczyłem takich rzeczy nie było :( próbuję sam

Już czytam o przerwaniach mam niebieską książkę i spróbuję napisać.

Czy mogę pominąć wejście pcint? I sprawdzać stan zwykłego wejścia w pętli głównej, jeśli jest wysoki to ustawić wyjście na wysoki i zerować licznik, przerwanie od licznika gasi? Da się tak?
Płytkę mam już zrobioną, ale jak trzeba to przepnę jakimś kynarkiem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 16:46 
Offline
Użytkownik
Avatar użytkownika

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

Wszystko zależy czym zajmuje się uC. Jeśli procek nie jest czymś intensywnie zajęty to takie rozwiązanie zadziała, lecz jeśli masz bardziej skomplikowany program i procesor będzie zajęty wykonywaniem instrukcji których czas wykonywania będzie dłuższy od okresu mrygania kontrolki to nie będzie to działać stabilnie tzn reakcja wyjścia na zamryganie kontrolki może nastąpić z opóźnieniem albo wcale, a dodatkowo nawet jak wyjście zadziała to możesz mieć przypadki że pomimo dalszego mrygania kontrolki wyjście się wyłączy (licznik będzie tykał od przerwania więc zadziała za każdym razem natomiast zapalanie diody w pętli głównej może się przycinać w zależności od wykonywanych zadań w pętli głównej)
Na jakim procku się bawisz? Bo np seria procków atmega 48, 88, 168... posiada PCINT praktycznie na każdym pinie I/O, jedyna różnica jest taka że przerwanie jest dla grupy pinów i pierwszą rzeczą w przerwaniu musisz zrobić sprawdzenie na którym pinie wystąpił sygnał pobudzający.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2017, o 18:00 
Offline
Użytkownik

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

Mój scalaczek to Atmga64a, program raczej prosty. Szczerze brak mi doświadczenia by to stwierdzić ale czuję że da rade :)
Będę pamiętał na przyszłość o tych PCINT. A teraz spróbuje użyć samego przerwania od timera i warunku w pętli głównej.
Trochę muszę poczytać by to zrobić, na pewno jeszcze się odezwę w tej sprawie. Bardzo dziękuję za pomoc.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 kwi 2017, o 16:11 
Offline
Użytkownik

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

Potrzebuje pomocy, najlepiej przykładu/ kawałka kodu z ustawieniem przerwania od timera1 pod mój procesorek, atmega64a.
W tej chwili nie wiem z jaką częstotliwością mruga kontrolka, a w zasadzie kontrolki bo są dwie, ale mniej więcej co 1sek.
Więc będę potrzebował dwóch liczników i dwóch przerwań od nich, jak dobrze rozumiem muszą być 16bitowe.
Pan Mirek w książce zaleca stosowanie trybu ctc, chciałbym go ustawić ale w tym uc, jest inaczej niż w przykładzie z książki. Dlaczego są dwa tryby ctc, którego użyć?

http://www.atmel.com/Images/Atmel-8160- ... asheet.pdf
strona 161



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 kwi 2017, o 17:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

witam,
Do takiego zadania szkoda timera1 ;)
wystarczy timer0.
jeżeli taktowanie jest np 8MHz to 8000000/1024/256 = 30Hz (przerwanie)
dla trybu "normal" nie musimy nawet myśleć o bitach WGM.
w rejestrze TCCR0 załączamy bit CS00, CS01, CS02. dla preskalera 1024.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

i chyba tyle w ustawieniach timera który wywoła przerwanie 30 razy na sek.
Oczywiście trzeba jeszcze ustawić pin wejściowy i wyjściowy. W DDR.. i PORT.
i jeszcze globalne zezwolenie na przerwania sei();

W przerwaniu od przepełnienia można by wpisać:
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 sprawdzać jeżeli jest flaga ,
jeżeli tak to:
czy stan PINU == zapisana_wartość,
jeżeli tak to zgaś wyjście;(bo brak zmiany napięcia na wejściu)
else{
załącz wyjście;
zapisz aktualny stan PINU do zapisana_wartość;
i nie zapomnieć o skasowaniu flagi.

tak jakoś. :) pozdrawiam.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2017, o 11:05 
Offline
Użytkownik

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

A mogę tak?

Kod:
ISR(TIMER0_OVF_vect)
{
static uint8_t zliczanie=0;

   if (!wejscie)
   {
      zliczanie=zliczanie+1;
      if (zliczanie >= 29) FLAGA_MRUGA=0;
   }
   else
   {
      zliczanie=0;
      FLAGA_MRUGA=1;
   }

}


FLAGA_MRUGA jako zmienna globalna z volatile ?
W głównej jak mruga to wyjście w stan wysoki jak nie mruga to niski.
Dodatkowo "29" jako stała globalna i gdzieś na początku programu ustawię wartość jak będę wiedział z jakim czasem to mruga.

a może zliczanie zrobić jako zmienną globalną i w tedy ten "else" jako "if (wejscie)" przenieść do pętli głównej. żeby przerwanie było krótsze?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2017, o 12:07 
Offline
Użytkownik
Avatar użytkownika

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

55555 napisał(a):
Więc będę potrzebował dwóch liczników i dwóch przerwań od nich,
Jeśli kontrolki migają mniejwięcej z tą samą częstotliwością to wystarczy Ci jeden timer, jedno przerwanie tylko dwie zmienne po jednej dla każdej kontrolki.
Cytuj:
FLAGA_MRUGA jako zmienna globalna z volatile ?
zmienn jest modyfikowana w przerwaniu więc tak.
Cytuj:
Dodatkowo "29" jako stała globalna i gdzieś na początku programu ustawię wartość jak będę wiedział z jakim czasem to mruga.
chyba lepiej jako definicja preprocesora #define.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2017, o 12:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

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

to w Twoim przerwaniu możesz pominąć flagę a zamiast niej, od razu ustawiać wyjście.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

może tak - idąc Twoim tropem. :)


Autor postu otrzymał pochwałę


Ostatnio edytowano 28 kwi 2017, o 12:58 przez Daro69, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2017, o 12:36 
Offline
Użytkownik

Dołączył(a): 10 sty 2017
Posty: 50
Pomógł: 5

Do 55555. Zwróć uwagę że inkrementacja zmiennej zliczanie spowoduje przekręcenie licznika i ponownie zliczanie będzie mniejsze od 29.
Jak już nie chcesz wykorzystać INT0 to w pętli głównej za każdym obiegiem sprawdzaj stan wejścia i wstaw
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

W przerwaniu dekrementuj zmienną volatile zliczanie sprawdzając uprzednio czy większa od 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  
PostNapisane: 28 kwi 2017, o 12:47 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

o.. Tu kolega "riddik" dobrze zauważył -
poprawiam i w moim kawałku bo nie zabezpieczyłem podobnej sytuacji " inkrementacja". :)
dopisuję w tamtym kodzie z wykrzyknikami. ;)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2017, o 14:51 
Offline
Użytkownik

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

Przepraszam że się nie odzywałem miałem trochę problemów osobistych.

Kontrolki mrugają tak że przez 600ms są zapalone i przez 300ms są zgaszone.
Kod:
ISR(TIMER0_OVF_vect)
{

   if (!WEJSCIE_L)
   {
      ZLICZANIE_L=ZLICZANIE_L+1;
      if (ZLICZANIE_L >= MAX_ZLICZANIE)
      {
         FLAGA_MRUGA_L=0;
         ZLICZANIE_L=MAX_ZLICZANIE;
      }
   }


   if (!IN_WEJSCIE_P)
   {
      ZLICZANIE_P=ZLICZANIE_P+1;
      if (ZLICZANIE_P >= MAX_ZLICZANIE)
      {
         FLAGA_MRUGA_P=0;
         ZLICZANIE_P=MAX_ZLICZANIE;
      }
   }
}

Flagę zostawiam bo użyję jej jeszcze do innych rzeczy.

W pętli głównej będzie
Kod:
      if (WEJSCIE_L)
      {
         ZLICZANIE_L=0;
         FLAGA_MRUGA_L=1;

i analogicznie dla prawego wejścia

zmienne globalne
volatile uint8_t FLAGA_MRUGA_L,FLAGA_MRUGA_P, ZLICZANIE_L, ZLICZANIE_P;

i
#define MAX_ZLICZANIE 10 //dobrze policzyłem?

jest jakaś różnica między zapisem ZLICZANIE_L+1 a ZLICZANIE_L++ dla kompilatora?
Jak użyję inkrementacji "++" dostaję warning "operation on ‘ZLICZANIE_L’ may be undefined"



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2017, o 14:57 
Offline
Moderator zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 3187
Lokalizacja: Kraków - obok FAB5 ATMEL'a
Pomógł: 89

topic7402.html



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2017, o 05:43 
Offline
Użytkownik
Avatar użytkownika

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

55555 napisał(a):
jest jakaś różnica między zapisem ZLICZANIE_L+1 a ZLICZANIE_L++ dla kompilatora?
Jak użyję inkrementacji "++" dostaję warning "operation on ‘ZLICZANIE_L’ may be undefined"

Różnica praktycznie żadna - jeśli się mylę niech ktoś mnie poprawi - generalnie masz 3 możliwe zapisy:

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

Wszystkie powyższe zapisy zwiększają zmienną ZLICZANIE_L o 1
Co do warninga to nie próbowałeś przypadkiem użyć inkrementacji razem z przypisaniem (ZLICZANIE_L=ZLICZANIE_L++)? Bo taki twór jest niewłaściwy...


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 maja 2017, o 19:04 
Offline
Użytkownik

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

Dokładnie tak było :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 maja 2017, o 19:42 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2562
Pomógł: 126

:) to dobrze, że już wiesz co było praprzyczyną, bo niektórzy w takich sytuacjach twierdzą, że kompilator jest uszkodzony i błędnie generuje kod ;) a prawda jest taka, że błąd był po stronie programisty.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 cze 2017, o 17:04 
Offline
Użytkownik

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

Znowu potrzebuje pomocy, będzie to rozwinięcie tego samego projektu, Ale chciałbym korzystać dodatkowo z 6 sprzętowych wyjść pwm.
Więc będę musiał zabrać timer0 którego wcześniej używałem i razem z timerem 2 użyć do obsługi PWM. Bo tylko one w tym procku mają obsługe PWM, prawda?

Jest nowa płytka, procesorek ten sam atmega64a. Mógłbym użyć któregoś timera 16bit zamiast wcześniejszego i przeliczyć czasy.
Ale tym razem wejścia od dwóch kontrolek są podpięte też do pinów pcint. Nie wiem którego rozwiązania użyć.
Bo w pierwszym miałem tylko jedno przerwanie a w rozwiązaniu z pcint będą dwa.

Jeśli lepiej użyć pierwszego rozwiązania tak jak było wcześniej, to nie umiem ustawić timera 16bit :( nie radzę sobie z datasheetem a jeśli drugiego to poprosiłbym o przykład jak użyć.
I o wyjaśnienie sytuacji kiedy na dwóch wejściach pcint w tym samym czasie pojawia się sygnał. Przerwanie od którego wejścia wykona się najpierw?

ps. Trochę gorączkuje i nie pełno sprytny jestem. Proszę mocno na mnie nie krzyczeć :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 cze 2017, o 18:57 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

hmm...
zerknąłem na ds'a i widzę że ma na timerze_1 OC1A, OC1B, OC1C oraz na timerze_3 OC3A, OC3B, OC3C .

nie bawiłem się jeszcze tą atmesią, ale chyba trzeba by ustawić.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i chyba tyle dla T1 i T3. ;)
PCINT'y sprawdzało się programowo bo zgłaszane były wszystkie. w przerwaniu trzeba sprawdzać z którego pinu.
Natomiast co do INT'ow to pierwszeństwo ma ten z mniejszym numerem.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 cze 2017, o 19:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Dodam jeszcze informacyjnie, skoro rozpatrujemy ATMEGA_64_A.
55555 napisał(a):
Ale chciałbym korzystać dodatkowo z 6 sprzętowych wyjść pwm.
Więc będę musiał zabrać timer0 którego wcześniej używałem i razem z timerem 2 użyć do obsługi PWM. Bo tylko one w tym procku mają obsługe PWM, prawda?

T0 i T2 nie mają 6_kanałów sprzętowego PWM. :?
Sprzętowe wyjścia T0 i T2 zaznaczyłem na czerwono, a dla T1 i T3 na zielono.
Obrazek
pozdrawiam :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 19 cze 2017, o 16:46 
Offline
Użytkownik

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

Przepraszam że znowu się nie odzywałem, ale tak mnie zasypali robotą że dopiero teraz znalazłem chwilę na ten projekt.
Jeśli chodzi o wyjścia i timery to już widzę swój błąd, wykorzystać oczywiście chcę te zaznaczone na zielone.

Dziękuję za kod, oczywiście pięknie 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.

Potrzebuję rozjaśnienia :oops: rozumiem że to do tabelki "Table 20-6" z manulala do atmega64a, ale nie wychodzi mi.
Czy wzór na częstotliwość pwm z książki Pana Mirka zawsze jest Fpwm=F_CPU / preskaler / 256 ?
Czy te 256 to tylko dla 8bit pwm?

Częstotliwość jaka mi pasuje jest w zakresie 100-200hz



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 19 cze 2017, o 19:03 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

55555 napisał(a):
Dziękuję za kod, oczywiście pięknie działa.

A proszę :D .
55555 napisał(a):
Czy te 256 to tylko dla 8bit pwm?

Też..., dla ośmio bitowego timera, lub dla timera pojemniejszego ale zliczającego np. od 0 do 255(w wielu timerach można to ustawiać) .
W powyższym przykładzie określają to wartości w rejestracg ICR liczników 16_to bitowych.
linijka 32 i 33. przykladowe 10000. Oczywiście OCR'y muszą być mniejsze od ICR'ów.
A wyliczyć częstotliwość można ze wzoru zamieszczonego w DS'ie. :)
W tym wypadku interesuje nas :
20.9.3. Fast PWM Mode
Obrazek
Czyli w tym wypadku:
" Fpwm =F_CPU / preskaler / (10000+1) " ;)
Pozdrawiam.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 cze 2017, o 12:42 
Offline
Użytkownik

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

Napisz mi jeszcze proszę, jakoś inaczej/innymi słowami jak preskaler się ustawia.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 cze 2017, o 16:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Np. Procesor jest taktowany np. 8MH -> 8 000 000 HZ .
w naszym kodzie - "TYM POWYŻEJ",
możemy ustawić preskaler na następujące wartości.
przedostatnia cyfra w CSXx - czyli X oznacza timer a ostatnia nr bitu CS__ w rejestrze.
przyjrzyj się , wcześniej użyłem skrótu z numerami CS'ów i wartością preskalera."// preskalery CS. załączone - 0=1, 1=8, 0 i 1=64, 2=256, 2 i 0=1024"
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

wybierzmy sobie np. preskaler 8 z linijki nr 4.
do timera dotrze co ósmy takt, czyli F_CPU / 8.... na razie mamy 1MHz.
który będzie za każdym tyknięciem w naszym przypadku inkrementował licznik od 0 -włącznie-, do naszej wartości ICR'a 10000.
czyli 10001 tyknięć. i teraz się "przekręci licznik" :). czyli w tym przypadku F_CPU / 8 / 10001 = ~99,99 Hz (częstotliwość PWM).
interesuje Ciebie częstotliwość od 100 do 200 Hz.
jeżeli zmniejszymy zakres zliczania timera do 5000 ICR1=5000; to o połowę częściej będzie się "przekręcał licznik".
czyli uzyskamy F_CPU / 8 / 5001 otrzymamy na wyjściu sygnał o częstotliwości ~199,98 Hz. :)
ustawiając OCR1A w zakresie od 0 do 5000, będziemy regulować wypełnienie tego sygnału. :)
Mam nadzieję że rozbłysło. :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 sie 2017, o 18:33 
Offline
Użytkownik

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

Została mi ostatnia funkcja do dodania. Będę potrzebował przerwania co ok. 100ms.
Został mi tylko timer2 z którego mógłbym zrobić 10ms i później zmienną robiącą za licznik zwiększyć 10x

8 000 000/1024/78 = 100hz = 10ms

Domyślnie licznik timera2 liczy od 0 do 255?, ale z książki Pana Mirka wiem że mogę ustawić rejestr TCNT2? żeby nie liczył od 0 tylko od 177, w tedy będę miał 78 zliczeń.
I za każdym razem gdy wystąpi przerwanie muszę wpisać do rejestru TCNT2 cyfrę 177

Proszę o sprawdzenie czy dobrze rozumuję i czy dobrze to ustawiam czy nie robię jakiegoś błędu.
I czy na pewno potrzebuję ustawić liczenie od 177? "AVR Timer Kalkulator" Pana Mirka proponuje 178
A może licznik timera liczy od 1 do 256?

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: 5 sie 2017, o 16:31 
Offline
Użytkownik
Avatar użytkownika

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

Cytuj:
A może licznik timera liczy od 1 do 256?
Licznik liczy od 0 do 255 czyli ma 256 tyknięć bo zero też się liczy.

55555 napisał(a):
I czy na pewno potrzebuję ustawić liczenie od 177? "AVR Timer Kalkulator" Pana Mirka proponuje 178

Powinieneś wpisać zgodnie ze wzorem 256-(FCPU/prskaler/f_wynikowe)) czyli wychodzi około 178 i taką wartością musisz ładować rejestr TCNT2 - niestety częstotliwość będzie generowana z niewielkim błędem wynikającym z niecałkowitego podziału.

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 jakim celu masz tu wpisane (0<<CS21) bo taki zapis przy dodawaniu nie wnosi absolutnie nic - chyba że chcesz mieć "dla oka"

Mała rada - jeśli jest dostępny to dla takich zastosowań wybieraj tryb CTC - zaoszczędzasz w ten sposób kilka czasem bardzo cennych taktów procesora bo tylko raz na początku wpisujesz wartość do rejestru porównania, a w trybie normal co każde przerwanie musisz przypisywać obliczoną wartość do rejestru TCNT2, przez co wydłużasz czas trwania przerwania.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 sie 2017, o 20:34 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

witam,
Działa tak jak kolega 'xentis' opisał.
Poza tym, czy świadomie załączasz wspomniany bit CS21 ?
Obrazek

55555 napisał(a):
Została mi ostatnia funkcja do dodania. Będę potrzebował przerwania co ok. 100ms.
Został mi tylko timer2 z którego mógłbym zrobić 10ms i później zmienną robiącą za licznik zwiększyć 10x

możesz także wykorzystać licznik pracującego timera_1.
Ustawiałeś licznik na ~200 Hz. Możesz wpisać by w przerwaniu od przepełnienia 'ICR' zliczał zmienną statyczną i wystawiał flagę,
albo flaga jako zmienna volatile i dekrementowana w przerwaniu od 19 do 0 ...
( w przerwaniu :jeżeli flaga ma wartość , to flaga--;
a w pętli : jeżeli !flaga to coś wykonaj i flaga=19. )
Nie będzie to precyzyjne 10Hz (100ms) ale zbliżone do założeń.
taki pomysł. :)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 sie 2017, o 11:01 
Offline
Użytkownik

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

Dziękuje za radę z (0<<CS21), czyli go pominąć bo 0 jest tam domyślnie?

Ja nawet chciałem użyć trybu CTC, ale nie wiem jak go skonfigurować :(
Jeśli mogę poprosić o przykład.

Timerra_1 używam do czegoś innego i nie chciał bym mieszać, dla mnie to ciężkie tematy jeszcze są.
Chętnie akurat nauczyłbym się korzystać z trybu CTC.



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: 37 ]  Przejdź na stronę 1, 2  Następna strona

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 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