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