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



Teraz jest 28 mar 2024, o 13:14


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
Autor Wiadomość
PostNapisane: 5 sie 2019, o 20:23 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 mar 2014
Posty: 196
Lokalizacja: Kielce
Pomógł: 3

Cześć,

Mam mały problem Timerem sprzętowym. Coś robię źle, ale nie mam pomysłu co :roll:

Mianowicie chcę zrobić generatorek, który generuję sygnał prostokątny z określoną częstotliwością. Częstotliwość jest zmieniana poprzez zmianę wartośći rejestru OCR1A. Procek to Atmega 328PB taktowana kwarcem 16 Mhz.

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


Zmiana wartości rejestru jest realizowana poprzez podział Dzielnika który ma wartość 15 625. Wartość tą dzielę przez wartość zmiennej enkoder1, która wynosi kolejno 1,2,3 itd. w zależności jak kręcę enkoderem.

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


Wszystko jest ok, założenia spełnione. Lecz zaobserwowałem dziwne zachowanie. Mianowicie podczas zmiany wartości zmiennej enkoder1, procek jakby na chwilę przystaje i po chwili realizuję generowanie sygnału. Na wyjściu mam podłączoną diodę więc jak zmieniam częstotliwość to miga szybciej albo wolniej, ale zdarzają się momenty, że na chwilę jakby procek się zatrzymał i dioda nie świeci.

A może to przez to, że podczas dzielenia generuje się liczba po przecinku a jak mam typ int ?? Co myślicie ??

_________________
BlueBook



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 sie 2019, o 07:39 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Przedstawiłeś zbyt mało kodu. Istotne jest, w jakim momencie zmieniasz wartość OCR1A. Zapis do tego rejestru w trybie CTC jest natychmiastowy (nie ma podwójnego buforowania), więc jeśli wpisujesz do niego wartość mniejszą od aktualnej wartości TCNT1, to porównanie w tym cyklu zliczania zostanie pominięte. W efekcie tego licznik nie zostanie wyzerowany, tylko będzie musiał doliczyć do maksymalnej pojemności licznika i dopiero w następnym cyklu nastąpi porównanie (przy preskalerze 1024 to opóźnienie będzie szczególnie widoczne).

Widzę, że masz włączone zezwolenie na przerwanie od porównania. Jeśli tak do tej pory nie miałeś, to najlepiej wynik obliczeń Dzielnik/enkoder1; wpisywać do jakiejś zmiennej pośredniczącej, a dopiero w procedurze obsługi przerwania od przepełnienia kopiować go do rejestru OCR1A. Nadal może być problem przy niskich wartościach OCR1A i preskalera, ale przy preskalerze 1024 powinno działać OK. Ewentualnie zamiast trybu CTC użyj innego trybu, gdzie zapis do rejestru jest OCR1A jest synchronizowany sprzętowo (podwójnie buforowany), np. trybu 15 (Fast PWM).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sie 2019, o 18:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 mar 2014
Posty: 196
Lokalizacja: Kielce
Pomógł: 3

Wprowadziłem zmienna pomocniczą, ale niestety problem pozostał.

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 trybie FAST PWM chyba nie będzie można zmieniąć częstotliwości co 1 Hz. A to jest główne moje założenie :(
W takim razie jak powinna wyglądać płynna zmiana rejestru OCRx tak aby nie było zakłóceń pracy Timera ??

------------------------ [ Dodano po: 1 minucie ]

Jeszcze udostępnię kod:

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

_________________
BlueBook



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sie 2019, o 19:35 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Rafal9018 napisał(a):
Wprowadziłem zmienna pomocniczą, ale niestety problem pozostał.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Czy Ty w ogóle przeczytałeś to, co napisałem?
Cytuj:
wynik obliczeń Dzielnik/enkoder1; wpisywać do jakiejś zmiennej pośredniczącej, a dopiero w procedurze obsługi przerwania od przepełnienia kopiować go do rejestru OCR1A


Rafal9018 napisał(a):
A w trybie FAST PWM chyba nie będzie można zmieniąć częstotliwości co 1 Hz.

A w trybie CTC można? W obydwu trybach zależność częstotliwości od wartości rejestru OCR1A jest nieliniowa, więc nie da się tak łatwo uzyskać dokładnej rozdzielczości 1Hz (dokładność częstoliwości zależy od zakresu częstotliwości, jaki chcesz uzyskać). Poszukaj w dokumentacji mikrokontrolera, jak się oblicza częstotliwości wyjściowe w poszczególnych trybach.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sie 2019, o 06:36 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1960
Lokalizacja: Lipsko
Pomógł: 125

@andrews dobrze prawi, posłuchaj go i ze zrozumieniem jeszcze raz przeczytaj co napisał. Dodam tylko, że ten "błąd" aktualizacji rejestru jest dobrym przykładem dla, niektórych początkujących programistów dlaczego timerów programowych ze zmiennym opóźnieniem nie robi się liczących w górę tylko w dół, a stosunkowo często się z tym spotykałem. Podczas zmian przy liczeniu w dół program nigdy nie przeskoczy porównania :)

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sie 2019, o 06:50 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Z powodu burzy nie zdążyłem wczoraj dopisać.

Obawiam się, że Twoje obliczenia wartości OCR1A nie są prawidłowe. Po pierwsze zakładasz rozdzielczość 1Hz, a po Twoich obliczeniach zmiana wartości zmiennej enkoder1 o 1 spowoduje zmianę częstotliwości wyjściowej o ok. 0,5Hz. Po drugie częstotliwość będzie niedokładna (pomijając niedokładności wynikające z zaokrągleń przy dzieleniu). Szczególnie będzie to zauważalne przy wyższych częstotliwościach. Użyj lepiej wzoru na częstotliwość w trybie CTC podaną w dokumentacji przez producenta mikrokontrolera.

Dodatkowo zwróć uwagę na to, że zmienna enkoder1 jest mianownikiem w dzieleniu, więc jej wartość nie może wynieść zero (dzielenie przez zero jest niedopuszczalne), a w Twoim kodzie osiąga. Ewentualnie możesz zabezpieczyć operację dzielenia warunkiem:
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: 29 sie 2019, o 10:42 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Jeszcze jedna rzecz mi przyszła do głowy. Ze względu na to, że zmienna wynik_ocr1 jest 16-bitowa, aby uniknąć problemów, należałoby dodatkowo zachować atomowość operacji, czyli przed przypisaniem jej wartości należałoby wyłączyć przerwania, przykładowo:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Tymczasowa zmienna tmp jest po to, żeby nie blokować przerwań na cały czas trwania operacji dzielenia, który może być dość długi.



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 11 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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO