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



Teraz jest 13 maja 2026, o 17:34


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
Autor Wiadomość
 Tytuł: Timer do PMW
PostNapisane: 18 gru 2013, o 22:18 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 25 lis 2013
Posty: 108
Pomógł: 0

Próbuje dojść do ładu z timerem1 dla PWM , zamiast delay-ów , ale mam za mało doświadczenia w programowaniu , dlatego mam prośbę koledzy rzućcie okiem na kod gdzie jest błąd . Dodam że na delay-ach działa. Dzięki z góry i Pozdrawiam.


Kod:
[syntax=c]#include <avr/io.h>
//#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

// definicje zmiennych do sterowania 4 kanałami programowych PWM
// zmienne typu uint8_t, rozdzielczość 8-bitowa
volatile uint8_t pwm1, pwm2, pwm3, pwm4;
volatile uint16_t Timer1;

// główna funkcja programu main()
int main(void)
{

   //***** PROGRAMOWY PWM - 4 KANAŁY*******
   // ustawienie pinów kanałów programowych PWM jako WYJŚCIA
   DDRC |= (1<<PC7)|(1<<PC6)|(1<<PC5)|(1<<PC4);

   // wyłączenie diod LED podłączonych katodami do wyjść
   PORTC |= (1<<PC7)|(1<<PC6)|(1<<PC5)|(1<<PC4);


   //***** SPRZĘTOWY PWM - *******
   // ustawienia TIMER2 w Fast PWM
   TCCR0 |= (1<<WGM01)|(1<<WGM00);      // tryb Fast PWM
   TCCR0 |= (1<<COM01);            // clear at TOP
   TCCR0 |= (1<<CS00);               // preskaler = 1
   OCR0=255;                     // wygaszenie diody w kanale PWM


    //  TIMER1 dla F_CPU=11,0592MHz */
     TCCR1B |= (1<<WGM12);            /* tryb CTC */
     TCCR1B |= (1<<CS12)|(1<<CS10);  /* preskaler = 1024 */
     OCR1A = 9;                       /* podział przez 10  */
     TIMSK |= (1<<OCIE1A);            /* przerwanie CompareMatch */
        // tyknięcie 1ms



   // ustawienia TIMER2 w tryb CTC
   TCCR2 |= (1<<WGM21);   // tryb  CTC
   TCCR2 |= (1<<CS20);      // preskaler = 1
   OCR2 = 199;            // dodatkowy podział częsttotliwości przez 200
   TIMSK |= (1<<OCIE2);   // zezwolenie na przerwanie CompareMatch




   sei();            // odblokowanie globalne przerwań

   uint8_t i;         // definicja zmiennej i na potrzeby pętli for()


   while(1)
   {
      // pętla rozjaśniająca 4 diod LED
      for(i=0;i<255;i++)
      {
         OCR0=i;      // ta dioda będzie ulegała ściemnianiu w tej pętli
         pwm1=i;
         pwm2=i;
         pwm3=i;
         pwm4=i;


         // W związku z dużą nieliniowością zależności prądu diod LED
         // i jasności świecenia, wprowadzone jest zmienne opóźnienie
         // przy wartościach bliskich zera aby zminimalizować ten efekt
         if(i>50) Timer1=3;
         else Timer1=10;
      }
      // całkowite rozjaśnienie diody LED przez 100ms
      OCR0=255;
      // rozświetlenie na maksimum przez 100ms
      pwm1=255;
      pwm2=255;
      pwm3=255;
      pwm4=255;

      Timer1=500;

      // pętla stopniowo ściemniająca 4 diod LED
      for(i=255;i;i--)
      {
         OCR0=i;      // ta dioda będzie ulegała rozjaśnianiu w tej pętli
         pwm1=i;
         pwm2=i;
         pwm3=i;
         pwm4=i;


         // W związku z dużą nieliniowością zależności prądu diod LED
         // i jasności świecenia, wprowadzone jest zmienne opóźnienie
         // przy wartościach bliskich zera aby zminimalizować ten efekt
         if(i>50) Timer1=3;
         else Timer1=10;
      }
      // całkowite rozjaśnienie diody LED przez 100ms
      OCR0=0;
      // całkowite wygaszenie diod LED przez 100ms
      pwm1=0;
      pwm2=0;
      pwm3=0;
      pwm4=0;

      Timer1=500;
   }

}

ISR( TIMER1_COMPA_vect )


      {
            uint16_t n;

             n = Timer1;
             if (n) Timer1 = --n;

     }

// ciało procedury obsługi przerwania Compare Match Timera2
ISR( TIMER2_COMP_vect )
{
   static uint8_t cnt; // definicja naszego licznika PWM

   // bezpośrednie sterowanie wyjściami kanałów PWM
   if(cnt>=pwm1) PORTC |= (1<<PC7); else PORTC &= ~(1<<PC7);
   if(cnt>=pwm2) PORTC |= (1<<PC6); else PORTC &= ~(1<<PC6);
   if(cnt>=pwm3) PORTC |= (1<<PC5); else PORTC &= ~(1<<PC5);
   if(cnt>=pwm4) PORTC |= (1<<PC4); else PORTC &= ~(1<<PC4);


   cnt++;   // zwiększanie licznika o 1

}[/syntax]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 gru 2013, o 22:40 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 208
Lokalizacja: Kraków
Pomógł: 16

1. Kod wrzucamy w syntax-ie ale bez dodatkowych znaczników code.
2. Opisz dokładniej co nie działa. Nie piszesz nawet jaki masz procesor. Nie wiem czy dobrze konfigurujesz bity konfiguracyjne timerów.
3. Jeżeli chcesz korzystać ze sprzętowego PWM z timer-a to i tak musisz skonfigurować piny timera jako wyjścia.
4. Na pierwszy rzut oka wydaje mi się, że nieprawidłowo używasz timera programowego. Ale temu się jeszcze przyglądne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 gru 2013, o 22:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 lut 2013
Posty: 376
Lokalizacja: Kłopoty-Stanisławy
Pomógł: 33

Gdzieś ktoś kiedyś napisał, że aby pozbyć się delay'ów w PWM to "naj sam wpierw" należy się zastanowić czym jest PWM jako taki. Jak działa, kiedy działa jak wygląda.

W ten sposób raczej nie zadziała ( chociaż mam nadzieję, że Ci się uda). Ja ostatnio sporo czasu spędziłem nad tym żeby coś takiego zrobić i się ..... udało, ale na razie tylko częściowo. Pwm jest co prawda, ale mam jeszcze problem z rozjasnianiem i ściemnianiem i pewnie jeszcze do tego wrócę jak się z innymi rzeczami ogarnę. Na razie kod nie nadaje się do publikacji .... ( Mirek kazałby mi pewnie ze 10 ...... e100 pompek zrobić ... )

Z trzeciej strony to po co się w to bawić ? Są dedykowane układy PWM ( PCA9685) - czytaj u SunRiviera na stronce.

A Do prostego wysterowania kilku kilkunastu "schodów" w zupełności wystarczy PWM programowy.

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

Przepraszam za taki demotywujący post ale może chociaż Ty oszczędzisz trochę czasu .....

Ja jak już mniej więcej skumałem co i jak to ogarnąłem się że nie było warto ....

_________________
50 znaków Atnela ....



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 gru 2013, o 22:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 25 lis 2013
Posty: 108
Pomógł: 0

Procek ATmega 32 , Timer0 - sprzętowy PWM , Timer2 - programowy PWM , Timer1 - programowy timer , do obsługi opóźnień .
i właśnie timerem1 mam problem , wszystko działa jak za timer1 w kodzie wstawię delay-e , tak jak to opisane w BB.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 gru 2013, o 23:12 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 208
Lokalizacja: Kraków
Pomógł: 16

Całkowicie źle podchodzisz do opóznień generowanych za pomocą timera sprzętowego. Chodzi tutaj o sprawdzaniu w if-ie czy timer już odliczył zadany odcinek czasu.

------------------------ [ Dodano po: 3 minutach ]

Wpisanie w programie
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
nie powoduje wygenerowania opóźnienia 500ms. To nie działa dokładnie tak samo jak zwykły delay. W BB masz to dokładnie opisane, wczytaj się.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 gru 2013, o 23:56 
Offline
Moderator
Avatar użytkownika

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

Ja w ogóle nie rozumiem - jak można aż TAK MOCNO utrudniać sobie życie :(

no jeśli ja bym nie rozumiał timerów programowych jeszcze (a tak też miałem kiedyś przecież!) ... to nigdy bym nie wpadł na pomysł żeby sobie je (przepraszam za określenie) "wklepać" razem z jakimś ogromnym kodem do testowania gdzie np do końca nie rozumiem jak w ogóle sobie organizować na różne sposoby opóźnienia i już nie ważne czy z delayami czy bez.

AndreAs ---> wiesz od czego ja zaczynałem trenowanie timerów programowych ? Od migania za ich pomocą diodami LED. Kod krótki, prosty i łatwy do ogarnięcia po to aby do bólu zrozumieć istotę timerów programowych .... I taką drogę pokazuję w Bluebooku ...

tymczasem ty - nagle próbujesz wplatać timery programowe w kod, który i bez nich sprawia ci nieco kłopotu ... po co ?

Już nie wspomnę - że nawet jak zadajesz pytanie to komu - sam się zastanów będzie się chciało analizować jakiś tasiemiec - zamiast precyzyjnie zadanego pytania ze wskazaniem na kłopot w kodzie, wskazania fragmentu, który sprawia ci problem ....

tymczasem wklejasz hektolitr kodu - po raz kolejny zresztą nie w znacznikach

[ syntax = c ]

tylko z uporem w

[ code ]

co powoduje kolejny problem żeby wygodnie analizować kod tym którym zadajesz pytanie ....

Warto pomyśleć i tego też staram się uczyć na tym forum, jak dobrze zadawać pytania aby uzyskać szybko dobre i precyzyjne odpowiedzi, a nie wkleić mnóstwo kodu i zapytać - "powiedzcie mi co tu jest źle z tym timerem"

tak jak kolega wyżej mówił - no wszystko jest źle z timerem programowym dlatego proszę

wklej, krótki kod np z miganiem dwoma diodami LED w różnym tempie za pomocą dwóch timerów programowych - jak to okiełznasz - do końca to zobaczysz że dalej już pójdzie ci z górki ok ? ;)

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

Juffre napisał(a):
W BB masz to dokładnie opisane, wczytaj się.


DOKŁADNIE - wczytaj się, wypróbuj tamtejszy przykład z diodą LED a gdy czegoś nie zrozumiesz to pytaj .... bo uwierz mi - staram się prowadzić od podstaw ... ale jak ktoś chce je pominąć i skoczyć od radu na za głęboką wodę - to nie ma co się dziwić że się sam podtapia


Autor postu otrzymał pochwałę

_________________
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: 19 gru 2013, o 16:54 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 25 lis 2013
Posty: 108
Pomógł: 0

Mirku skoro mamy zacząć od dwóch migających diód , to żaden problem , bo i tak jestem wdzięczny tobie i wszystkim innym osobom na tym forum , za poświęcony czas .
Dobra no to krótko -diody z timerem programowym mi działają , ale czekam na uwagi i sugestie co można tym kodzie poprawić Dzięki i Pozdrawiam.


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: 19 gru 2013, o 17:25 
Offline
Moderator
Avatar użytkownika

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

A! no i super - teraz jest krótki przejrzysty kod - zwróć uwagę - że twoje polecenie LEDx_TOG; jest jakby "procesem" który odbywa się co określoną ilość czasu, pomimo że pętla główna while(1) .... zapiernicza (sorki za wyrażenie) nadal jak motorek - czyli mamy odpalane procesy bez delaya i w sposób nieblokujący ...

no to teraz z tego punktu widzenia pomyśl jak taki mechanizm - takiego IF() zastosować dalej .... o ile do końca i w PEŁNI rozumiesz jak on działa .... i nie ma w razie czego wstydzić się przyznać - że jeszcze nie do końca np czegoś rozumiesz ...

ale dobra dalej ....

teraz chciałbyś mieć opóźnienie w pętli .... czyli mamy np taki przypadek:

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

i chciałbyś to zamienić na użycie z timerem ;) ... no to przecież nie tak jak to wcześniej próbowałeś robić bo to wskazywało właśnie że gdzieś czegoś nie rozumiesz i dlatego prosiłem o powrót do początków czyli timera programowego z diodą ...

a zatem można to zrobić np tak (podkreślam - na przykład - co oznacza że można jeszcze na milion innych sposobów - żeby nie urodził się w głowie pomysł że tylko tak! ... ja chcę po prostu naprowadzić jak najprostszymi przykładami na dalsze już samodzielne myślenie i
kombinowanie w tym zakresie a nie wciskanie komuś (jak to robią na innych blogach) ;) że TYLKO tak się programuje

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


oczywiście musisz pamiętać o tym, że jeśli to będzie działo się w pętli głównej to ładnie co jakiś czas wykona się ta operacja "coś tam coś tam" tak jak wyżej w pętli for .... ale !!! ale w międzyczasie po każdym wykonaniu mogą się jeszcze równolegle odbyć kolejne działania z innego timera programowego - a zatem już CAAAAAŁKIEM inaczej trzeba zacząć podchodzić do pisania kodu

a nie że weźmiesz sobie przykładowy kod z delayami - wpiszesz sobie w te miejsca jakiś tam Timer1 .... i co ? to tak jakbyś chciał zastąpić delaya innym delayem - czyli zatrzymać na chwilę wykonywanie innych procesów - a pewnie docelowo nie o to ci chodzi

więc jak widzisz - warto jeszcze troszkę poćwiczyć z diodami - bo one dają lepszy obraz - po prostu wymyślać sobie zadania dla takich 2-3 albo i 10 diod ... i kombinować np

chcę żeby najpierw mi migała pierwsza dioda LED co 100ms na timerze programowym 1, a gdy skończy to wtedy druga ma pomigać co 50ms na timerze 2, a w międzyczasie trzecia ma non stop migać co 400ms na timerze 3

widzisz ? .... o taką metodą ćwiczymy sobie w najprostszy sposób timery programowe, trzeba sobie zacząć wyznaczać mniejsze cele i je ogarniać - a nie od razu rzucić się na przerobienie nawet niewielkiego kodu - ale bez zrozumienia jak to działa (albo gdy wydaje ci się tylko że wiesz jak to działa) bo nawet ten niewielki kod będzie wtedy dla ciebie za dużym głazem do podniesienia z tą technologią którą na razie znasz ok?


Autor postu otrzymał pochwałę

_________________
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: 22 gru 2013, o 19:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 25 lis 2013
Posty: 108
Pomógł: 0

Tak jak mi zasugerował Mirek postanowiłem zrobić ćwiczenie opisane niebieskim drukiem. I tak działa pierwszy kod , a drugi nie , powiedzcie mi dlaczego? Pozdrowienia.


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



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: 22 gru 2013, o 20:38 
Offline
Użytkownik
Avatar użytkownika

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

Witam
przeanalizuj co robi poniższy fragment Twojego drugiego programu

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


to nie oto Ci chodziło :)
w pierwszym programie masz to dobrze zrobione

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


Jeśli coś pokiełbasiłem to przepraszam ale się uczę :D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 gru 2013, o 21:41 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 25 lis 2013
Posty: 108
Pomógł: 0

Miałem problem z drugim kodem który mi w ogóle nie działał , więc postanowiłem poprawić pierwszy , ponieważ nie działał tak do końca tak jakbym sobie życzył , a mianowicie gdy działała jedna dioda to druga powinna być wyłączona ,a tak nie było i przy pracy jednej czasami działała druga . Ale go poprawiłem ku mojej radości we własnym zakresie . Poniżej poprawiony prawidłowo działający kod.

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: 18 lip 2016, o 10:48 
Offline
Nowy

Dołączył(a): 16 lip 2016
Posty: 2
Pomógł: 0

Witam, ze względu na to, iż jest to pierwszy mój post proszę o wybaczenie kolegów ewentualnych błędów.
Mam pytanie (zgodnie z sugestią P.Mirka by samemu kombinować)odnośnie podobnego przykładu z książki BB. Otóż czy utworzenie timerów w ten sposób:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


jest tożsame (oczywiście "na oko" działa tak samo) z przykładem z książki?
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: 18 lip 2016, o 21:07 
Offline
Moderator
Avatar użytkownika

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

Cytuj:
jest tożsame (oczywiście "na oko" działa tak samo) z przykładem z książki?

Pewnie, że jest tożsame tylko działa o wiele gorzej i wolniej i to na zasadzie im więcej dodajesz timerów programowych tym gorzej z twoim sposobem. Oczywiście sama przeróbka absolutnie będzie działać ;)

Jeśli chcesz wiedzieć dlaczego gorzej jest twoim sposobem to weź sobie podejrzyj plik *.lss po kompilacji i zobacz jaka masakra się dzieje gdy porównasz dwa sposoby. Dlaczego dużo korzystniej jest to zrobić tak jak pokazałem jednak w książce.

_________________
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  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 

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