O co chodzi z FAST-PWM?

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

O co chodzi z FAST-PWM?

Post autor: nasiono » 16 sty 2007, 9:33

Witam.
Mam wielką prośbę czy mógł by mi ktoś napisać do czego służą poszczególne rejestry odpowiedzialne za konfigurowanie trybu fastPwm.
Z datasheetu nic kompletnie nie rozumiem. Na początku myślałem że jeśli interesuje mnie częstotliwość 8 bitowa to ustawiam timer aby liczył od 0 do 256 rejestrem TCNT, a do rejestru OCR1 wpisuje wartość przy której ma pojawić się stan niski, z kolei przy dojściu TCNT do 256 ma być stan wysoki.
Wydawało mi się też że OCR1 definiuje wartość TOP, a TCNT wartość MAX jednak z opisu wynika że jest na odwrót ( tak to zrozumiałem ponieważ między jnnymi napisali, że licznik zlicza od BOTTOM do TOP! a nie do MAX ).
Tak czy owak mam mętlik w głowie i nic z tego nie rozumiem .
Proszę o jakąś pomoc
Pozdrawiam.

ZbeeGin

Post autor: ZbeeGin » 16 sty 2007, 18:12

Tryb Fast-PWM generalnie nie jest "symetryczny". Licznik liczy tylko w przód, rozpoczynając od zera (BOTTOM). Po "przepełnieniu" lub dojściu do wartości ustalonej np. przez dodatkowy rejestr(MAX), zeruje się i znów liczy w górę. Jeśli zawartość licznika TCNTnx zrówna się z zawartością rejestru OCRnx to stan końcówki zmienia się - zwykle na stan niski. Po "przepełnieniu" lub zliczeniu do wartości ustalonej (TCNTnx=MAX), stan końcówki powraca w stan poprzedni - zwykle w stan wysoki. Oczywiście sygnał ten można odwrócić poprzez zmianę bitów COMnx.
Jeśli zatem do rejestru OCRnx wpiszesz zero to na wyjściu pojawi się tylko impuls w postaci szpilki. Zaś wpisanie do rejestru OCRnx wartości równej MAX spowoduje, że żaden impuls się nie pojawi.

W wielu wypadkach dla licznika 16-bitowego wartość TOP/MAX nie będzie równa 65535 (0xFFFF)!! O wartości TOP/MAX decyduje rozdzielczość licznika. Dla przykładu 10-bitowy PWM licznika Timer1 układu AT90s8515 posiada wartość TOP równą 1023 (0x03FF). Pozostałe dostępne w tym układzie rozdzielczości: 8-, 9-bitowe mają odpowiednio mniejszą wartość TOP narzucaną sprzętowo.

Nie napisałeś o jaki procesor ci chodzi, więc szczegółów podać nie mogę... :neutral:
Ostatnio zmieniony 17 sty 2007, 18:26 przez ZbeeGin, łącznie zmieniany 1 raz.

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 17 sty 2007, 9:38

Dzięki za odpowiedź, procek to Atmega 16.
Licznik liczy tylko w przód, rozpoczynając od zera (BOTTOM).
Jeśli zatem do rejestru OCRnx wpiszesz zero to na wyjściu pojawi się tylko impuls w postaci szpilki. Zaś wpisanie do rejestru OCRnx wartości równej BOTTOM - lub MAX w zależności od możliwości licznika - spowoduje, że żaden impuls się nie pojawi.
Nie wiem czy dobrze zozumiałem ale BOTTOM nie oznacza zera tylko liczbe od której timer zaczyna zliczać, i jeżeli podam do rej. OCRnx wartość mniejszą niż BOTTOM to wyrzuci jeden impuls? Gdy zaś dam OCRnx==BOTTOM lub OCRnx==MAX nie będzie żadnych szpilek?

I co właściwie oznacza TOP wydawało mi się, że TOP jest to poprostu zrównanie OCRnx i TCNT przy którym zostaje ustawiony stan na odnodze uP, po czym licznik zlicza dalej do MAX kiedy to zmieni stan nogi na przeciwny.
Z tego co napisałeś to po dojściu do TOP licznik od razu się zeruje, w takim razie czym jest MAX !!!

ZbeeGin

Post autor: ZbeeGin » 17 sty 2007, 18:13

nasiono pisze:Z tego co napisałeś to po dojściu do TOP licznik od razu się zeruje, w takim razie czym jest MAX !!!
Na początek małe wyjaśnienie definicji. Zmieniłem treść posta wyżej, gdyż Moje założenia były... poprostu błędne. :oops:
BOTTOM - jest to wartość od której licznik zaczyna zliczać i do której powraca przy przepełnieniu w trybach FastPWM, w pozostałych trybach oznacza wartość od której licznik zlicza w górę i do której zlicza w dół,
TOP - jest to wartość do której licznik zlicza w górę i od której liczy w dół w pozostałych trybach pracy PWM.
MAX - to wartość do której licznik zlicza i po osiągnięciu której zeruje się do wartości BOTTOM w trybie FastPWM.
nasiono pisze:Nie wiem czy dobrze zozumiałem ale BOTTOM nie oznacza zera tylko liczbe od której timer zaczyna zliczać, i jeżeli podam do rej. OCRnx wartość mniejszą niż BOTTOM to wyrzuci jeden impuls?
BOTTOM generalnie oznacza 0, chyba że licznik posiadał będzie jakąś wartość przed uruchomieniem trybu PWM. Nota katalogowa nic nie mówi co zrobi licznik i czy przyadkiem nie wyzeruje się automatycznie. Wspomniana przez Ciebie operacja nie wygeneruje niczego, bo wewnętrzny mechanizm buforowania zapisu na to nie pozwoli. PWMy w AVR są tzw. glitch-free i mają dodatkowy bufor który przepisze się dopiero po osiągnięciu warotści TOP/MAX lub BOTTOM w zależności od trybu pracy.
nasiono pisze:Gdy zaś dam OCRnx==BOTTOM lub OCRnx==MAX nie będzie żadnych szpilek?
W/g noty: Nie nie będzie, stany na wyjściach będą stabilne.
nasiono pisze:I co właściwie oznacza TOP wydawało mi się, że TOP jest to poprostu zrównanie OCRnx i TCNT przy którym zostaje ustawiony stan na odnodze uP, po czym licznik zlicza dalej do MAXkiedy to zmieni stan nogi na przeciwny.
Z tego co napisałeś to po dojściu do TOP licznik od razu się zeruje, w takim razie czym jest MAX !!!
Myślę, że definicja czym jest TOP, BOTTOM, MAX wyjaśni te wątpliwości.

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 18 sty 2007, 11:53

Przeczytałem kilka razy datasheeta i inne źródła, chyba mi się rozjaśniło prosze mnie poprawić jeśli się myle ale FAST-PWM ma kilka trybów które właściwie dyktują wartość przy której licznik się zeruje. W zależności od trybu wpisujemy tą wartośc do rejestru ICR dzięki czemu mozemy generwoać jednoczesnie 2 przebiegi na 2 nogach różniących się wypełnieniem, lub też wartość wpisujemy do rej. OCR1A i uzyskujemy przebieg tylko na jednej odnodze. Te 2 tryby pozwalają na dodatkową regulacje częstotliwości. Można też ustawić sztywną wartość na 8-9-10 bit. Czy tak jest w istocie dobrze zrozumiałem ?

Spróbowałem napisać prosty programik z wykorzystaniem trybu 8-bit :

Kod: Zaznacz cały

DDRD=0xFF;

TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);

TCCR1B|=(1<<WGM12)|(1<<CS11)|(1<<CS10);

//TCNT1=0;


OCR1A=128;
Licznik co prawda ustawia przy zrównaniu wyprowadzenie ale przy dojściu do MAX nie zeruje się na BOTTOM i nie przestawia nogi tylko zaczyna dekrementować do zera przestawiając stan nogi przy 128 na przeciwny i tak w kółko ( 0 +++ 128 L +++ 255 --- 128 H --- 0). Jak to właściwie jest?

ZbeeGin

Post autor: ZbeeGin » 18 sty 2007, 18:50

Licznik co prawda ustawia przy zrównaniu wyprowadzenie ale przy dojściu do MAX nie zeruje się na BOTTOM i nie przestawia nogi tylko zaczyna dekrementować do zera przestawiając stan nogi przy 128 na przeciwny i tak w kółko ( 0 +++ 128 L +++ 255 --- 128 H --- 0). Jak to właściwie jest?
Jeśli chodzi o symulację w AVR Studio to on właśnie może to tak pokazać. Też próbowałem symulować różne tryby PWM ale jak widać nie radzi sobie z tym dobrze.
nasiono pisze:(...) FAST-PWM ma kilka trybów które właściwie dyktują wartość przy której licznik się zeruje. (...)
Owszem. Nie zagłębiałem się tak daleko - to już Twoja działka.

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 18 sty 2007, 20:58

Dzięki. Mam jeszcze pytanko jak można sprawdzić czy PWM na prawde chodzi jak powinien?

ZbeeGin

Post autor: ZbeeGin » 18 sty 2007, 21:02

Napisz prosty program który będzie sterował jasnością diody LED. Zmieniaj zawartość OCRnx i będziesz wiedział, że działa. Resztę - czasy, impulsy szpilkowe, itd. - niestety można będzie sprawdzić dopiero na oscyloskopie...

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 19 sty 2007, 10:55

Tak rzeczywiście PWM chodzi jak powinien zeruje sie przy przejściu przez MAX tylko symulator szwankuje sprawdziłem to dając w głównej pętli while warunek

Kod: Zaznacz cały

while(1){

if(bit_is_set(PIND,PD5)) 
{
licznik[0]=TCNT1;
delayus(205);
licznik[1]=TCNT1;
delayus(1);
licznik[2]=TCNT1;
delayus(5);
licznik[3]=TCNT1;


LCD_putint(licznik[0],10);LCD_putstr_P(PSTR(","));
LCD_putint(licznik[1],10);LCD_putstr_P(PSTR(","));
LCD_putint(licznik[2],10);LCD_putstr_P(PSTR(","));
LCD_putint(licznik[3],10);
dzięki czemu wiem że po przejściu przez 255 się zeruje.
Problem rozwiązany, dziękuje za pomoc i pozdrawiam!

[ Dodano: 2007-01-20, 10:24 ]
Mam jeszcze pytanko czy wypełnienie można zmieniać normalnie w pętli programu, czy tylko w przerwaniu ewentualnie w instrukcji oczekiwania na zmiane flagi?

ZbeeGin

Post autor: ZbeeGin » 23 sty 2007, 0:32

nasiono pisze:Mam jeszcze pytanko czy wypełnienie można zmieniać normalnie w pętli programu, czy tylko w przerwaniu ewentualnie w instrukcji oczekiwania na zmiane flagi?
Zmianę wypełnienia możesz wykonać w dowolnym momencie. Jednak z powodu systemu podwójnego buforowania, zmiana ta nie będzie natychmiastowa i dopiero po przepełnieniu licznika nowa wartość zostanie uwzględniona. Z tego też powodu nie ma sensu oczekiwać na zmianę stanu flagi OCF, gdyż w takim przypadku zmiana wypełnienia byłaby opóźniona o jeden cały cykl licznika.

ODPOWIEDZ