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



Teraz jest 24 mar 2026, o 17:17


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 
Autor Wiadomość
 Tytuł: PWM PROGRAMOWY
PostNapisane: 1 sty 2014, o 11:53 
Offline
Nowy

Dołączył(a): 18 gru 2013
Posty: 15
Pomógł: 0

Wrzucam post w którym przedstawię jak krok po kroku zabierałem się do stworzenia programowego PWM, wrzucam go tutaj ze świadomością, że być może niektóre kroki można było wykonać inaczej, bądź można było podejść do sprawy w nieco inny sposób. Dlatego też liczę na jakiekolwiek sugestie które pozwoliły by udoskonalić ten program, zmodyfikować go tak aby działał lepiej, „stabilniej” choć nie mówię, że on nie działa ;) bo realizuje założone cele, ale być może któreś z fragmentów kodu mogły by być nieco zmodyfikowane, „zoptymalizowane”, no ale w miarę swoich umiejętności stworzyłem oto taki program którym chce się podzielić, być może komuś się przyda, pozwoli przybliżyć zasadę, a raczej moje pierwsze podejście do sposobu realizacji programowego PWM.

UKŁAD:
- Atmega8
- zewnętrzny kwarc 8 MHz
- wykorzystane piny: PB0, PB1, PB3 – DIODY LED
- Układ bazujący na buforze SN74HC245N wykorzystujący port LPT komputera, pełniący rolę swego rodzaju analizatora stanów logicznych,
- program: The Fabulous Logic Analyser.

Krótko na temat metody regulacji szerokości impulsów, wykorzystanej do stworzenia programowego PWM.

Obrazek

_length – długość trwania impulsu (wyrażona w [ms])
_period – okres powtarzania impulsu (wyrażony w [ms])

Dla stałej wartości okresu ( _period ), możemy regulować wartością trwania impulsu ( _length ) bądź inaczej zwaną czasem przewodzenia, wykorzystywanym w metodzie regulacji impulsowej napięcia stałego.

Można w ten sposób zdefiniować wielkość zwaną współczynnikiem wypełnienia:
Obrazek
gdzie wartość tego współczynnika może się zmieniać od 0 do 1, na potrzeby prezentacji zostanie zdefiniowana procentowa wartość (od 0% do 100%).

W programie dla określenia częstotliwość generowanego sygnału PWM wykorzystanie zostanie poniższy wzór:
Obrazek

Ze względu na wrażliwość ludzkiego oka, a dokładnie na pulsacje sygnałów zmiennych, które oko jest w stanie wyłapać, w metodzie PWM zostanie użyta częstotliwość sygnału równa 100 [Hz], w ten sposób światło emitowane przez diodę LED zostanie odebrane jako ciągłe.

Tak więc okres ( _period ) będzie wynosił 10 [ms].

ZAŁOŻENIA:
- Liczba stopni, impulsów generowanych w ciągu okresu -> 100.
Pozwoli to na zmianę współczynnika wypełnienia od 0% do 100% z krokiem równym 1, tym samym jego zwiększanie wpłynie na intensywność świecenia diody LED.

W ten sposób czas trwania jednego impulsu będzie równy 10ms / 100 = 0,1 [ms].

Tak więc najmniejsza wartość impulsu (_length=1) będzie trwać 0,1[ms]

Na samym początku zostaną skonfigurowane porty, oraz TIMER_1 pracujący w trybie CTC generującego przerwanie co 0,1 [ms].

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


Wynikiem powyższego kodu będzie szybkie mruganie diodą na pinie PB0, zmiana stanu co 0,1 ms.
Obrazek
Odczytane z programu:
Difference: 0,1053 ms (czas między czerwoną a zieloną linią)

Poniższe kroki pozwolą wygenerować przebieg PWM o współczynniku wypełnienia równym 1%

Zdefiniowane zmienne globalne, przypisanie określonych wartości

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


Modyfikacja obsługi przerwania

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


W momencie wystartowania licznika ( _counter ) gdy posiada wartość 0 stan na pinie do którego podpięta jest dioda LED_2 jest zmieniany na przeciwny (1). Gdy licznik osiągnie wartość określoną prze _length w tym przypadku wartość równą „1” następuje ponowna zmiana stanu na pinie (2). Licznik zlicza kolejne impulsy aż osiągnie wartość określoną przez _period, zostaje wyzerowany, i cykl się powtórzy(3).

Obrazek
Difference: 10,3907 ms ->OKRES ->_period

Przebiegi dla współczynnika wypełnienia _length=0;
Obrazek
Difference: 10,3912 ms

oraz dla _length=100
Obrazek
Difference: 10,1903 ms

Analizując przebiegi a także metodę, wprowadzamy drobne modyfikacje które sprawią, że dla wartości 0 zostanie określony poziom GND zaś dla 100 poziom VCC, w celu wyeliminowania zjawisk przedstawionych na powyższych przebiegach.

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


W tym momencie został stworzony program który generuje sygnał PWM o dowolnie określonej wartości współczynnika wypełnienia.

Kolejnym krokiem będzie stworzenie funkcji która pozwoli wprowadzać wartość współczynnika wypełnienia (_length), wartość okresu (_length), a także port na którym generowany będzie sygnał PWM.
Do tego celu zostanie stworzona i wykorzystana struktura. ;)

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


Ustawienie portu na którym będziemy generowany przebieg PWM, określenie wartości współczynnika wypełnienia oraz okresu.

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


Tworzona funkcja która będzie generować przebieg PWM, posiadać będzie identyczną budowę jak ta która została wcześniej stworzona i umieszczona w obsłudze przerwania. Rożnica polega na tym, że będzie ona operować na zmiennych zdefiniowanych w strukturze.

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


Otrzymany efekt:
Obrazek

W ramach przetestowania możliwości stworzonych funkcji sprawimy że:
- na pinie do którego podpięta jest dioda LED_1: zwiększanie wartości współczynnika wypełniane od 0 do 100
- na pinie do którego podpięta jest dioda LED_2: zmniejszanie wartości współczynnika wypełniane od 100 do 0
- na pinie do którego podpięta jest dioda LED_3: początkowo zwięszanie współczynnika wypełnienia od 0 do 100 a następnie zmniejszanie go od 100 do 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 chyba było by wszystko. Co prawda zawarłem tu kilka informacji które, można by było pominąć a tym samym post ten był by nieco krótszy, no ale chciałem przedstawić krok po kroku jak się za to zabierałem, być może komuś właśnie tak zaprezentowany temat w jakimś stopniu pomoże, a jeżeli gdzieś popełniłem jakiś błąd czy to merytoryczny czy związany z zasadą, metodą pisania i tworzenia programu mam nadzieje, że wybaczycie i zrozumiecie początkującego sympatyka mikroklocków ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 12:30 
Offline
Użytkownik
Avatar użytkownika

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

Hmm, opis ładny i dość szczegółowy. Zastanawiam się tylko nad sensem stosowania tak rozbudowanego pwm względem standardowych rozwiązań programowych mieszczących się w trzech linijkach. No, ale nie wykluczam, że komuś się może przydac takie coś, a Tobie jako trening w programowaniu na pewno ;) Zresztą sam czasem piszę dziwne rzeczy, które albo czekają cierpliwie na zastosowanie albo... przepadają na korzyść innych rozwiązań ;)

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 12:45 
Offline
Nowy

Dołączył(a): 18 gru 2013
Posty: 15
Pomógł: 0

Stworzenie tego "PWM" ;) mam nadzieje, że moge go tak nazwać ;) jak słusznie stwierdziłeś miało stanowić swego rodzaju trening w programowaniu, w poznawaniu mikrokontrolerów. Zdaję sobie sprawę, że o wiele mniej kodu zajeło by zrealizowanie tego samego za pomocą rozwiązań programowych, nie mniej jednak chciałem stworzyć taki program który pozwalał by wykorzystać dowolny port procesora, a bazuje póki co na ATMEGA8A-PU a z tego co się orientuję PWM na nim można uzyskać jedynie na PB1 oraz PB2 no chyba, że się mylę.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 13:39 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 mar 2013
Posty: 739
Lokalizacja: Poznań
Pomógł: 84

Witam
Bardzo fajny poradnik z którego nie tylko można dowiedzieć się jak uzyskać
sygnał PWM na dowolnym pinie ale to co mnie zainteresowało najbardziej
wykorzystanie struktur i w związku z tym mam pytanie
dotyczące specyfikatora volatile

Czy jak w strukturze zadeklaruje tylko jedną zmienną jako volatile to
cała struktura jest objęta tą specyfikacją czy tylko ta jedna zmienna w niej zawarta



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 13:43 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

Nie kwestionuję broń boże takich własnych badań ;) i ciekawych opisów - tak jak mówisz - czasem do człowieka można trafić na różny sposób, jednak kilka drobnych uwag:

RedLine napisał(a):
a z tego co się orientuję PWM na nim można uzyskać jedynie na PB1 oraz PB2 no chyba, że się mylę.


No mylisz się - tzn zastanawiam się czy zaglądasz do noty PDF procka czy może czytasz tylko jakieś opracowania o nim ... a ja zawsze z uporem maniaka przypominam że nota PDF, nota PDF to podstawa ;) ....

spójrz na pin PB3 na drugiej stronie i oznaczenie OC2 .... jak myślisz do czego jest ? ;)

no i tak jak mówisz - przygotowałeś sobie coś żeby można było stosować programowy PWM na dowolnej końcówce - tylko pewnie jeszcze z racji tego że początkujesz nie wiesz, że akurat jeden jedyny Timer 16-bitowy w tak biedniutkim i starym procku jak ATmega8 to SKARB, skarb na wagę złota i warto się po 100-kroć zastanowić zanim się go zmarnuje ...

tak tak ... tu troszkę albo nawet hmmm bardzo się marnuje niestety :( bo do programowego PWM'a i to wielokanałowego na dowolnych pinach procka, można z powodzeniem wykorzystać zwykły biedny Timer 8-bitowy! Ba! ... nawet najbiedniejszy timer 8-bitowy w Babci Atmega, jakim jest NIC NIE MAJĄCY Timer0 ;) .... tzn może on pracować tylko w trybie zwykłego licznika a już może dać nam kilka kanałów programowego PWM'a

polecam (może jeszcze nie masz?) Bluebooka:

http://atnel.pl/mikrokontrolery-avr-jezyk-c.html

tam jest to ale także wiele innych ciekawych rzeczy opisane - może się przyda.

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 15:00 
Offline
Nowy

Dołączył(a): 18 gru 2013
Posty: 15
Pomógł: 0

Tworząc ten program, fakt mogłem sprecyzować pewne założenia... no właśnie, choćby takie żeby jak wspominasz nie używać Timera 16-bitowego, bo jak tak teraz na to patrzę to faktycznie po co aż 16 bitowy, no ale jakoś tak mnie pochłonęło pisanie kodu, że o tym w ogóle nie myślałem. Co do not PDF owszem zaglądam do nich i stopniowo dzięki nim poznaje możliwości danego mikrokontrolera, choć właśnie... ten PB3 (OC2) mógł gdzieś umknąć mojej uwadze, może dlatego, że nie skupiałem się na programowym realizowaniu PWM, tylko właśnie na stworzeniu jego programowego odpowiednika.

Odnośnie pytania zadanego przez ->Zaba
Zaba napisał(a):
Czy jak w strukturze zadeklaruje tylko jedną zmienną jako volatile to
cała struktura jest objęta tą specyfikacją czy tylko ta jedna zmienna w niej zawarta


Tak jak wspomniałem jestem dopiero początkującym, i choć bardzo chciałbym pomóc, niestety w tej kwestii nie udzielę konkretnej informacji aby nie wprowadzać jakiś błędnych tłumaczeń, gdyż dopiero jestem na etapie poznawania struktur, specyfikatorów, czego efekt zamieściłem w tym właśnie programie ;) Jeżeli tylko będę umiał i wiedział jak dobrze odpowiedzieć na to pytanie, zapewne umieszczę je tutaj, no chyba, że ktoś, kto lepiej się na tym zna, mnie uprzedzi :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 15:08 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

Zaba napisał(a):
Czy jak w strukturze zadeklaruje tylko jedną zmienną jako volatile to
cała struktura jest objęta tą specyfikacją czy tylko ta jedna zmienna w niej zawarta


no oczywiście że tylko ta zmienna ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 16:24 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 mar 2013
Posty: 739
Lokalizacja: Poznań
Pomógł: 84

Jak zawsze można na liczyć to forum

Dzięki za odpowiedź :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 sty 2014, o 21:56 
Offline
Użytkownik
Avatar użytkownika

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

RedLine napisał(a):
Zdaję sobie sprawę, że o wiele mniej kodu zajeło by zrealizowanie tego samego za pomocą rozwiązań programowych

Chyba chodziło Ci o rozwiązanie sprzętowe ;)
Ja miałem na myśli 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.


Tylko wcześniej na początku programu deklarujesz zmienne PWM1...3 jako volatile uint8_t i ustawiasz przerwania, na którymś timerze wg uznania (od nich będzie zależeć częstotliwość). Ewentualnie w powyższym dodajesz warunek zawężający rozdzielczość (zmienna lpwm), bo tak jak teraz jest pełne 8bitów. Jest szybciej i czytelniej. Zresztą Mirek już bardzo dokładnie to opisał.

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2014, o 12:28 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

I jeszcze jedna drobna uwaga, bo wcześniej nikt o tym nie wspomniał.
Należy unikać wywoływania funkcji z przerwania, a u Ciebie w kodzie jest
wywołanie z przerwania
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

I to aż trzy razy ;-)

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2014, o 14:41 
Offline
Nowy

Dołączył(a): 18 gru 2013
Posty: 15
Pomógł: 0

SylwekK napisał(a):
Chyba chodziło Ci o rozwiązanie sprzętowe ;)

Tak dokładnie miałem na myśli sprzętowe, no a napisałem programowe ;) mając przed oczami linie kodu w których konfiguruje się TIMER_1 tak aby pracował w trybie PWM. ;)

W pierwszym etapie w obsłudze przerwania nie było żadnej funkcji:

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


Stworzyłem funkcję fun_pwm() aby tylko za pomocą jej wywołania, obsługiwać wybrany port na którym miał być generowany sygnał PWM. Ale dzięki waszym uwagom ( za co serdecznie dziekuje :) ) widzę, że można by było wprowadzić parę modyfikacji, no ale tak jak wspominałem było to swojego rodzaju ćwiczenie programowania, w którym to wiadomo na początku coś się napisze i owszem działa, a po czasie dopiero widzi się, że można kilka rzeczy zmienić, poprawić. ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2014, o 14:46 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

RedLine napisał(a):
SylwekK napisał(a):
Chyba chodziło Ci o rozwiązanie sprzętowe ;)

Tak dokładnie miałem na myśli sprzętowe, no a napisałem programowe ;) mając przed oczami linie kodu w których konfiguruje się TIMER_1 tak aby pracował w trybie PWM. ;)

W pierwszym etapie w obsłudze przerwania nie było żadnej funkcji:

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


Stworzyłem funkcję fun_pwm() aby tylko za pomocą jej wywołania, obsługiwać wybrany port na którym miał być generowany sygnał PWM. Ale dzięki waszym uwagom ( za co serdecznie dziekuje :) ) widzę, że można by było wprowadzić parę modyfikacji, no ale tak jak wspominałem było to swojego rodzaju ćwiczenie programowania, w którym to wiadomo na początku coś się napisze i owszem działa, a po czasie dopiero widzi się, że można kilka rzeczy zmienić, poprawić. ;)

Tak wiem. Czytałem całego posta ;-) I zauważyłem, że funkcja pojawiła się dopiero na samym końcu.
Nie zmienia to jednak istoty sprawy którą poruszyłem. ;-)
Na pewno w tym przypadku niczym to nie grozi, jednak w większym projekcie...
Po prostu należy tego unikać.

_________________
Jestem początkujący i moje porady mogą być błędne



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

Strefa czasowa: UTC + 1


Kto przegląda forum

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