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

[Atmega32] - PWM i błąd podczas kompliowania przykładu z książki

eiliat 20 Gru 2014 09:18 885 4
REKLAMA
  • #1 14238804
    eiliat
    Poziom 15  
    Witam, Korzystam z książki Tomasza Francuza i na swojej Atmedze32 próbuje skompilować kod, którym odczytam wypełnienie PWM sygnału. Podczas kompilacji dostaje błąd:
    Cytat:
    Error 1 'GTCCR' undeclared (first use in this function)
    Error 4 'ICIE1' undeclared (first use in this function)
    Error 3 'PSRSYNC' undeclared (first use in this function)


    To jest ten kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • REKLAMA
  • Pomocny post
    #3 14240006
    Piotr Piechota
    Poziom 22  
    zamiast TIMSK1 użyj TIMSK gdzie znajdziesz ICIE1
    PSRSYNC w M32 nazywa się chyba PSR10 i jest w SFIOR a nie w GTCCR jak w M168
  • REKLAMA
  • #4 14240830
    eiliat
    Poziom 15  
    Piotr Piechota napisał:
    zamiast TIMSK1 użyj TIMSK gdzie znajdziesz ICIE1
    PSRSYNC w M32 nazywa się chyba PSR10 i jest w SFIOR a nie w GTCCR jak w M168


    Tak, to dało rozwiązanie, że kod mi się kompiluje. Problem w tym, że na wejście dostaje sygnał 50 Hz (ramka trwa 20ms) a sygnały wysoki w przedziale 0-2 ms. Obojętnie jakie dam wypełnienie (0-2ms) to ciągle na z tego kodu otrzymuje wartości 44-47.

    Dlaczego tak się dzieje? Konfiguracja jest nieprawidłowa?


    EDIT: Mój kod wygląda następująco:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    I tak jak mówiłem, dostaję cały czas około 40-kilku procent. Gdzie maks to 10% (2ms wypełnienie na 20 ms okresu).
  • #5 14261402
    Andrzej__S
    Poziom 28  
    Jeśli jeszcze aktualne :)

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

    W ten sposób to obliczasz częstotliwość sygnału, a nie wypełnienie. Powinno być raczej:

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

    przy czym wynik będzie raczej mało precyzyjny: dla sygnału wejściowego o którym pisałeś - od 0% do 10% z rozdzielczością 1%. Zastosowanie arytmetyki zmiennoprzecinkowej jest w 8-bitowych AVR zasobożerne, więc lepiej byłoby liczyć:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    i później w wyniku przesunąć przecinek o 2 miejsca w lewo. Zwiększy to rozdzielczość do 0,01%.

    Manipulacja stanem licznika TCNT1 wewnątrz procedury obsługi przerwania Input Capture wprowadza pewien błąd. Będzie on w tym konkretnym przypadku wynosił ok. 3-4 mikrosekundy. W stosunku do okresu trwającego 20 000 mikrosekund to relatywnie niewiele, ale jeśli czasy trwania impulsu (stanu wysokiego) będą faktycznie zbliżone do zera, np. będą wynosiły kilkanaście/kilkadziesiąt mikrosekund, może to być błąd znaczący. Osobiście stosuję inną technikę wykorzystującą Output Compare do kontroli "przekręcenia" licznika.

    Jeśli sprawa dotyczy sygnału sterującego serwem modelarskim, to czas trwania impulsu będzie się zawierał od ok. 1ms do ok. 2ms, i wtedy takie rozwiązanie będzie wystarczające (błąd praktycznie bez znaczenia). Poza tym w takim przypadku wypełnienie jest mniej istotne, ważniejszy jest czas trwania impulsu. W tym konkretnym przypadku zmienna ts zawiera (bez konieczności przeliczania) czas trwania impulsu w mikrosekundach.
REKLAMA