Politechnika Warszawska Wydział Elektryczny Laboratorium Podstaw Techniki Mikroprocesorowej Skrypt do ćwiczenia M.43 Obliczanie wartości średniej oraz amplitudy z próbek sygnału język C
.Część teoretyczna Jednym ze sposób obliczania amplitudy jest metoda uśredniania. Zakładając, Ŝe mamy dane próbki składowej podstawowej sygnału przedstawione równaniem gdzie: x n) = m cos( nω + ) (3.) ( ϕ Tp 2π Ω = ω Tp = 2π = (3.2) T N gdzie - liczba próbek w okresie sygnału. Poprzez uśrednienie wartości bezwzględnej dla przedziału czasowego, będącego wielokrotnością półokresu sygnału, otrzymujemy amplitudę tego sygnału. Dla danego przykładu naleŝy obliczyć sumy dyskretne z dostępnych próbek. Wartość tych sum nie jest uzaleŝniona tylko od amplitudy sygnału, lecz równieŝ od chwili, w jakiej rozpoczęło się próbkowanie sygnału, a dokładniej od czasu pomiędzy startem przetwarzania i przejściem sygnału przez zero. Maksymalna wartość tego czasu maleje wraz ze wzrostem częstotliwości próbkowania sygnału. Aby uzyskać symetryzację obliczonych sum trzeba załoŝyć wartość średnią współczynnika, który jest skojarzony z obliczaną sumą. Dla sumy obliczanej z połowy okresu otrzymuje się n= x ( n) = S av (3.3) m gdzie: S av π =,5ctg 2 (3.4) Uwzględniając te załoŝenia obliczenie amplitudy moŝe odbyć moŝe odbyć się w następujący sposób m π = 2tg 2 x n= ( n) (3.5) Pojawienie się błędu pomiarowego, związanego z przypadkowym czasem próbkowania, powodującego wahania obliczonej wartości sumy, zaleŝy od ilości próbek w jednym okresie sygnału, czyli w efekcie od częstotliwości próbkowania sygnału. Czym większa częstotliwość próbkowania, tym mniejszy błąd pomiaru. W związku z tym, jeŝeli częstotliwość próbkowania będzie dostatecznie duŝa to moŝna załoŝyć następujące równanie będzie prawdziwe m = π N x n= ( n) (3.6) Obliczenia amplitudy w programach zostały wykonane zgodnie ze wzorem (3.6).
.. Program obliczający wartość średnią oraz amplitudę (język C) Opisane w tym rozdziale programy znajdują się w katalogu c\pr4 - obl sr i ampl. Zadaniem tego programu jest obliczanie wartości średniej oraz amplitudy sygnałów podawanych na wejście analogowe oraz kontrolera DSM-5. Sygnały te za pomocą multipleksera przekazywane są na przetwornik analogowo-cyfrowy, gdzie następuje ich próbkowanie oraz kwantyzacja. Częstotliwość próbkowania wynosi 8Hz, co w efekcie daje 6 próbek na jeden okres sygnału wejściowego przy załoŝeniu, Ŝe częstotliwość zmian sygnału badanego wynosi 5Hz. Obsługa timerów, przerwań oraz zapis próbek w tym programie odbyły się zgodnie z opisaną wcześniej częścią wspólną. Program ten funkcjonuje według schematu przedstawionego na Rys... Deklaracja zmiennych, ustawienie trybu pracy timerów oraz zezwolenia na przerwania Ustawienie liczników timerów oraz start Timera Obsługa przerwań od Timera: - ustawienie Timera - wybór wejścia na multiplekserze - start przetwornika A/C - nastawienia Timera - start Timera Obsługa przerwań od Timera: - zapis wartości z przetwornika A/C - wybór wejścia na multiplekserze - start przetwornika A/C - start Timera Pętla nieskończona Instrukcje obliczające wartość średnią Instrukcje obliczające amplitudę Obsługa przerwań od Timera: - zapis wartości z przetwornika A/C Skok do początku bloku Rys... Schemat blokowy działania programu Program główny rozpoczyna się od deklaracji zmiennych oraz wskaźników, za pomocą których pobrane zostaną zapisane w pamięci wartości próbek. Po wstępnym ustawieniu wartości tych wskaźników zostały ustawione tryby pracy timerów. Timer pracuje w trybie, czyli jako pełen rejestr 6 bitowy. W trybie tym timer moŝe odliczać maksymalnie do wartości 65536. Licznik tego timera został wstępnie ustawiony na wartość 64384, co powoduje, Ŝe timer zlicza 52 impulsy zegarowe odmierzając w ten sposób czas wynoszący,25ms. Odliczony czas, jest czasem pomiędzy pobieraniem kolejnych próbek badanego sygnału. Drugi timer pracuje w trybie 2, czyli jako rejestr 8 bitowy TL, przy czym po przekroczeniu maksymalnej wartości (256) następuje wystawienie flagi oraz załadowanie zawartości rejestru TH do rejestru TL. Timer ten odmierza czas potrzebny przetwornikowi A/C na dokonanie przetwarzania. W kolejnym etapie programu zostało ustawione ogólne zezwolenie na przerwania, następnie zezwolenie na przerwanie od timera oraz. Po nastawieniu liczników timerów nastąpił start timera oraz zainicjowany został wyświetlacz LCD. Kod opisanych powyŝej czynności przedstawia się następująco:
void main(void) short srednia; /*Deklaracja zmiennej dla wartosci sredniej sygnalu */ short srednia; /*Deklaracja zmiennej dla wartosci sredniej sygnalu */ short amplituda; /*Deklaracja zmiennej dla wartosci amplitudy sygnalu */ short amplituda; /*Deklaracja zmiennej dla wartosci amplitudy sygnalu */ short modul; /*Deklaracja zmiennej do obliczania modulu*/ char licz = ; /*Deklaracja licznika dla petli*/ unsigned char *pam,*pam; /*Deklaracja wskaznikow komorek pamieci*/ pam = x22; pam = x22; TMOD = x2; EA = ; ET = ; ET = ; TH = xfb; TL = x8; TH = x; TL = x; TR = ; lcd_init(); /*Nadanie adresu wskaznikowi pamieci*/ /*Nadanie adresu wskaznikowi pamieci*/ /*Ustawienie trybow pracy timerow*/ /*Ogólne zezwolenie na przerwania*/ /*Zezwolenie na przerwania od timera T*/ /*Zezwolenie na przerwania od timera T*/ /*Nastawienie licznika T*/ /*Nastawienie licznika T*/ /*Nastawienie licznika T*/ /*Nastawienie licznika T*/ /*Start licznika T*/ /*Zainicjowanie wyswietlacza LCD*/ Dalsza część programu wykonywana jest w pętli nieskończonej.... Obliczenie wartości średniej Polecenie while() rozpoczyna pętle nieskończoną, w której wykonywane są obliczenia oraz realizowane jest wyświetlanie wyników. Opóźnienie jest niezbędne, aby dane wyświetlane na ekranie LCD były czytelne. Funkcja if sprawdza, czy moŝna wykonywać obliczenia. JeŜeli zmienna pozwolenie ma wartość oznacza to, Ŝe nie zostały zapisane próbki dla całego okresy sygnału. Obliczenia wykonane zostaną dopiero wtedy, kiedy w przerwaniu odpowiadającym za zapis próbek zmiennej pozwolenie nadana zostanie wartość. Obliczenie wartości średniej realizowane jest poprzez zsumowanie wszystkich próbek a następnie dzielenie otrzymanej wartości przez ilość próbek. Kod realizujący obliczenie wartości średniej przedstawiono poniŝej: while () /*Wywolanie petli nieskonczonej*/ delay(2); if (pozwolenie == ) /*Sprawdzenie, czy moŝna wykonywac obliczenia*/ /* OBLICZENIE WARTOSCI SREDNIEJ KANAL */ srednia = ; pam = x222; for (licz = ; licz < 6; licz++) srednia = srednia + *pam; pam++; srednia = (srednia/6); /* OBLICZENIE WARTOSCI SREDNIEJ KANAL */
srednia = ; pam = x223; for (licz = ; licz < 6; licz++) srednia = srednia + *pam; pam++; srednia = (srednia/6); Przed dokonaniem obliczeń zmienna, w której zapisany zostanie wynik została wyzerowana, aby wynik poprzednich obliczeń nie wpłyną na wynik aktualnych obliczeń. Do wskaźnika wpisany został adres komórki pamięci, w której znajduje się pierwsza próbka sygnału. Sumowanie próbek odbyło się w pętli for wykonanej szesnaście razy. Przy kaŝdym przejściu pętli do zmiennej srednia dodana została wartość kolejnej próbki. Dodatkowo przy kaŝdym sumowania zwiększana była wartość wskaźnika, aby przy kaŝdym kolejnym przejściu pętli wskazywał on kolejną próbkę. Po dokonaniu sumowania próbek wynik został podzielony przez ilość próbek wynoszącą szesnaście oraz odjęta została od niego składowa stała. Obliczenie wartości średniej dla drugiego sygnału odbyło się analogicznie. Jedyną róŝnicą był fakt, Ŝe wskaźnik wskazywał pierwszą próbkę drugiego sygnału...2. Obliczenie amplitudy Obliczenie amplitudy odbyło się zgodnie z poniŝszym wzorem: gdzie: - amplituda m m - liczba próbek w okresie sygnału x - próbka sygnału = π N x n= ( n) (7.4) PoniŜszy kod przedstawia sposób realizacji obliczeń: /* OBLICZENIE AMPLITUDY KANAL */ amplituda = ; pam = x222; for (licz = ; licz < 8; licz++) modul = *pam - 25; if (modul < ) modul = modul * -; amplituda = amplituda + modul; pam++; amplituda = (amplituda/6) * 3,4; /* OBLICZENIE AMPLITUDY KANAL */ amplituda = ; pam = x223; for (licz = ; licz < 8; licz++) modul = *pam - 25; if (modul < ) modul = modul * -;
amplituda = amplituda + modul; pam++; amplituda = (amplituda/6) * 3,4; Przed dokonaniem obliczeń zmienna, w której zapisany zostanie wynik została wyzerowana, aby wynik poprzednich obliczeń nie wpłyną na wynik aktualnych obliczeń. Do wskaźnika wpisany został adres komórki pamięci, w której znajduje się pierwsza próbka sygnału. Sumowanie próbek odbyło się w pętli for wykonanej osiem razy. Do zmiennej amplituda przy kaŝdym przejściu pętli dodawany zostawał moduł wartości próbki, od której wcześniej odjęto składową stałą sygnału. Obliczanie modułu z wartości próbki zostało zrealizowane poprze funkcję if, która mnoŝy ujemne wartości raz minus jeden. Oprócz sumowania przy kaŝdym przejściu pętli została zwiększona wartość wskaźnika, aby przy kaŝdym kolejnym przejściu pętli wskazywał on kolejną próbkę. Wynik sumowania został podzielony przez ilość próbek oraz pomnoŝony przez 3,4. Obliczenie wartości maksymalnej drugiego sygnału odbyło się analogicznie. Jedyną róŝnicą był fakt, Ŝe wskaźnik wskazywał pierwszą próbkę drugiego sygnału. Po dokonaniu obliczeń nastąpiło wyczyszczenie wyświetlacza LCD, a następnie wyświetlono na nim wyniki obliczeń. PoniŜszy kod realizuje operację wyświetlania obliczonych wartości: pozwolenie = ; lcd_clr(); printf ("S=%i A=%i\nS=%i A=%i",srednia,amplituda,srednia,amplituda); TuŜ przed wyświetleniem wyników zmiennej pozwolenie nadano wartość, co oznacza zezwolenie na zapis kolejnego wektora próbek. Takie rozwiązanie powoduje, Ŝe nie zaistnieje sytuacja, w której wykonywane są obliczenia na wartościach stale odświeŝanych, czyli w efekcie stale zmieniających się. Długi czas wykonywania obliczeń przy takim rozwiązaniu nie wprowadza błędów do obliczeń. W pętli znajduje się równieŝ podprogram wprowadzający 2ms opóźnienie. Dzięki takiemu rozwiązaniu wartości wyświetlone na wyświetlaczu LCD są bardziej czytelne. PowyŜej opisany program znajduje się w załączniku Z.2.2 jako wersja a programu oraz w katalogu c\pr4 - obl sr i ampl\4a. Istnieje równieŝ druga wersja programu wyświetlająca w innym sposób wyniki obliczeń (załącznik Z.2.2 wersja programu b oraz katalog c\pr4 - obl sr i ampl\4b ). pam = x222; pozwolenie = ; lcd_clr(); printf ("%i %i %i %i\n",(int)*pam,(int)*(pam+),(int)*(pam+2),(int)*(pam+3)); printf ("S=%i A=%i",srednia,amplituda); Do wskaźnika pam załadowany został adres pierwszej próbki sygnału. W pierwszej linii wyświetlono cztery pierwsze wartości próbek sygnału. W drugiej linii wyświetlono wartość średnią oraz amplitudę sygnału. Do wskaźnika pam załadowany został adres pierwszej próbki. Trzecia wersja programu (załącznik Z.2.2 wersja programu c oraz katalog c\pr4 - obl sr i ampl\4c ) wyświetla na ekranie wartości średnie oraz amplitudy sygnałów,
wyskalowane do rzeczywistych wartości fizycznych. Sposób obliczenia amplitudy w tej wersji programu przedstawiono poniŝej. /* OBLICZENIE AMPLITUDY KANAL */ amplituda = ; pam = x222; for (licz = ; licz < 8; licz++) modul = *pam - 25; if (modul < ) modul = modul * -; amplituda = amplituda + modul; pam++; amplituda = (amplituda/6) * 3,4; amplituda = amplituda / 5,8; /* OBLICZENIE AMPLITUDY KANAL */ amplituda = ; pam = x223; for (licz = ; licz < 8; licz++) modul = *pam - 25; if (modul < ) modul = modul * -; amplituda = amplituda + modul; pam++; amplituda = (amplituda/6) * 3,4; amplituda = amplituda / 5,8; pozwolenie = ; lcd_clr(); printf ("S=%.fV A=%.fV\n",srednia,amplituda); printf ("S=%.fV A=%.fA",srednia,amplituda); Od poprzednich wersji programu, tę wersję odróŝnia tylko dodatkowe dzielenie zmiennej amplituda przez 5,8 oraz sposób wyświetlania zawierający jednostki mierzonych sygnałów.