Systemy cyfrowe z podstawami elektroniki i miernictwa

Transkrypt

Systemy cyfrowe z podstawami elektroniki i miernictwa
Systemy cyfrowe z podstawami elektroniki i miernictwa
Wyższa Szkoła Zarządzania i Bankowości w Krakowie Informatyka II rok studia dzienne
Ćwiczenie nr 10: Podstawy programowania mikrokontrolerow cz. 1
Cel ćwiczenia
Celem ćwiczenia jest poznanie podstaw budowy prostych aplikacji opartych o mikrokontrolery
jednoukładowe , oraz elementów programowania mikrokontrolerów w językach wysokiego poziomu..
Wymagane wiadomości
• Budowa mikrokontrolera BasicStamp2
• Zestaw edukacyjny StampInClass – budowa i obsługa
• Język PBASIC.
Wykorzystywany sprzęt
Komputer PC z oprogramowaniem do obsługi zestawu BasicStamp.
Zestaw edukacyjny StampInClass firmy Parallax inc.
Literatura
www.parallaxinc.com
www.stampsinclass.com
Zestaw edukacyjny The Board of Education BASIC Stamp II jest platformą,
pozwalającą budować różnorodne obwody, w ramach zajęć, z podstaw elektroniki, z
możliwością programowania przy pomocy komputera. Łatwy w użyciu i montażu, bez użycia
lutownicy lub podobnego tego typu osprzętu.
Cechy charakterystyczne:
• Płyta główna z mikrokontrolerami; BASIC Stamp II (BS2-IC) lub BASIC Stamp
IISX (BS2SX-IC)
• Zasilanie - 9V bateria, ewentualnie inne zewnętrze źródło zasilania.
• Przewód RS232 łączący komputer z zestawem służący do programowania
urządzenia
• Zestaw złączy, przewodników w izolacji, w czerwonym i czarnym kolorze
• Płyta CD z kompilatorem języka PBasic
Zdjęcie urządzenia, wraz z zestawem:
Opis modułu BASIC Stamp II (BS2I-C)
Jest to mały mikrokontroler, wielkości znaczka pocztowego, który służy jako
interpreter języka PBasic (to znaczy wykonuje programy napisane w tym języku), ma on 16 w
pełni konfigurowanych wyprowadzeń (I/O pins), które mogą służyć jako bezpośrednie
interfejsy różnych urządzeń z logicznego punktu widzenia, czyli takie jak guziki, diody,
potencjometry, słuchawki, głośniczki, rejestry przesuwne, itp. Gdyby dodać jeszcze kilka
dodatkowych komponentów, piny mogłyby być podłączone do urządzeń zwanych non-TTL,
czyli solenoidy, obwody transmisyjne, przekaźniki, interfejs RS-232, mierniki napięcia, i
sterować nimi.
Z fizycznego punktu widzenia składa się on z 5-voltowego regulatora, rezonatora (20
Mhz), szeregowego EEPROM, i interpretera PBASIC. Odpowiednie tokeny napisane w tym
języku (czyli pojedyncze instrukcje) są nie ulotnie przechowywane w pamięci EEPROM
(oczywiście zawartość zmienia się pomiędzy poszczególnymi załadowaniami, co jest
sygnalizowane diodą) które są czytane i interpretowane przez sterujący chip. Pobiera on jedną
instrukcję w jednostce czasu, i wykonuje żądaną operację, na odpowiednich pinach, lub innej
wewnętrznej struktury w granicach interpretera. BS2-IC przechowuje 500 - 600 instrukcji i
wykonuje około 4000 instrukcji/s. Ponieważ cały kod programu jest przechowywany w
EEPROM, może być bezustannie programowany, modyfikowany, bez konieczności jej
wcześniejszego wymazywania. Kod jest pisany przy pomocy komputera, i dołączonego
oprogramowania: kompilatora, który dokonuje sprawdzenia jego poprawności, i wytwarza
plik binarny, który jest następnie przesyłany, przy pomocy kabla.
Zdjęcie tego modułu:
Schemat przedstawiający poszczególne podzespoły:
Zestaw dostępny na zajęciach jest odpowiednio skonfigurowany i przygotowany do pracy.
Płyta do montowania komponentów składa się z gniazdek (otworów), które służą do
wkładania elementów. Poszczególne wyprowadzenia używanych w doświadczeniach
elementów tworzą stabilne złącza elektryczne umożliwiające przepływ prądu. Gniazdka są
połączone tak jak to przedstawiono na rysunku. Do dyspozycji są zatem 2 kolumny po 17
punktów z których każdy ma 5 gniazdek. Dodatkowo na złączu X3 dostępne jest 5 gniazd
dostarczających dodatnie napięcie zasilania Vss, 3 dla Vin( nie podłączone) i 5 dla uziemienia
Vdd.
Dostępne z boku złącze X2 doprowadza sygnały z mikrokontrolera oznaczone jako P0 do
P14
Rysunek 1 Schemat połączeń płyty do montowania komponentów
Po podłączeniu zasilania powinna zapalić się zielona dioda świecąca opisana jako PWR.
Uruchom na komputerze edytor BASIC Stamp II, który służy do pisania kodu źródłowego
programu, i wpisz następującą linię kodu:
DEBUG “Basic Stamp II jest gotowy do pracy”
Uruchom program, jeśli wszystko pójdzie dobrze, plik wykonywalny programu zostanie
skompilowany i przesłany do urządzenia.
Na ekranie powinno się pojawić okno DEBUG :
Kilka informacji o programowaniu Basic Stampa
Język używany do zaprogramowania mikrokontrolera nazywa się PBASIC. Składnia tego
języka programowania, jest w istocie bardzo prosta, jest to język, który składa się z ciągu
instrukcji wykonywanych kolejno, tak samo jak w powszechnie znanych językach Basic, C,
Pascal. Można przedstawić schemat programu, w postaci wyrażeń:
wyra•anie 1
wyra•anie 2
wyra•anie 3
END
Gdzie za wyrażenie można podstawić dowolną instrukcję tego języka. To jest bardzo prosta
struktura programu. Jednakże programy nie działają w sposób liniowy często są rozgałęzianie
instrukcjami warunkowymi, robią pętlę i dzielą się na podprogramy, z krótkimi linearnymi
sekcjami w między nimi. Wymagania dla programu są określone przez cel programu i
warunków pod który program działa.
Rozgałęzienia warunkowe i bezwarunkowe
Rozgałęzienie rozkazu jest sposobem na zmianę wykonywanych instrukcji na inne, wskutek
zajścia jakiegoś warunku. Są dwie kategorie rozgałęzień programu: warunkowe i
bezwarunkowe. PBASIC ma 2 komendy, które umożliwiają bezwarunkowe rozgałęzienie
programu: GOTO, GOSUB, oto przykład:
Etykieta:
wyra•anie 1
wyra•anie 2
wyra•anie 3
GOTO Etykieta
GOTO powoduje przeskoczenie do instrukcji, znajdującej się bezpośrednio poniżej etykiety,
zakończonej dwukropkiem. Nazwa etykiety z dwukropkiem powoduje zapamiętanie adresu,
który jest używany dla rozkazu GOTO poprzez nazwę tej etykiety.
Sposobem na warunkowe przejście do innej instrukcji jest użycie:
IF warunek THEN instrukcja.
Jeśli warunek będzie miał wartość logiczną TRUE powoduje to wykonanie instrukcji
instrukcja, w przeciwnym wypadku przejście do następnej linii kodu, np.:
Etykieta:
wyra•anie 1
wyra•anie 2
wyra•anie 3
if condition THEN Etykieta
wyra•anie 4
Jeśli condition ma wartość true powoduje to przejście do wyra•anie 1 w
przeciwnym razie do następnej linii kodu, i wykonanie wyra•anie 4
Można też użyć wiele takich instrukcji następujących po sobie:
IF condition_0 THEN Label_0
IF condition_1 THEN Label_1
IF condition_2 THEN Label_2
To podejście jest prawidłowe, jednakże można użyć specjalnej instrukcji BRANCH, która ma
prostszy zapis, i zastępuje wiele instrukcji IF następujących po sobie.
BRANCH controlVar,[Label_0, Label_1, Label_2]
Używa pojedynczej zmiennej controlVar do kontroli listy adresów, a działa tak że, jeśli
controlVar jest równy zero, to program przejdzie do Label_0, jeśli controlVar
jest równy jeden, to program przejdzie do Label_1 i tak dalej.
Pętle
Pętle są używane do wielokrotnego powtarzania danej sekcji programu. Pętle używają
warunkowych lub bezwarunkowych rozgałęzień, w celu przejścia do odpowiedniej etykiety.
Oto przykład pętli z rozgałęzieniem bezwarunkowym.
Etykieta:
wyra•anie 1
wyra•anie 2
wyra•anie 3
GOTO Etykieta
Poprzez użycie GOTO wyrażenia są wielokrotnie powtarzane. Poprzez użycie IF-THEN
można dodać element warunkowy do danej pętli, np. określający kiedy dana pętla ma się
zakończyć, oto przykład warunkowego wyjścia z pętli:
Etykieta:
wyra•anie 1
wyra•anie 2
wyra•anie 3
IF warunek THEN Etykieta
W tym przypadku jeśli zmienna warunek będzie miała wartość logiczną TRUE to
powtarzanie instrukcji wewnątrz pętli będzie kontynuowane, natomiast jeśli będzie miała
wartość logiczną FALSE to wykonywanie instrukcji wewnątrz tej pętli zakończy się. Łatwo
zauważyć, że przy tej konstrukcji pętla te przynajmniej raz wykona się. Aby temu zapobiec
można przekształcić nieco powyższy kod, dodając NOT przy sprawdzaniu warunku.
W tym przypadku, aby na samym początku pętla się w ogóle nie wykonała zmienna
warunek na początku musi mieć wartość FALSE.
Label_1:
IF (warunek) THEN Label_2
wyra•anie 1
wyra•anie 2
wyra•anie 3
GOTO Label_1
Label_2:
wyra•anie 4
Kolejną konstrukcją używaną do tworzenia pętli i sprawdzania warunku zakończenia jest
FOR-NEXT:
FOR controlVar = startVal TO endVal STEP stepSize
wyra•anie 1
wyra•anie 2
wyra•anie 3
NEXT
Używana jest do wykonywanie instrukcji pewną określoną z góry ilość razy, zmienna
controlVar przyjmuje wartości kolejno od startVal do stepSize, poprzez krok ,
który jest opcjonalny, jeśli tylko ten krok jest różny od liczby jeden.
Podprogramy
Podprogram jest sekcją kodu, która może być wywołana gdziekolwiek w programie. GOSUB
jest używane, aby przekierować wykonywanie programu na ten właśnie podprogram.
Podprogram jest kończony rozkazem RETURN, który powoduje zakończenie wykonywania
podprogramu, i przejście z powrotem do linii programu, z skąd dany podprogram został
wywołany przez GOSUB.
Start:
GOSUB MySub
PAUSE 1000
GOTO Start
MySub:
wyra•anie 1
wyra•anie 2
wyra•anie 3
RETURN
Tutaj jest wywoływany podprogram MySub, po jego zakończeniu program zastanie
zatrzymany na 1000 milisekund, następnie następuje skok do etykiety Start, i tak w
nieskończonej pętli. Definicja podprogramu składa się z jego nazwy, zakończonej
dwukropkiem, i kończy się rozkazem RETURN.
Styl programowania
PBASIC jest bardzo elastycznym językiem programowania, ma łatwą składnie i strukturę.
Jego reguły są proste i szybkie do opanowania. Nie są rozróżniane małe i duże litery, więc
można pisać RETURN, return, ReTuRn, a to będzie znaczyło jedno i to samo dotyczyło
jednego rozkazu. Warto jednak wypracować sobie swój indywidualny styl programowania,
zachować przejrzystość kodu, dodawać komentarze, by później nie mieć problemów z
rozpoznaniem co się kiedyś pisało. Komentarzem jest wszystko, co zostało napisane po znaku
' aż do końca danej linii, np.:
' To jest komentarz, ta część jest pomijana przy kompilacji
Szablon:
Każdy program jest strukturalnie podobny, poprzez skorzystanie pewnego szablonu. Ten
szablon jest podzielony na cztery części:
- Nagłówek: ta sekcja zawiera nazwę pliku, autora i krótki opis programu (do czego ma
służyć, jak działa itp.) Od wersji 1.1 dodano również dyrektywy kompilatora.
- Deklaracje: zawiera deklaracje stałych i zmiennych, alias dla pinów wejściowych i
wyjściowych (I/O pins)
- Dane: deklaracje danych użytych w programie, (np. pamięć EPROM)
- Inicjalizacja: przewiduje miejsce dla inicjalizacji danych użytych w programie, czyli
stałych, zmiennych, pinów wejścia/wyjścia, oraz jeśli zachodzi taka potrzeba
zewnętrznego sprzętu.
- Kod: główny kod programu
- Podprocedury: definicje wszystkich procedur użytych w programie.
Przykład: szablonu BLANK.BS2, można go użyć, jak pisze się całkiem nowy program.
'
'
'
'
'
'
'
'
=========================================================================
File: BLANK.BS2
{ opis }
{$STAMP BS2}
=========================================================================
{ I/O pins }
' { sta•e }
' { zmienne }
' ------------------------------------------------------------------------' { dane }
' ------------------------------------------------------------------------' { inicjalizacja }
' ------------------------------------------------------------------------' { program g•ówny }
Main:
GOTO Main
END
' ------------------------------------------------------------------------' { podprocedury }
Przyjęte konwencje nazewnicze
Przyjęło się, dla zachowanie czytelności programu zachować pewne normy dotyczące nazw.
Dzięki temu łatwo rozpoznać stałe, zmienne, słowa kluczowe używane w programie, a i sam
program staje się bardziej przejrzysty.
- Stałe, dołączając etykiety, i podprocedury: można używać małych lub wielkich liter, ale
zazwyczaj zaczynają się dużymi literami, np. LimitSw, LMotor, DlyTm, InitLCD
- Zmienne: można używać małych lub wielkich liter, ale zazwyczaj zaczynają się małymi
literami, np. lcdChar, hrs, iCount.
- PBASIC słowa kluczowe, są pisane w całości dużymi literami, np. RETURN
1. Migająca dioda (wersja 1.0)
Wykorzystana zostanie dioda luminescencyjna, która będzie się zaświecać i gasnąć na
przemian. Diody tego typu są powszechnie wykorzystywane w urządzeniach jako wskaźnik
danego stanu.
Nowe komendy języka PBASIC:
• CON
• HIGH
• LOW
• PAUSE
• GOTO
Obwód elektryczny do ćwiczenia:
Wygiąć oba wyprowadzenia rezystora , tak, aby przypominały kształtem literę U. Jedno z
wyprowadzeń umieścić w gnieździe P15 złącza X2. Drugie wyprowadzenie umieścić w
jednym z otworów drugiej kolumny.
Dioda świecąca posiada wyprowadzenia niesymetrycznej długości i ściętą obudowę przy
krótszym z nich. Aby dioda zaświeciła należy zagwarantować przepływ prądu w
odpowiednim kierunku (dłuższe wyprowadzenie powinno być podłączone do punktu o
wyższym napięciu, a krótsze do punktu o niższym napięciu) W tym eksperymencie krótsze
wyprowadzenie należy umieścić w gnieździe oznaczonym Vss złącza X3, a drugie tak, aby
było połączone elektrycznie z jednym z wyprowadzeń rezystora.
Wpisać i uruchomić przedstawiony poniżej program:
Kod programu:
' =========================================================================
' BLINK1.BS2
'
' migaj•ca dioda pod••czana do portu P15
' =========================================================================
LEDpin CON 15
' LED podlaczony do Pin 15
DlyTm CON 500
' czas zw•oki w milisekundach
' ------------------------------------------------------------------------Main:
HIGH LEDpin
' w••cz diod•
PAUSE DlyTm
' w•acz pauz•
LOW LEDpin
' wy••cz diod•
PAUSE DlyTm
' wy••cz pauz•
GOTO Main
' przeskocz do etykiety Main, czyli niesko•czona p•tla
END
Każdy z pinów wejścia/wyjścia ma (Stamp’s I/O pins) ma 3 bity skojarzone z jego
kontrolą. Bit dirs mówi czy pin ten ma być jako wejście (bit=0) czy jako wyjście (bit=1). Jeśli
pin jest skonfigurowany jako wyjście, jego aktualny stan jest przechowywany w skojarzonym
z bitem słowie Outs (Outs word). ). Jeśli pin jest skonfigurowany jako wejście, jego aktualny
stan jest przechowywany w skojarzonym z bitem słowie Ins (Ins word).
Rozkazy HIGH i LOW powodują skonfigurowanie wyselekcjonowanego pinu jako wyjście, i
odpowiednia wartość w Outs jest ustawiana (1 dla HIGH lub 0 dla LOW).
Dla przykładu następująca linia kodu:
HIGH 0
daje takie same efekty jak:
Dir0 = 1
' ustaw pin 0 jako wyj•cie
Out0 = 1
' ustaw pin 0 w stan wysoki
Uruchomić program dla kilku różnych wartości parametru DlyTm. Na co wpływa zmiana
wartości tego parametru.
2 Migająca dioda (wersja 2.0)
W tym ćwiczeniu dioda będzie bardziej elastyczna, niż w ćwiczeniu poprzednim.
Wykorzystywany jest ten sam układ
Nowe komendy języka PBASIC:
• VAR
• Out0 – Out15
• Dir0 – Dir15
• Byte
• Bit0 – Bit15
Użyj tego samego obwodu, co w eksperymencie pierwszym, i uruchom następujący program:
' =========================================================================
' File: BLINK2.BS2
'
' Blinks an LED connected to Pin 0. LED on-time and off-time can be set
' independently of each other.
' dioda migaj•ca, pod••czona do pinu 0 czas •wiecenia
' i czas nie-•wicenia s• niezale•ne od siebie
' =========================================================================
MyLED VAR Out15
' dioda pod••czona do pin 15
DlyOn CON 1000
' czas •wiecenia w milisekundach
DlyOff CON 250
' czas nie-•wiecenia w milisekundach
On CON 1
Off CON 0
' ------------------------------------------------------------------------Initialize:
Dir15 = %1
' skonfiguruj pin diody (pin 15) jako wyj•cie
' ------------------------------------------------------------------------Main:
MyLED = On
PAUSE DlyOn
' przerwa przez czas •wiecenia
MyLED = Off
PAUSE DlyOff
' przerwa przez czas nie •wiecenia
GOTO Main
' p•telka niesko•czona
END
Uruchomić program dla różnych wartości DlyOn i DlyOff. Jak zmiany wpływają na efekt
wykonania programu.
3. Licznik
Celem tego eksperymentu będzie wyświetlenie aktualnej zawartości licznika, przy pomocy
ośmiu diod luminescencyjnych (binarnie odpowiednie diody odpowiadają poszczególnym
bitom licznika).
Nowe komendy języka PBASIC:
• OutL, OutH
• DirL, DirH
• FOR-NEXT
Budowa obwodu:
Linijka diodowa wykorzystywana w eksperymencie jest oznaczona na jednej stronie
obudowy czarną kropką. Oznacza ona stronę, na którą wyprowadzone zostały anody
wszystkich diod świecących wchodzących w skład drabinki. Drabinkę diodową należy
umieścić tak aby anody były po stronie złącza X2.
W celu zbudowania tego obwodu:
1. Ukształtować 8 rezystorów o wartości 200Ω w kształt litery U
2. Umieść rezystor tak aby 1 końcówka znalazła się w gniazdku P0 złącza X2 a druga
została połączona z anodą pierwszej diody.
3. Powtórz czynność z punktu 2 dla kolejnych 7 diod (do P7)
4. Połącz razem katody wszystkich diod i podłącz je do masy (gniazdko Vss złącza X3)
Uruchom program:
' =========================================================================
' File: LEDCNTR.BS2
'
' wy•wietlacz licznika binarnego P0-7
' =========================================================================
LEDs VAR OutL
' piny diod do P0-7
MinCnt CON 0
' pocz•tkowa zawarto•• licznika
MaxCnt CON 255
' ko•cowa zawarto•• licznika
DlyTm CON 100
' czas przerwy
cntr VAR Byte
' warto•• licznika, typu Bajt
' ------------------------------------------------------------------------Initialize:
DirL = %11111111
' zainicjalizuj wszystkie diody jako wyj•cia
' ------------------------------------------------------------------------Main:
FOR cntr = MinCnt TO MaxCnt
' p•tla for, 'poprzez wszystkie warto•ci
licznika
LEDs = cntr
' poka• aktualn• zawarto•c licznika na diodach
PAUSE DlyTm
' przerwa przed zmian• stanu licznika
NEXT
GOTO Main
END
' niesko•czona p•telka
Stan wszystkich pinów wyjściowych jest przechowywany w pewnym obszarze pamięci, do
którego można się odwołać poprzez Outs (OutL jest najmniej znaczącym bajtem słowa
Outs). Wartości mogą być odczytywane i zmienia w tym obszarze pamięci. W naszym
przypadku kopiujemy zawartość zmiennej cntr do OutL, co powoduje odpowiednie
ustawienie pinów, i w konsekwencji świecenie odpowiadających im diod.
Zmodyfikować i uruchomić program, aby zliczał wstecz.
4. Efekty świetlne z wykorzystaniem linijki diodowej
Efekt świecenia diod od początku kolejno do ostatniej, i z powrotem
Nowe komendy języka PBASIC:
• << (Shift Left operator)
• >> (Shift Right operator)
• IF-THEN
Obwód ten sam co w punkcie 3
Program:
' =========================================================================
' File: PONG.BS2
' "Ping-Pongs" an LED (one of eight)
' =========================================================================
LEDs VAR OutL
' diody pod••czone do pinów 0-7
DlyTm CON 50
' czas opó•nienia w milisekundach
' ------------------------------------------------------------------------Initialize:
DirL = %11111111
' wszystkie piny jako wyj•cia
LEDs = %00000001
' pierwsza dioda przy pin 0 -> stan HIGH, reszta stan LOW
' ------------------------------------------------------------------------GoForward:
PAUSE DlyTm
' show the LED //w••cz przerw•
LEDs = LEDs << 1
' przesuni•cie bitowe w lewo 00000001 -> 00000010
IF LEDs = %10000000 THEN GoReverse
' //wyj•cie z p•tli
GOTO GoForward
' continue in this direction //kontynuacja p•tli
GoReverse:
PAUSE DlyTm
' show the LED
LEDs = LEDs >> 1
' shift on LED to the right //przesuni•cie bitowe w prawo
IF LEDs = %00000001 THEN GoForward ' test for final position //skaczemy do
pocz•tku
GOTO GoReverse
' continue in this direction //kontyuacja tej p•tli
END
Ten program pokazuje zdolność do bezpośredniego manipulowania wyjściem. Inicjalizuje on
diody, i kolejno jedna dioda gaśnie, a na jej miejsce zaświeca się ta tuż obok niej, w jednym
kierunku, gdy dojdziemy do końca kierunek zostaje zmieniony. Używany jest do tego celu
operator << , który powoduje pomnożenie binarnej liczby przez 2, natomiast operator >>
podzielenie liczby binarnej przez 2.
Przekształcić program tak aby zrealizował następujący efekt: diody zapalają się kolejno od
strony prawej do lewej tak, ze kolejno świeci się 1,2,3 ... 8 diod. Następnie są w tej samej (
lub odwrotnej kolejności wygaszane