instrukcja - Politechnika Warszawska

Transkrypt

instrukcja - Politechnika Warszawska
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
1.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
x1 (n) = X 1m cos(nΩ1 + ϕ1 )
(3.1)
gdzie:
Ω1 = ω1T p = 2π
Tp
T1
=
2π
N1
(3.2)
gdzie N 1 - 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ę
N1 / 2 −1
∑ x ( n) = S
1
av
X 1m
(3.3)
n =0
gdzie:
 π 

S av = 0,5ctg 
 2 N1 
(3.4)
Uwzględniając te załoŜenia obliczenie amplitudy moŜe odbyć moŜe odbyć się w
następujący sposób
 π  N1 / 2−1
 ∑ x1 (n)
X 1m = 2tg 
 2 N 1  n =0
(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
X 1m =
π
N1 / 2 −1
N1
n =0
∑ x ( n)
1
Obliczenia amplitudy w programach zostały wykonane zgodnie ze wzorem (3.6).
(3.6)
1.1. 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 0 oraz 1 kontrolera DSM-51. 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 800Hz, co w efekcie
daje 16 próbek na jeden okres sygnału wejściowego przy załoŜeniu, Ŝe częstotliwość
zmian sygnału badanego wynosi 50Hz. 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. 1.1.
Deklaracja zmiennych,
ustawienie trybu pracy
timerów oraz zezwolenia
na przerwania
Ustawienie liczników
timerów oraz start
Timera 0
Obsługa przerwań od Timera0:
- ustawienie Timera0
- wybór wejścia 0 na multiplekserze
- start przetwornika A/C
- nastawienia Timera 1
- start Timera 1
Pętla nieskończona
Instrukcje
obliczające
wartość średnią
Instrukcje
obliczające
amplitudę
Obsługa przerwań od Timera1:
- zapis wartości z przetwornika A/C
- wybór wejścia 1 na multiplekserze
- start przetwornika A/C
- start Timera 1
Obsługa przerwań od Timera1:
- zapis wartości z przetwornika A/C
Skok do początku bloku
Rys. 1.1. 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 0
pracuje w trybie 1, czyli jako pełen rejestr 16 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 1152 impulsy zegarowe odmierzając w ten
sposób czas wynoszący 1,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 TL1, przy czym po przekroczeniu maksymalnej wartości (256) następuje
wystawienie flagi oraz załadowanie zawartości rejestru TH1 do rejestru TL1. 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 0 oraz 1. Po nastawieniu liczników timerów nastąpił
start timera 0 oraz zainicjowany został wyświetlacz LCD. Kod opisanych powyŜej
czynności przedstawia się następująco:
void main(void)
{
short srednia0;
/*Deklaracja zmiennej dla wartosci sredniej sygnalu 0*/
short srednia1;
/*Deklaracja zmiennej dla wartosci sredniej sygnalu 1*/
short amplituda0;
/*Deklaracja zmiennej dla wartosci amplitudy sygnalu 0*/
short amplituda1;
/*Deklaracja zmiennej dla wartosci amplitudy sygnalu 1*/
short modul;
/*Deklaracja zmiennej do obliczania modulu*/
char licz = 0;
/*Deklaracja licznika dla petli*/
unsigned char *pam0,*pam1;
/*Deklaracja wskaznikow komorek pamieci*/
pam0 = 0x022000;
pam1 = 0x022010;
TMOD = 0x21;
EA = 1;
ET0 = 1;
ET1 = 1;
TH0 = 0xFB;
TL0 = 0x80;
TH1 = 0x00;
TL1 = 0x00;
TR0 = 1;
lcd_init();
/*Nadanie adresu wskaznikowi pamieci*/
/*Nadanie adresu wskaznikowi pamieci*/
/*Ustawienie trybow pracy timerow*/
/*Ogólne zezwolenie na przerwania*/
/*Zezwolenie na przerwania od timera T0*/
/*Zezwolenie na przerwania od timera T1*/
/*Nastawienie licznika T0*/
/*Nastawienie licznika T0*/
/*Nastawienie licznika T1*/
/*Nastawienie licznika T1*/
/*Start licznika T0*/
/*Zainicjowanie wyswietlacza LCD*/
Dalsza część programu wykonywana jest w pętli nieskończonej.
1.1.1. Obliczenie wartości średniej
Polecenie while(1) 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ść 0 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ść 1.
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 (1)
/*Wywolanie petli nieskonczonej*/
{
delay(200);
if (pozwolenie == 1)
/*Sprawdzenie, czy moŜna wykonywac obliczenia*/
{
/* OBLICZENIE WARTOSCI SREDNIEJ KANAL 0*/
srednia0 = 0;
pam0 = 0x022020;
for (licz = 0; licz < 16; licz++)
{
srednia0 = srednia0 + *pam0;
pam0++;
}
srednia0 = (srednia0/16);
/* OBLICZENIE WARTOSCI SREDNIEJ KANAL 1*/
srednia1 = 0;
pam1 = 0x022030;
for (licz = 0; licz < 16; licz++)
{
srednia1 = srednia1 + *pam1;
pam1++;
}
srednia1 = (srednia1/16);
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 ”srednia0” 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.
1.1.2. Obliczenie amplitudy
Obliczenie amplitudy odbyło się zgodnie z poniŜszym wzorem:
X 1m =
π
N1 / 2 −1
N1
n =0
∑ | x ( n) |
1
gdzie:
X 1m - amplituda
N1 - liczba próbek w okresie sygnału
x - próbka sygnału
PoniŜszy kod przedstawia sposób realizacji obliczeń:
/* OBLICZENIE AMPLITUDY KANAL 0*/
amplituda0 = 0;
pam0 = 0x022020;
for (licz = 0; licz < 8; licz++)
{
modul = *pam0 - 125;
if (modul < 0) modul = modul * -1;
amplituda0 = amplituda0 + modul;
pam0++;
}
amplituda0 = (amplituda0/16) * 3,14;
/* OBLICZENIE AMPLITUDY KANAL 1*/
amplituda1 = 0;
pam1 = 0x022030;
for (licz = 0; licz < 8; licz++)
{
modul = *pam1 - 125;
if (modul < 0) modul = modul * -1;
(7.14)
amplituda1 = amplituda1 + modul;
pam1++;
}
amplituda1 = (amplituda1/16) * 3,14;
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 amplituda0 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,14.
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 = 0;
lcd_clr();
printf ("S0=%i A0=%i\nS1=%i A1=%i",srednia0,amplituda0,srednia1,amplituda1);
TuŜ przed wyświetleniem wyników zmiennej pozwolenie nadano wartość 0, 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 200ms 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 1a 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 1b oraz katalog „c\pr4 - obl sr i ampl\4b”).
pam0 = 0x022020;
pozwolenie = 0;
lcd_clr();
printf ("%i %i %i %i\n",(int)*pam0,(int)*(pam0+1),(int)*(pam0+2),(int)*(pam0+3));
printf ("S0=%i A0=%i",srednia0,amplituda0);
Do wskaźnika pam0 załadowany został adres pierwszej próbki sygnału 0. W pierwszej
linii wyświetlono cztery pierwsze wartości próbek sygnału 0. W drugiej linii wyświetlono
wartość średnią oraz amplitudę sygnału 0. Do wskaźnika pam0 załadowany został adres
pierwszej próbki.
Trzecia wersja programu (załącznik Z.2.2 wersja programu 1c 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 0*/
amplituda0 = 0;
pam0 = 0x022020;
for (licz = 0; licz < 8; licz++)
{
modul = *pam0 - 125;
if (modul < 0) modul = modul * -1;
amplituda0 = amplituda0 + modul;
pam0++;
}
amplituda0 = (amplituda0/16) * 3,14;
amplituda0 = amplituda0 / 50,8;
/* OBLICZENIE AMPLITUDY KANAL 1*/
amplituda1 = 0;
pam1 = 0x022030;
for (licz = 0; licz < 8; licz++)
{
modul = *pam1 - 125;
if (modul < 0) modul = modul * -1;
amplituda1 = amplituda1 + modul;
pam1++;
}
amplituda1 = (amplituda1/16) * 3,14;
amplituda1 = amplituda1 / 50,8;
pozwolenie = 0;
lcd_clr();
printf ("S0=%1.1fV A0=%1.1fV\n",srednia0,amplituda0);
printf ("S1=%1.1fV A1=%1.1fA",srednia1,amplituda1);
}
}
}
Od poprzednich wersji programu, tę wersję odróŜnia tylko dodatkowe dzielenie
zmiennej amplituda przez 50,8 oraz sposób wyświetlania zawierający jednostki
mierzonych sygnałów.