Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Sinus 8051

27 Sie 2005 16:22 2166 9
  • Poziom 9  
    Witam.
    Mam takie pytanie. Jak wygenerować przebieg sinusoidalny w mikrokontrolerze z rodziny '51 , programowanym w języku C. Jest chyba funkcja sinus w bibliotece math.h, ale jak ją użyć do wygenerowania jednego okresu przbiegu sinusoidalnego od -5 do 5V ??
    Z gory dzieki za pomoc .
  • Poziom 30  
    Gdzieś już było o tym na forum...
    Zdaje się, że można to zrobić na PWM i filtrze RC...
    Można by też mostkiem H sterować i powstały przebieg prostokątny podać na małe trafo 1:1...
    Ale poszukaj bo tam powinno być coś więcej napisane...
  • Poziom 9  
    No tak, ale chodzi mi o wygenerowanie sinusa programowo ( za pomocą C), ponieważ narazie programuje w symulatorze mikrokontrolera
  • Admin grupy Projektowanie
    PWM albo zewnętrzny przetwornik C/A.
    Zależy jaką chcesz dokładność uzyskać.
    Mozna użyć swojej tablicy sinusów jeżeli nie potrzebna dużej dokładności,
    tyle że przebieg będzie bardziej postrzępiony.
    Aby uzyskać rozpiętość -5 do +5V proponuję użyć dwóch rezystorów o tej samej rezystancji podłączonych pod +5V i -5V na ich wspólnym połączeniu będzie ok 0V (względem masy).
    Można użyć helitrimów do kalibracji 0V albo odseparować wyjście kodensatorem.
    Na punkt 0V można podać przegieg TTL przez kondensator ( o pojemności zależnej od częstotliwości sygnału)
    to da rozpiętość około -2.5 do 2.5V.

    Zależy jaką wydajność potrzebujesz, przy większych prądach można użyc wzmacniacz operacyjny.
  • Poziom 9  
    No tak, ale chodzi mi o wygenerowanie sinusa programowo ( za pomocą C), ponieważ narazie programuje w symulatorze mikrokontrolera
  • Poziom 31  
    A gdzie chcesz dostać ten przebieg?
    Jeśli chodzi o generowanie wartości próbek przebiegu - to może powinieneś generować liczby z przedziału 0-255 z zerem np. w punkcie 128 (80h).
    y=127*sin(x)+128;
    x oczywiście zmieniać w żądanym zakresie z odpowiednio dobranym krokiem.
  • Poziom 32  
    Do jednego portu podpiąć drabinkę R2R, dalej wzmacniacz na operacyjnym z przesunięciem aby uzyskać wymagany zakres. Do portu, programowo oczywiście, ładować z tablicy wcześniej wyliczone próbki. Częstotliwość możesz zmieniać szybkością wpisów tych próbek.
  • Poziom 36  
    GienekS napisał:
    Do jednego portu podpiąć drabinkę R2R, dalej wzmacniacz na operacyjnym z przesunięciem aby uzyskać wymagany zakres. Do portu, programowo oczywiście, ładować z tablicy wcześniej wyliczone próbki. Częstotliwość możesz zmieniać szybkością wpisów tych próbek.


    Próbki musisz wysyłać synchronicznie (np w przerwaniach zegara), żeby nie zniekształcić przebiegów czasowych...a, prawda, programujesz w symulatorze...
  • Poziom 25  
    Najlepsza metoda to generacja w oparciu o skwantowaną tablicę próbek (sampli) przebiegu. Zmiana częstotliwości oczywiście poprzez zmianę czasu wystawiania danej wartości np. na port a na porcie przetwornika R2R lub np bardzo fajny układ AD7524 z analoga.

    Taki temat juz był:
    https://www.elektroda.pl/rtvforum/topic311117.html
    warto się z nim zapoznać.

    Programowe liczenia to dramat dla procesora :-) a konkretnie zbędne marnowanie i tak niedużej mocy obliczeniowej, nawet DSP opiera się o skwantowane teablice przebiegów.
  • Poziom 36  
    Stosunkowo szybkim sposobem wyliczenia sekwencji punktów funkcji sinus/cosinus jest całkowanie równania różniczkowego układu drgającego bez tłumienia metodami numerycznymi (np. RK-4, czy Adamsa).

    x''=-ax przy warunku x(0)=0 ; x'(0)=1

    Wyliczenie kolejnego punktu to kilka mnożeń i dodawań. W przypadku 32-bitowej reprezentacji stałoprzecinkowej ta metoda daje sensowną dokładność w obrębie pierwszego okresu przy stosunkowo niewielkich nakładach obliczeniowych (zwłaszcza jeśli procesor mnoży sprzętowo).
    Zaletą w stosunku do metody tablicowej jest niska zajętość pamięci niezależna od gęstości kwantowania i dokładności (długości) reprezentacji.

    Przykład - symulacja (OpenOffice.org 1.9.122 Calc):

    reprezentacja 16-bitowa,
    metoda całkowania najprostsza z możliwych - Eulera (1 dodawanie, 1 odejmowanie, 2 mnożenia na 1 punkt)

    Dodatkowo do mnożenia użyłem współczynnika 1/256 co pozwala mi policzyć kolejny punkt przy pomocy jednego dodawania i jednego odejmowania 16 bitowego (bez mnożenia), lecz niestety wymusza określoną liczbę punktów wynikowych (ok (Π/2)*256=402 na 1/4 okresu). W takim wariancie, przy przechowywaniu kolejnych punktów reprezentacji np. w rejestrach procesora wyliczenie kolejnego punktu reprezentacji funkcji sinus i cosinus to dokładnie dwa rozkazy 8-bitowego dodawania i dwa rozkazy odejmownia. Czas wykonania porównywalny z pobraniem wyniku z tablicy. Obliczenia realizuję w 1/4 okresu. Pozostałe części są lustrzanymi odbiciami i mogą być liczone z tych samych równań przy zmienionych warunkach początkowych. Okresowa korekta punktu startu jest niezbędna ze względu na kumulowanie się błędów.

    Algorytm wygląda tak

    Code:
    var x,y : smallint;   //16 bitów
    

    x:=0;
    y:=32767;       //2-bajtowa reprezentacja stałoprzecinkowa liczb z zakresu -1..1 (1.0 == 32767, 0==0, -1 == -32767)

    for i:=0 to 402 do
      begin
      Oddaj_Punkt_SINUSA_COSINUSA(x,y);     //Funkcja wykorzystująca wyliczoną wartość
      Dec(y,Hi(x));  //Całkowanie do kolejnego punktu - metoda Eulera
      Inc(x,Hi(y))
      end;
    end;


    Błąd względny wyliczonego sinusa nie przekracza 0.35% (dokładność nie gorsza od 8 bitów). Zwiększenie liczby punktów np przez interpolację, zmniejszenie bez wzrostu nakładów np przez zmianę współczynnika kroku (1/128, 1/64). Widać, że nawet zastosowanie najprymitywniejszej (i najmniej pracochłonnej) metody całkowania daje wyniki, które mogą być wykorzystane w praktyce.

    Stosunkowo prosto tą samą metodą, tylko przez zmianę warunków początkowych można wygenerować dwa przebiegi przesunięte względem siebie o określony kąt (np 1/3 okresu).