Skocz do zawartości

Funkcja Input Capture w Arduino


Pomocna odpowiedź

(edytowany)
13 minut temu, farmaceuta napisał:

Sam teraz czytam o tych timerach/przerwaniach/wektorach/przepelnieniach itp....i katastrofa!😂

Fajnie że Cię zmotywowałem 🙂 o ile zrozumienie idei przerwania jest dość proste to faktycznie, w nazwach rejestrów i ich różnych kombinacji można się pogubić. Sam nieraz rwę włosy z głowy zwłaszcza jak trzeba jakiś timer ustawić w PWM czy tam inny nietypowy tryb. Na "szczęście" taki m328 ma tylko 3 timery (pisząc szczęście w cudzysłowie mam na myśli to że czasem przydałoby się ich więcej) i daje się to ogarnąć. O np: jest taka ciekawostka związana z Timerem2 możesz podłączyć do niego zewnętrzny kwarc zegarkowy 32678Hz i masz przerwania równo co sekundę 🙂 Także możliwości jest sporo. Z czasem uznasz, że mając wolny timer, zaczniesz opóźnienia programowe realizować za jego pomocą a nie jakichś tam dealy.  

Edytowano przez _LM_
Link to post
Share on other sites
1 minutę temu, _LM_ napisał:

o ile zrozumienie idei przerwania jest dość proste to faktycznie, w nazwach rejestrów i ich różnych kombinacji można się pogubić

O to to to! ...wlasnie te nazwy i kombinacje...masakra jakas..😕 to ja przy okazji zapytam...powiedzmy ze chce generowac jakis sygnal, niekoniecznie pwm...jakis tam sygnal poprostu..to moge uzyc dowolnego pinu? A w przypadku odczytu sygnalu to musze uzyc jakiegos konkretnego? Czy dowolnie..? 

Link to post
Share on other sites

Jeśli chcesz użyć sprzętowych timerów to w AVR niestety jesteśmy ograniczeni do tego co udostępnił producent. Czyli w m328 jest to PD5 (OC0A), PD5(OC0B), PB1(OC1A), PB2(OC1B), PB3(OC2A) natomiast można programowo generować impulsy na dowolnym pinie. Są sterowniki serwomechanizmów które wykorzystują więcej pinów niż jest wyjść pwm zobacz

  • Lubię! 1
Link to post
Share on other sites
(edytowany)
17 minut temu, farmaceuta napisał:

A w przypadku odczytu sygnalu to musze uzyc jakiegos konkretnego? Czy dowolnie..?

Przy odczycie jest nieco inaczej gdyż gdybyś chciał odczytywać wartości analogowe to masz tylko 6 wejść i tego nie obejdziesz w prosty sposób, przy innych, cyfrowych sygnałach znów - można użyć większości dostępnych pinów

Edytowano przez _LM_
Oczywiście m328 ma sześć a nie 8 wejść analogowych
  • Lubię! 1
Link to post
Share on other sites
48 minut temu, _LM_ napisał:

gdybyś chciał odczytywać wartości analogowe to masz tylko 6 wejść

osiem - chyba że ograniczysz się do UNO który nie ma wyprowadzonych wszystkich wejść (A6 i A7).

Link to post
Share on other sites

Tak i jeszcze o ile dobrze pamiętam były różnice w rozdzielczości zależnie od wersji obudowy mikrokontrolera. Ale to chyba już stare dzieje

Link to post
Share on other sites

Jesli to jeszcze mozliwe to wytlumaczcie mi tak na "chlopski rozum" co ocnaczaja te litery na koncach nazw rejestrow...A/B 

TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS12); 
OCR1A = 31250;
TIMSK |= (1 << OCIE1A);

Kod skradziony z neta..(moze CBS mnie nie dopadnie)..Czym to sie rozni?? Bo sa np. takie opcje 

TCCR1A
TCCR1B

...(dostane padaczki arduinowej zaraz..😅) chodzi mi tylko tak z grubsza o wyjasnienie, bo do niczego mi to nie jest narazie potrzebne, ale jak bym cokolwiek kumal to bym sie nie pogniewal na siebie..😉

Link to post
Share on other sites
(edytowany)

Najchętniej odpowiedziałbym: rtfm. No ale nie będę taki złośliwy. Rejestr TCCR1 jest szesnastobitowy i w taki właśnie sposób inżyniery z Atmela go podzielili: na część a i b po osiem bitów. W każdym z tych "półrejestrów" siedzą odpowiednie bity sterujące timerem.  Czyli te CS, WGM i inne pieroństwo. A te nazwy mają na celu łatwiejsze skojarzenie co jest co. Przyznasz mi rację że ustawienie np 

TCCR1B |= (1 << WGM12);

jest czytelniejsze niż 

TCCR1B|= (1<<3);

A te zapisy zadziałają tak samo

Edytowano przez _LM_
  • Pomogłeś! 1
Link to post
Share on other sites
(edytowany)
51 minut temu, _LM_ napisał:

Najchętniej odpowiedziałbym: rtfm. No ale nie będę taki złośliwy. Rejestr TCCR1 jest szesnastobitowy i w taki właśnie sposób inżyniery z Atmela go podzielili: na część a i b po osiem bitów. W każdym z tych "półrejestrów" siedzą odpowiednie bity sterujące timerem.  Czyli te CS, WGM i inne pieroństwo. A te nazwy mają na celu łatwiejsze skojarzenie co jest co. Przyznasz mi rację że ustawienie np 



TCCR1B |= (1 << WGM12);

jest czytelniejsze niż 



TCCR1B|= (1<<3);

A te zapisy zadziałają tak samo

 

51 minut temu, _LM_ napisał:

inżyniery z Atmela go podzielili: na część a i b po osiem bitów. W każdym z tych "półrejestrów" siedzą odpowiednie bity sterujące timerem.

A widzisz...tego w zadnym poradniku nie napisali..😅 dzieki wielkie! 

No a ten zapis jak mam rozumiec?

OCR1A = cos tam...

Wiem mniej wiecej do czego sluzy ten rejestr tylko zastanawia mnie czemu on tez sie dzieli na A/B? Nie moge uzyc poprostu 

OCR1  ??

 

Edytowano przez farmaceuta
Link to post
Share on other sites

Tu już wchodzimy w zawiłości timerów ten rejestr ma różne zastosowania zależnie od trybu pracy timera. W nocie jest to opisane na str 97.

Ustalając parametry jakiegoś timera czy jakiegokolwiek innego wbudowanego modułu jak najbardziej można zapisać:

 TCCR1B = 0b00001011;
  

Tyle że: taki zapis jest nieczytelny, oraz jeśli któryś bit miał inną wartość wtedy zostanie zasłonięty tym co teraz jest wpisywane. Należy unikać takich sytuacji stąd zapisy z przesunięciami << 

  • Pomogłeś! 1
Link to post
Share on other sites
23 minuty temu, _LM_ napisał:

Tu już wchodzimy w zawiłości timerów ten rejestr ma różne zastosowania zależnie od trybu pracy timera. 

No cos teraz kapuje bo znalazlem kilka przykladow/problemow i wiem ze OCR1A i OCR1B to dwa osobne rejestry 16-bitowe dla tego samego timera oczywiscie...no ale zeby poslugiwac sie jednym i drugim na raz to "cza umic" tak z grubsza..😉

28 minut temu, _LM_ napisał:

Tu już wchodzimy w zawiłości timerów ten rejestr ma różne zastosowania zależnie od trybu pracy timera. W nocie jest to opisane na str 97.

Ustalając parametry jakiegoś timera czy jakiegokolwiek innego wbudowanego modułu jak najbardziej można zapisać:


 TCCR1B = 0b00001011;
  

Tyle że: taki zapis jest nieczytelny, oraz jeśli któryś bit miał inną wartość wtedy zostanie zasłonięty tym co teraz jest wpisywane. Należy unikać takich sytuacji stąd zapisy z przesunięciami << 

Tak tak..to akurat rozumiem wrecz doskonale zeby uzywac preferowanych nazw..wtedy sie uniknie niespodzianek w stylu.." no k**** czego nie dziala!!"😉

Link to post
Share on other sites

Musze jeszcze dopytac...o ile coraz blizej "rozgryzienia" tych timer'ow jestem to jeszcze kilku rzeczy nie rozumiem...mam kilka trybow do wyboru..kazdy moze uzywac przerwan ktorych rowniez jest kilka rodzajow..mam to tak rozumiec ze kazdy tryb ma swoje indywidualne przerwanie?

TOIE1: 
OCIE1A:
TICIE1:

Czyli w trybie normalnym uzywam tylko "TOIE1"? Czy to jeszcze jakos inaczej sie dzieli..?

Link to post
Share on other sites
(edytowany)

Każdy timer jak i inne "sprzęty" mają przypisane swoje wektory przerwań także inne będą do ADC inne dla Timerów w tym każdy z nich też ma swoje. 

39 minut temu, farmaceuta napisał:

Czyli w trybie normalnym uzywam tylko "TOIE1"? Czy to jeszcze jakos inaczej sie dzieli..?

w trybie normalnym jest dostępne tylko przerwanie od przepełnienia TOV1(tj: dostępne są wszystkie z tym że tylko TOV1 będzie zgłaszane) natomiast do jego blokowania/odblokowania służy właśnie TOIE1.  

39 minut temu, farmaceuta napisał:

kazdy moze uzywac przerwan ktorych rowniez jest kilka rodzajow..mam to tak rozumiec ze kazdy tryb ma swoje indywidualne przerwanie?

Chyba nie do końca rozumiem twoje pytanie. No ale zobacz na kod który wstawiłem: Program korzysta zarówno z przerwania od przepełnienia jak i od przechwytu. 

Edytowano przez _LM_
  • Pomogłeś! 1
Link to post
Share on other sites

Mam taki kod jak ponizej, i dziala dobrze z tym ze z dwukrotna czestotliwoscia..

byte x = 0;

void setup() {
pinMode(13, OUTPUT);
                                
  TCCR2B|=(1<<CS02)|(1<<CS00);  //preskaler na 1024
  TIMSK2|=(1<<TOIE2);    //wlaczenie przerwania od przepelnienia
  TCNT2=0;               //przypisanie wartosci startowej do licznika
  sei();                 // przerwania globalne wlacz
}

void loop() {
//delay(77777);

if (x == 61)  {
  digitalWrite(13, HIGH);
}
if (x == 122)  {
  digitalWrite(13, LOW);
  x = 0;
}
}

ISR(TIMER2_OVF_vect)
{
  x++;
 }

no i teraz tak, o ile dobrze rozumiem to licze to tak;

16000000(taktowanie) / 1024(preskaler) = 15625(impulsow z czego jeden zawiera 1024 takty zegara). nastepnie 15625 / 256(licznik 8-bitowy) = +/- 61.

wiec zmienna "x" co 1 sekunde ma wartosc 61 tak?  wiec dioda powinna zmieniac stan co 1s a u mnie jest to 0.5s..czemu?

Link to post
Share on other sites
(edytowany)

Tak na szybko odpowiadam w przerwaniu mususz aktualizowac tcnt2albo skorzystać z rejestru porownania ocr2 chyba. Później szczegóły 

Edytowano przez _LM_
Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.