logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

PWM programowo - C - _delay_ms - AT90PWM3B

artgme 21 Mar 2011 13:05 1681 13
  • #1 9303524
    artgme
    Poziom 10  
    Cześć,
    Napisałem program na AT90PWM3B (16MHz), który w sposób programowy zmienia wartość wypełnienia PWM. Impulsy są generowane w przerwaniu (CTC - Compare Match). PWM ma wartość 50 Hz - ta część działa prawidłowo.

    Nie zmienia się jednak wartość wypełnienia. Wypełnienie poszczególnych impulsów jest równe początkowej wartości zmiennej. Program zakłada, że wartość ta powinna zmieniać się co pół sekundy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Z moich obserwacji wynika, że program tylko raz wywołuje program główny. Tak, jakby nie widział while(1).
    Jeżeli ktoś wie, w czym tkwi błąd, to proszę o pomoc.
    Pozdrawiam
  • #3 9303721
    artgme
    Poziom 10  
    Jest zdefiniowana w projekcie. Program piszę w AVR Studio.
  • #5 9303743
    artgme
    Poziom 10  
    Przerwanie wywołuje się prawidłowo (na oscyloskopie są widoczne impulsy o założonej częstotliwości, ich wypełnienie jednakże nie zmienia się - i tutaj tkwi ów błąd).
  • #6 9303752
    dondu
    Moderator na urlopie...
    Jednak spróbuj taki wektor przerwania: TIMER0_COMP_A_vect

    Dodano po 7 [minuty]:

    Dla Twojego procesora właściwym wektorem jest ten podany przeze mnie:
    http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
    Jeżeli nie pomogło to napisz.

    Dodano po 10 [minuty]:

    Powiedz mi co ma robić ta pętla:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Bo w takiej formie generuje duże opóźnienie.
    Czy to zamierzony cel?
  • #7 9303827
    artgme
    Poziom 10  
    Niestety nie pomogło. Przy tym wektorze program nie wchodzi w przerwania.
  • #8 9303835
    dondu
    Moderator na urlopie...
    artgme napisał:
    Przy tym wektorze program nie wchodzi w przerwania.

    Czy na pewno masz prawidłowo wybrany procesor w projekcie?
    Według wykazu z linku (wiarygodny) powinieneś mieć ten wektor, który podałem (chyba, że się mylę).
  • #9 9303844
    artgme
    Poziom 10  
    Pętla jest zamierzonym celem. Za jej pomocą chciałem zaobserwować zmiany wartości wypełnienia sygnału na oscyloskopie (zmiana co 0,5 sec.).

    Modyfikując program zauważyłem, że fragment programu będący w 'while(1)' wykonuje się tylko raz. Sprawdziłem jednocześnie przed chwilą program na programowym debugerze i działa prawidłowo. Prawidłowość ta nie wiąże się jednak z poprawną pracą procesora.
  • #10 9303861
    dondu
    Moderator na urlopie...
    artgme napisał:
    ... zmiana co 0,5 sec.

    To zastąp ją po prostu: _delay_ms(500)
    Oczywiście nie ma to wpływu na Twój problem.

    artgme napisał:
    Prawidłowość ta nie wiąże się jednak z poprawną pracą procesora.

    Przyczyna jest gdzieś indziej niż while(1).

    Dodano po 8 [minuty]:

    Nie odpowiedziałeś na moje pytanie:
    dondu napisał:
    Czy na pewno masz prawidłowo wybrany procesor w projekcie?


    Dodano po 3 [minuty]:

    Już wiem :)
    Zastanów się jak wykonuje się pętla while i czego brakuje Ci na jej końcu.
    Innymi słowy, co się stanie zaraz po: maly4=100;
  • #11 9303940
    artgme
    Poziom 10  
    - W projekcie mam dobry procesor.

    - Kompilator nie rozpoznaje podanego wektora:

    ../pwmprog.c:167: warning: 'TIMER0_COMP_A_vect' appears to be a misspelled signal handler

    - Nie używam składni typu: _delay_ms(500), ponieważ w pliku delay.h jest następująca informacja:

    The maximal possible delay is 262.14 ms / F_CPU in MHz.

    - Nie wiem czego może mi brakować... Klamrę mam, w przeciwnym razie kompilator wyłapałby takie błędy.
  • Pomocny post
    #12 9303945
    dondu
    Moderator na urlopie...
    Brakuje Ci drugiego : _delay_ms(500)

    Dodano po 4 [minuty]:

    artgme napisał:
    Nie używam składni typu: _delay_ms(500), ponieważ w pliku delay.h jest następująca informacja:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.

    Ale jest także napisane:

    Cytat:
    When the user request delay which exceed the maximum possible one,
    _delay_ms() provides a decreased resolution functionality. In this
    mode _delay_ms() will work with a resolution of 1/10 ms, providing
    delays up to 6.5535 seconds (independent from CPU frequency). The
    user will not be informed about decreased resolution.

    Czyli możesz śmiało robić wielkie opóźnienia.

    Dlatego też, parametr milisekund jest typu DOUBLE:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #13 9303965
    artgme
    Poziom 10  
    Masz rację... taki głupi błąd... Dziękuję za pomoc
REKLAMA