Witam, napisałem prosty program zmieniający za pomocą przycisków jasność diody LED. Na podstawie tego muszę napisać program, który będzie mi generował "automatycznie PWM". Działać to ma tak:
Współczynnik wypełnienia od 0 rośnie automatycznie do 100. Zwiększanie współczynnika wypełnienia inkrementuje się (zmienna wypelnienie++; ) po każdym przepełnieniu timera0, czyli od 0 rośnie co 1% do 100 czyli do stanu całkowitego zgaśnięcia diody - stan wysoki. W momencie osiągnięcia stanu wysokiego, czyli wypełnienie = 100% program ma zacząć dekrementację współczynnika wypełnienia od stanu wysokiego (100%) co 1% do stanu niskiego. Powstawać ma tak pulsacja diody. Napisałem program, który nie w pełni działa, mianowicie. współczynnik wypełnienia rośnie od 0 do 100% po czym widać szybki przeskok znów od 0 do 100%... Czyli cykl dekrementacji się zapętla i resetuje a tak nie powinno być.
Stworzyłem dwa liczniki, licznik1 zwiększa się co przerwanie o 1, porównywany jest ze zmienną wypelnienie i jeśli jest równe to przechodzi do zmiany stanu na porcie aby generować prostokąta (jest to PROGRAMOWY A NIE SPRZĘTOWY PWM, NIE MOGĘ UŻYWAĆ SPRZĘTOWEGO.), następnie mamy if ze zmienną pomocniczą zwieksz, jeśli jest równe 1 to następuje inkrementacja wypełnienia, dalej jak widać mamy sprawdzenie czy wypełnienie = 100%, jeśli tak to przypisz do zmiennych zwieksz i zmniejsz 0. Pozwala to na przejście w następnym cyklu timera do dekrementacji w if (zmniejsz == 0). Dzięki temu, ze zmienna zwieksz ma wartość 0, program nie będzie wchodził w if(zwieksz == 1) i nie będzie inkrementował wypełnienia. W momencie pisania programu powstał problem, jak można się domyśleć licznik1 zliczał ciągle w górę aż do przepełnienia rejestru w którym pracował, czyli od 0 do 255 potem automatycznie został zerowany. Ale przecież, gdy dojdziemy do sytuacji gdy wypełnienie = 255 (wartość w rejestrach ATmegi 0xFF) wtedy trzeba dekrementować zgodnie z licznikiem...ale nasz licznik1 inkrementuje, a wypełnienie ma być dekrementowane (myślę, że rozumiecie), tak więc w tym celu utworzyłem drugą zmienną licznk2 który początkowo ma wartość 0xFF, a w momencie dojścia wypełnienia do 100% (0xFF) pracuje licznik2 dekrementujący wypełnienie (bo przecież mamy warunek if((licznik1 == wypelnienie) || (licznik2 == wypelnienie)) aby wejść w zmianę stanu i zmieniać wypełnienie). Reasumując, nie działa to tak jak powinno. Wyżej pisałem jaki jest efekt. Mam prośbę, program nie jest duży, PORTA jako wyjście, a dokładnie PA0. Mógłby ktoś pomóc... ? Nie wiem jak zrobić, aby po osiągnięciu 100% wypełnienie zaczęło spadać, a nie nagle przeskakiwać znów na 0%. Liczę na pomoc userów elektrody. Pozdrawiam i życzę spóźnione szczęśliwego nowego roku
Współczynnik wypełnienia od 0 rośnie automatycznie do 100. Zwiększanie współczynnika wypełnienia inkrementuje się (zmienna wypelnienie++; ) po każdym przepełnieniu timera0, czyli od 0 rośnie co 1% do 100 czyli do stanu całkowitego zgaśnięcia diody - stan wysoki. W momencie osiągnięcia stanu wysokiego, czyli wypełnienie = 100% program ma zacząć dekrementację współczynnika wypełnienia od stanu wysokiego (100%) co 1% do stanu niskiego. Powstawać ma tak pulsacja diody. Napisałem program, który nie w pełni działa, mianowicie. współczynnik wypełnienia rośnie od 0 do 100% po czym widać szybki przeskok znów od 0 do 100%... Czyli cykl dekrementacji się zapętla i resetuje a tak nie powinno być.
Kod: C / C++
Stworzyłem dwa liczniki, licznik1 zwiększa się co przerwanie o 1, porównywany jest ze zmienną wypelnienie i jeśli jest równe to przechodzi do zmiany stanu na porcie aby generować prostokąta (jest to PROGRAMOWY A NIE SPRZĘTOWY PWM, NIE MOGĘ UŻYWAĆ SPRZĘTOWEGO.), następnie mamy if ze zmienną pomocniczą zwieksz, jeśli jest równe 1 to następuje inkrementacja wypełnienia, dalej jak widać mamy sprawdzenie czy wypełnienie = 100%, jeśli tak to przypisz do zmiennych zwieksz i zmniejsz 0. Pozwala to na przejście w następnym cyklu timera do dekrementacji w if (zmniejsz == 0). Dzięki temu, ze zmienna zwieksz ma wartość 0, program nie będzie wchodził w if(zwieksz == 1) i nie będzie inkrementował wypełnienia. W momencie pisania programu powstał problem, jak można się domyśleć licznik1 zliczał ciągle w górę aż do przepełnienia rejestru w którym pracował, czyli od 0 do 255 potem automatycznie został zerowany. Ale przecież, gdy dojdziemy do sytuacji gdy wypełnienie = 255 (wartość w rejestrach ATmegi 0xFF) wtedy trzeba dekrementować zgodnie z licznikiem...ale nasz licznik1 inkrementuje, a wypełnienie ma być dekrementowane (myślę, że rozumiecie), tak więc w tym celu utworzyłem drugą zmienną licznk2 który początkowo ma wartość 0xFF, a w momencie dojścia wypełnienia do 100% (0xFF) pracuje licznik2 dekrementujący wypełnienie (bo przecież mamy warunek if((licznik1 == wypelnienie) || (licznik2 == wypelnienie)) aby wejść w zmianę stanu i zmieniać wypełnienie). Reasumując, nie działa to tak jak powinno. Wyżej pisałem jaki jest efekt. Mam prośbę, program nie jest duży, PORTA jako wyjście, a dokładnie PA0. Mógłby ktoś pomóc... ? Nie wiem jak zrobić, aby po osiągnięciu 100% wypełnienie zaczęło spadać, a nie nagle przeskakiwać znów na 0%. Liczę na pomoc userów elektrody. Pozdrawiam i życzę spóźnione szczęśliwego nowego roku
![[ATmega32][C/AVR Studio 5] Regulacja świecenia diody LED - PWM [ATmega32][C/AVR Studio 5] Regulacja świecenia diody LED - PWM](https://obrazki.elektroda.pl/6202667300_1326048767.jpg)