instrukcja - Politechnika Warszawska

Transkrypt

instrukcja - Politechnika Warszawska
Politechnika Warszawska
Wydział Elektryczny
Laboratorium Podstaw Techniki Mikroprocesorowej
Skrypt do ćwiczenia M.42
Zbieranie pomiarów w czasie rzeczywistym - język C
1.Wstęp
W ćwiczeniach od M.42 do M.48 opisane zostały programy, wykonane w języku C,
korzystające z prostych algorytmów obliczających wartości wielkości kryterialnych.
Zadaniem tych programów jest obliczanie parametrów sygnałów podawanych na wejście
analogowe mikrokontrolera.
Następnie opisanych zostało sześć programów napisanych w języku C, które wykonują
następujące czynności:
• obliczenie wartości średniej oraz amplitudy,
•
obliczenie mocy czynnej oraz biernej (metoda 1),
•
obliczenie części rzeczywistej oraz urojonej sygnałów,
•
obliczenie mocy czynnej oraz biernej na podstawie części rzeczywistej oraz
urojonej sygnałów,
•
program obliczający rezystancję oraz reaktancję,
•
program obliczający przesunięcie fazowe pomiędzy sygnałami.
KaŜdy z programów składa się z części wspólnej dotyczącej zbierania próbek
sygnałów podawanych na wejście analogowe mikrokontrolera (nastawienie timerów,
deklaracja obsługi przerwań, sterowanie przetwornikiem A/C oraz zapis próbek) oraz
części obliczeniowej. Dotyczy to programów napisanych w asemblerze oraz w języku C.
Opisany poniŜej kod programu jest częścią wspólną programów opisanych w
kolejnych ćwiczeniach. Kod ten odpowiada za przetwarzanie analogowo-cyfrowe,
nastawienie timerów, deklaracja obsługi przerwań, sterowanie przetwornikiem A/C,
zbierania oraz zapis próbek sygnałów podawanych na wejście analogowe mikrokontrolera
DSM-51.
1.1. Część wspólna dla programów napisanych w języku C
Opisany w tym rozdziale kod znajduje się w katalogu „c\pr - podstawowy\”.
Wszystkie poniŜsze programy napisane w języku C funkcjonują zgodnie ze schematem
przedstawionym 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
obliczeniowe
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
Programy rozpoczynają się od deklaracji zmiennych, ustawienia trybu pracy timerów
oraz zezwolenia na przerwania, po czym następuje ustawienie liczników timerów oraz
start Timera 1. Timer ten odlicza czas pomiędzy pobieraniem kolejnych próbek. Dalsza
część programu działa w pętli nieskończonej, w której wykonywane są obliczenia.
Działania pętli przerywane są jedynie przez instrukcje obsługi przerwań od Timerów,
które odpowiadają za zbieranie oraz zapis próbek sygnałów.
Częścią wspólną wszystkich programów napisanych w języku C jest obsługa timerów,
obsługa przerwań oraz zapis próbek. Zostało to opisane poniŜej. Na początku programu
dołączone zostały pliki nagłówkowe. Odbyło się to w następujący sposób:
#include <reg51.h>
#include <stdio.h>
#include <math.h>
#include "lcd.c"
#include "delay.c"
Jako pierwszy dołączony został plik reg51.h zawierający definicje rejestrów
specjalnych mikrokontrolera. Plik stdio.h jest standardową biblioteką wejść-wyjść.
Kolejny plik (lcd.c) odpowiada za obsługę wyświetlacza LCD, natomiast plik delay.c
zawiera podprogram delay, wykorzystany do wprowadzania opóźnienia podczas
wyświetlania wyników na ekranie LCD.
Przed programem głównym zadeklarowane zostały poniŜsze zmienne, które
wykorzystywane są w obsłudze przerwań:
unsigned char a = 0;
unsigned char licznik = 0;
unsigned char *pamiec0,*pamiec1;
unsigned char *CSAD,*CSMX;
unsigned char licznik2;
unsigned char pozwolenie = 0;
/*Deklaracja przelacznika kanalow*/
/*Deklaracaja licznika dla obslugi przerwan*/
/*Deklaracja wskaznikow pamieci*/
/*Deklaracja wskaznika przetwornika A/C oraz multipleksera*/
/*Deklaracja licznika dla petli kopiujacej probki*/
/*Pozwolenie na wykonywanie obliczen oraz zapisu probek*/
Zmienna a wykorzystana została jako “przełącznik” kanałów. Jej stan (0 lub 1)
decyduje o tym dla którego sygnału wykonane zostanie przetwarzanie A/C w obsłudze
przerwań. Zmienna licznik, działa jako licznik w pętlach, pilnujący, aby zebrana została
odpowiednia ilość próbek. Zmienne *pamiec0 oraz *pamiec1 są wskaźnikami komórek
pamięci, do których zapisywane są próbki. Zmienna *CSAD wykorzystana została jako
wskaźnik zawierający adres, pod którym znajduje się przetwornik A/C. Zmienna *CSMX
pełni analogiczną funkcję co poprzednia zmienna, lecz zawiera informację o adresie, pod
którym znajduje się multiplekser. Zmienna licznik2 posłuŜyła jako licznik w pętli
kopiującej próbki do pamięci, z której pobierane będą wartości próbek do obliczeń.
Zmienna pozwolenie pilnuje, aby nie nastąpił zapis próbek w trakcie obliczeń. Jej
zastosowanie zostało dokładniej wyjaśnione w dalszej części opisu.
1.1.1. Podprogram obsługi przerwania od Timera 0
Następnie zdefiniowany został podprogram obsługi przerwania od timera 0. Kod tego
podprogramu przedstawiono poniŜej:
void Przerw_t0(void) interrupt 1
{
TH0 = 0xFB;
TL0 = 0x80;
CSAD = 0x2ff10;
CSMX = 0x2ff18;
*CSMX = 0;
*CSAD = 0x01;
TH1 = 0x00;
TL1 = 0x00;
TR1 = 1;
}
/*Program obslugi przerwania od timera T0*/
/*Nastawienie licznika T0*/
/*Nastawienie licznika T0*/
/*Adres przetwornika A/C */
/*Adres multipleksera*/
/*Wybór wejscia 0 na multiplekserze*/
/*Start przetwarzania A/C*/
/*Nastawienie licznika T1*/
/*Nastawienie licznika T1*/
/*Start licznika T1*/
Na początku obsługi przerwania nastawiony został licznik timera 0, aby kolejny raz
mógł on odliczyć właściwy czas. Następnie wskaźnikom przypisane zostały adresy
przetwornika A/C oraz multipleksera, po czym wybrane zostało wejście 0 na
multiplekserze i zainicjowane zostało przetwarzanie A/C. Przed końcem obsługi
przerwania nastawiony został licznik timera 1 oraz zainicjowany został jego start.
1.1.2. Podprogram obsługi przerwania od Timera 1
Tak jak w poprzednim podprogramie obsługi przerwań, tak i w tym wskaźnikom
przypisane zostały adresy przetwornika A/C oraz multipleksera oraz nastawiony został
licznik Timera 1, aby kolejny raz mógł on odliczyć właściwy czas. Aby wskaźniki
komórek pamięci, w których zapisywane są próbki, nie przekroczyły dopuszczalnych
wartości sprawdzona została wartość licznika. Zrealizowane zostało to za pomocą
instrukcji warunkowej if. JeŜeli wartość licznika wynosi zero, to wartości wskaźników
zostają ustawione na wartości początkowe, czyli takie, od których zaczyna się zapis
próbek. Pozostała część podprogramu wykonywana jest w instrukcji warunkowej if, którą
moŜna podzielić na dwie części. Pierwsza wykonywana jest dla zmiennej a równej 0,
natomiast druga dla zmiennej a równej 1.
void Przerw_t1(void) interrupt 3
{
CSAD = 0x2ff10;
CSMX = 0x2ff18;
TH1 = 0x00;
TL1 = 0x00;
if (licznik == 0)
/*Program obslugi przerwania od timera T1*/
/*Adres przetwornika A/C */
/*Adres multipleksera*/
/*Nastawienie licznika T1*/
/*Nastawienie licznika T1*/
{
pamiec0 = 0x022000;
pamiec1 = 0x022010;
/*Zresetowanie wskaznika pamieci*/
/*Zresetowanie wskaznika pamieci*/
}
if (a == 0)
{
*pamiec0 = *CSAD;
*CSMX = 1;
*CSAD = 0x01;
pamiec0++;
a = 1;
licznik++;
}
/*Zapis wyniku przetwarzania A/C dla kanalu 0*/
/*Wybór wejscia 1 na multiplekserze*/
/*Start przetwarzania A/C*/
/*Inkrementacja wskaznika pamieci*/
/*Przelaczenie na kanal 1*/
/*Inkrementacja licznika*/
W pierwszej kolejności zapisany został wynik przetwarzania dla kanału 0 do komórki
pamięci, którą wskazuje wskaźnik *pamiec0. Następnie wybrane zostało wejście 1 na
multiplekserze oraz zainicjowane zostało przetwarzanie A/C dla tego kanału. Na koniec
inkrementowany został licznik oraz wskaźnik *pamiec0. Aby przy następnym wywołaniu
podprogramu obsługi przerwania od Timera 1, wykonana została druga część instrukcji
warunkowej, wartość zmiennej a została zmieniona na jedynkę.
Dla zmiennej a równej jeden wykonywany jest poniŜszy kod:
else
{
a = 0;
TR1 = 0;
*pamiec1 = *CSAD;
pamiec1++;
/*Przelaczenie na kanal 0*/
/*Zatrzymanie licznika T1*/
/*Zapis wyniku przetwarzania A/C dla kanalu 1*/
/*Inkrementacja wskaznika pamieci*/
if (licznik == 16)
/*Sprawdzenie, czy licznik osiagnal maksimum*/
{
licznik = 0;
/*Resetowanie licznika*/
if (pozwolenie == 0)
/*Sprawdzenie zezwolenia na zapis probek*/
{
pamiec0 = 0x022020;
/*Wstepne nastawienie wskaznikow*/
pamiec1 = 0x022000;
/*Wstepne nastawienie wskaznikow*/
for (licznik2 = 0; licznik2 < 32; licznik2++) /*Kopiowanie probek*/
{
*pamiec0 = *pamiec1;
pamiec0++;
pamiec1++;
}
pozwolenie = 1;
/*Zezwolenie na wykonywanie obliczen*/
}
}
}
}
W tej części instrukcji nastąpił zapis wyniku przetwarzania A/C dla kanału 1,
zatrzymanie Timera 1, inkrementacja wskaźnika komórek pamięci do których zapisywane
mają być próbki z pierwszego kanału oraz wyzerowanie zmiennej a. Dodatkowo, jeŜeli
licznik osiągnie wartość równą szesnaście, zostanie wyzerowany oraz przekopiowane
zostaną wszystkie wartości próbek do pamięci od adresu 2030H. Osiągnięcie przez licznik
wartości równej szesnaście jest równowaŜne z zapisaniem próbek dla całego okresu
sygnałów wejściowych. Operacja kopiowania odbywa się w pętli for, przy wykorzystaniu
dwóch wskaźników komórek pamięci, z których jeden wskazuje pierwszą próbkę dla
sygnału 0, natomiast drugi wskazuje pierwszy adres komórki od którego zapisywane mają
być skopiowane wartości. Pętla wykonywana jest 32 razy, dzięki czemu kopiowane są
próbki dwóch sygnałów. Kopiowanie próbek odbędzie się tylko dla zmiennej pozwolenie
równej 0. Pilnuje tego funkcja if, w której odbywa się kopiowanie. Dla zmiennej
pozwolenie równej 0 moŜe nastąpić kopiowanie próbek, natomiast nie mogą zostać
wykonane obliczenia. Po kopiowaniu próbek zmiennej pozwolenie nadawana jest wartość
1, dla której mogą zostać wykonane obliczenia, natomiast nie moŜe nastąpić kopiowanie
próbek. Po wykonaniu obliczeń zmiennej pozwolenie nadawana jest wartość 0.
Początkowa wartość zmiennej pozwolenie wynosi 0, aby w pierwszej kolejności odbył się
zapis próbek, który rozpoczyna cykl naprzemiennego wykonywania zapisu próbek oraz
obliczeń. Takie rozwiązanie powoduje, Ŝe dane, na których wykonywane są obliczenia nie
zmienią się w trakcie wykonywania obliczeń. Dodatkową zaletą takiego rozwiązania jest
fakt, Ŝe obliczenia mogą trwać dowolnie długo.

Podobne dokumenty