Płyta testowa mikrokontrolera AVR
Parametry mikrokontrolera ATmega8
Mikrokontroler ATmega8 firmy ATMEL jest mikrokontrolerem 8-bitowym rodziny AVR, który dzięki architekturze RISC oraz wykonywaniu większości instrukcji w jednym cyklu maszynowym, osiąga wydajność obliczeniową do 1 MIPS (miliona operacji na sekundę) przy częstotliwości sygnału taktującego mikrokontrolera wynoszącej 1 MHz.
Mikrokontroler ATmega8 ma następujące parametry oraz cechy funkcjonalne:
• mały pobór mocy
• zaawansowana architektura RISC charakteryzująca się:
- 130 instrukcjami, z których większość jest wykonywana w jednym cyklu maszynowym
- 32 rejestrami 8-bitowymi ogólnego przeznaczenia
- maksymalną wydajnością 16 MIPS przy częstotliwości zegara 16 MHz
• pamięci:
- 8 kB nielotnej pamięci Flash o trwałości 10 000 zapisów/kasowań
- 512 B pamięci EEPROM o trwałości 100 000 zapisów/kasowań
- 1 kB pamięci SRAM
- ma programowalne zabezpieczenia pamięci programu przed odczytem
• układy peryferyjne:
- dwa 8-bitowe czasomierze/liczniki
- jeden 16-bitowy czasomierz/licznik - zegar czasu rzeczywistego z oddzielnym oscylatorem
- trzy kanały PWM (OC1A, OC1B, OC2)
- 6-kanałowy przetwornik A/C - cztery kanały o rozdzielczości 10 bitów i dwa o rozdzielczości 8 bitów
- szeregowy interfejs I2C
- programowany USART do transmisji przez RS232
- szeregowy interfejs Master/Slave SPI
- programowany tirem Watchdog z oddzielnym (wbudowanym) oscylatorem
- wbudowany komparator analogowy
• specjalne wyposażenie mikrokontrolera:
- zerowanie po włączeniu mikrokontrolera - wewnętrzny kalibrowany oscylator RC
- wewnętrzne oraz zewnętrzne źródła sygnałów przerwań
- pięć trybów uśpienia: Idle, ADC Noise Reduction, Power - save, Power - down i Standby
• 23 linie I/O dowolnego wykorzystania
• zakres napięć zasilających mikrokontroler:
- 2,7…5,5 V (ATmega8L)
- 4,5…5,5 V (Atmega8)
• zakres częstotliwości sygnału taktującego mikrokontroler:
- 0…8 MHz (ATmega8L)
- 0…16 MHz (ATmega8)
• pobierany prąd przy częstotliwości sygnału taktowania 4 MHz i przy napięciu zasilania 3 V (ATmega8L):
- w stanie aktywnym: 3,6 mA
- w trybie Idle: 1 mA
- w trybie Power - down: 0,5 μA !
W większości systemów mikroprocesorowych wykorzystuje się takie bloki funkcjonalne jak: zegary czasu rzeczywistego, LCD i LED itp., dlatego w zaprojektowanym układzie testowym
(z mikrokontrolerem ATmega8) zastosowano takie układy peryferyjne, które umożliwiają także komunikowanie się systemu ze światem zewnętrznym. Dużą zaletą układu jest możliwość budowania bez użycia lutownicy prostych układów do sprawdzenia różnych koncepcji układów sterowania. Potrzebne połączenia mogą być wykonywane specjalnymi przewodami zakończonymi miniaturowymi wtykami. Układ uruchomieniowy nie jest przeznaczony tylko do współpracy z Bascomem AVR. Z powodzeniem może być wykorzystany przy przygotowywaniu programów, a także uczenie się programowania mikrokontrolerów AVR w innych środowiskach programistycznych.
Ze schematu wynika, że w układzie uruchomieniowym są dostępne elementy, z których (bez konieczności lutowania) można utworzyć wiele różnych układów mikroprocesorowych.
W układzie są bowiem następujące elementy:
• mikrokontroler ATmega8 (U1), który może być traktowany wewnętrznym sygnałem zegarowym lub z zastosowaniem zewnętrznego rezonatora kwarcowego X1, dołączonego przez zworki JP2, JP3. Wszystkie wyprowadzeni mikrokontrolera ATmega8 są dostępne na podwójnych końcówkach, dlatego możliwe jest elastyczne wykorzystanie dostępnych portów mikrokontrolera. Elementy L1, C3, C4 tworzą filtr napięcia zasilającego wewnętrzny przetwornik A/C.
• S5, R24, C5, JP1 zapewniające zerowanie mikrokontrolera. Zerowanie można przeprowadzić przyciskiem S5. Zworka JP1 umożliwia dołączenie zewnętrznego obwodu zerującego do mikrokontrolera. W mikrokontrolerze ATmega8 można nie stosować zewnętrznego obwodu zerowania, dlatego linia zerowania RST może być wykorzystana jako zwyczajna linia I/O portu C
• złącze Z7 jest złączem programatora ISP. Służy ono do podłączenia programatora ze złączem Z2
• alfanumeryczny wyświetlacz LCD o organizacji 2*16 znaków. Jego zastosowanie umożliwia prezentację danych zobrazowujących wyniki działania opracowywanego oprogramowania. Potencjometr P1 służy do ustawienia kontrastu wyświetlacza.
• cztery wyświetlacze 7-segmentowe LED ze wspólną anodą są przeznaczone do prezentowania danych liczbowych. Na płytce układu uruchomieniowego można wykorzystać jeden wyświetlacz LED sterowany statycznie lub wszystkie cztery (chociaż mogą być wykorzystane tylko dwa lub trzy) przy sterowaniu multipleksowym. Wszystkie wyświetlacze LED są zasilane poprzez tranzystory T1-T4. Rezystory R9-R16 ograniczają prąd płynący przez diody segmentów wyświetlaczy LED.
• interfejs szeregowy RS232, który zrealizowano z wykorzystaniem konwertera poziomów U5. Poprzez złącze Z2 jest możliwa komunikacja z komputerem PC oraz innymi układami mikroprocesorowymi. Interfejs ten można wykorzystywać także podczas symulacji sprzętowej.
• konwerter I2C na 8-bitowy port I/O, który zrealizowano w układzie PCF8574. Układ ten może pracować zarówno z liniami wejściowymi jak i wyjściowymi, a także w trybie mieszanym (dowolne linie mogą być wejściowymi lub wyjściowymi). Adresy konwertera ustalono na stałe. Ten konwerter umożliwia wykonywanie eksperymentów z wykorzystaniem interfejsu I2C oraz większą liczbę portów o dodatkowy port 8-bitowy.
• na płytce układu są złącza Z5, Z6 (I2C), które umożliwiają dołączanie do niej zewnętrznych urządzeń sterowanych magistralą I2C. Rezystory R27 i R28 są konieczne do prawidłowej pracy magistrali I2C.
• port wyjściowy dużej mocy jest zbudowany z wykorzystaniem układu ULN2803A (U4). Umożliwia on sterowanie urządzeniami pobierającymi znaczny prąd (żarówki, przekaźniki, silniki DC czy silniki krokowe).
• osiem diod sygnalizacyjnych LED (D1…D8). Diody te można wykorzystać do sygnalizacji zdarzeń stwierdzonych przez zaprojektowany układ mikroprocesorowy. Rezystory R1…R8 ograniczają prądy płynące przez diody LED.
• złącze Z10 (1-Wire) umożliwia dołączanie elementów sterowanych za pomocą interfejsu
1-Wire. Do tego złącza można podłączyć wiele układów produkowanych przez firmę Dallas/Maxim, jak np.. scalone termometry, pastylki identyfikacyjne (iButton). Rezystor R26 jest konieczny do prawidłowej pracy dwukierunkowej magistrali 1-Wire.
• odbiornik transmisji danych w podczerwieni (np. dla kodu RC5) - U7. Odbiornik podczerwieni umożliwia sterowanie układem mikroprocesorowym nie tylko za pomocą lokalnej klawiatury, ale także pilotem zdalnego sterowania.
• złącze Z11 (Servo) służy do dołączenia serwomechanizmu modelarskiego.
• na płytce zostały umieszczone przyciski ogólnego przeznaczenia S1-S4. W zależności od wartości napięcia (0 V lub 5 V) na wyprowadzeniach R1 i R2, na wejścia portów mikrokontrolera, do których będą one podłączane, będzie po ich przyciśnięciu podawany odpowiednio poziom niski lub wysoki.
• złącze Z1 umożliwia dołączenie do płytki klawiatury PC ze złączem PS2. W Bascomie obsługa klawiatury PC jest bardzo łatwa. Rezystory R22 i R23 są wymagane do poprawnej komunikacji mikrokontrolera z klawiaturą PC.
• na złącza Z4, Z8, Z9 (AUX) wyprowadzone zostały napięcia zasilające płytkę (masa i +5 V) oraz linie uniwersalne oznaczone A1-A6 - umożliwiają dołączenie do płytki elementów zewnętrznych, jak przyciski, przekaźniki itp.
• potencjometr P2 umożliwia podanie na wejście przetwornika A/C zawartego w mikrokontrolerze ATmega8 napięcia z zakresu 0 - 5 V.
• w podstawkę U2 można włożyć dowolny układ 14-pinowy.
• w podstawkę U3 można włożyć dowolny układ 16-pinowy.
PROGRAMOWANIE MIKROKONTROLERA
W celu poznania podstaw programowania mikrokontrolerów, posłużono się jednym z dostępnych i prostych narzędzi jakim jest środowisko programistyczne Bascom, dedykowane dla mikrokontrolerów AVR firmy ATMEL, opracowane przez firmę MCS Electronics z Holandii.
Struktura pliku źródłowego
W Bascomie nie ma ściśle określonej struktury pliku źródłowego przygotowywanego programu, lecz dla większej jego przejrzystości pisany program można podzielić na bloki zawierające deklaracje oraz definicje podprogramów, zmiennych, stałych, aliasów (nazw zamiennych) i blok głównej części programu. Samo programowanie odbywa się w postaci listingu. Tak napisany program jest bardzo czytelny nie tylko dla jego autora, ale także dla osoby postronnej, zapoznającej się z programem. Instrukcją End kończy działanie programu. Po wykonaniu tej instrukcji wyłączane są wszystkie przerwania oraz wykonywana jest tak zwana nieskończona pętla. Zawsze należy więc na końcu programu głównego umieścić instrukcję End w celu uniknięcia niekontrolowanego działania programu.
Dobrym nawykiem programisty jest umieszczanie w pisanym programie komentarzy i objaśnień informujących o sposobie działania instrukcji czy poszczególnych bloków programu. Umożliwią one po pewnym czasie łatwe odtworzenie działania programu, co jest konieczne przy jego modyfikacji. Czytelność programu ułatwiają także dodatkowe wcięcia instrukcji znajdujących się w pętlach, instrukcjach warunkowych czy w podprogramach.
Znaki w Bascom Basic
Zestaw znaków w języku Bascom zawiera wszystkie znaki łacińskiego alfabetu, to jest znaki od A do Z i a…z, a także znak dolnej kreski (np. poprawna jest nazwa zmiennej: _wartość czy zmienna_licznikowa) i cyfry od 0…9. Stosowanie dolnej kreski poprawia czytelność długich nazw zmiennych, których człony nie mogą być rozdzielane spacją. Na przykład nie można nazwać zmiennej Czekaj Sekunde, ale prawidłowa jest nazwa: CzekajSekunde lub bardziej czytelnie Czekaj_sekunde. Polskie litery mogą występować tylko w komentarzach i ewentualnie w treści zmiennych tekstowych.
W języku Bascom są używane znaki o predefiniowanym znaczeniu. Należą do nich:
ENTER znak końca linii programu
Znak rozdzielający (spacja)
' znak początku komentarza (apostrof)
* znak operacji mnożenia (gwiazdka)
+ znak operacji dodawania (plus)
, znak rozdzielający argumenty instrukcji (przecinek)
- znak operacji odejmowania (minus)
. oddziela część całkowitą od ułamkowej (kropka)
/ znak operacji dzielenia (kreska ukośna)
: rozdziela instrukcje zapisane w jednej linii (dwukropek)
'' rozpoczyna i kończy stałe tekstowe (cudzysłów)
; rozdziela argumenty instrukcji wejścia/wyjścia (średnik)
< znak operacji porównywania (mniejszy niż)
= występuje w operacjach przypisania oraz porównywania (znak równości)
> znak operacji porównywania (większy niż),
\ znak dzielenia dla liczb całkowitych (odwrotna kreska ukośna)
^ znak operacji potęgowania (daszek)
Bascom umożliwia zapis liczb nie tylko w postaci dziesiętnej, ale także w postaci szesnastkowej lub dwójkowej. Zapis liczby w postaci szesnastkowej powinien być poprzedzony przedrostkiem &przedrostkiem (np. &H3F). Przy zapisie liczby w postaci dwójkowej jest stosowany przedrostek &B (np. &B10011100). Liczby zapisywane bez przedrostków będą przez kompilator domyślnie traktowane jako dziesiętne.
Struktura linii programu
Pojedyńcza linia programu w języku Bascom może zawierać następujące części:
[[identyfikator:]] [[instrukcja]] [[:instrukcja]]…[[' komentarz]]
W jednej linii może znajdować się kilka instrukcji oddzielonych znakiem dwukropka (:). Ale można też pisać każdą instrukcję w oddzielnym wierszu. Na przykład:
[[identyfikator:]]
[[instrukcja]] … [[' komentarz]]
[[instrukcja]] … [[' komentarz]]
Identyfikator, nazywany też etykietą, może składać się z dozwolonych liter lub cyfr i zawierać od 1 do 32 znaków. Musi zaczynać się literą, a kończyć dwukropkiem. Etykietą nie może być żadna z instrukcji słów kluczowych języka, chociaż mogą one być zawarte w treści etykiety. Na przykład, prawidłowymi etykietami są:
Skok1:
ZapiszZmienna:
Porównaj3wartosc:
Ponieważ kompilator Bascoma nie rozróżnia wielkości liter, to podane dalej etykiety są dla kompilatora tymi samymi.
Podziel:
podziel:
PODZIEL:
Etykiety są wykorzystywane w instrukcjach skoków do podprogramów (w tym obsługi przerwań), a także do zmiany kolejności wykonywania instrukcji programu poprzez skoki do etykiet. Zmiana kolejności wykonywania instrukcji programu poprzez bezpośrednie skoki do etykiet nie jest zalecana, gdyż obniża przejrzystość programu oraz utrudnia jego późniejszą interpretację. Skoki do etykiet można zastąpić odpowiednim zastosowaniem podprogramów oraz pętli wykonywanych warunkowo. Najlepiej, więc zapomnieć o możliwości skoków do etykiet.
Linie programu w Bascomie mogą być wykonywalne albo niewykonywalne. Linie wykonywalne (instrukcje) tworzą działający program realizujący określony algorytm. Linie niewykonywalne tworzą część informacyjną oraz organizacyjną programu. Do najważniejszych linii tego rodzaju należą:
- linie komentarza - rozpoczynająca się słowem Rem lub znakiem apostrofu (')
- linie deklaracji - zawierające słowa Dim, Declare
- linie dyrektyw kompilatora - rozpoczynających się znakiem dolara ($)
Komentarze mogą rozpoczynać się słowem Rem lub znakiem apostrofu. Należy jednak pamiętać, że komentarz rozpoczynający się słowem Rem, umieszczony w linii z instrukcją programu, musi być od niej oddzielony znakiem dwukropka i musi być na końcu danej linii programu. Oto przykład:
LCD ”Bascom” : Rem wyświetla na LCD napis Bascom
'nie może już być kolejnych instrukcji w powyższej linii
Komentarze mogą być używane nie tylko w postaci pojedynczych linii, ale także w postaci bloku, którego początek jest oznaczany znakami '(, a koniec ').
Komentarze w postaci bloków są pomocne, gdy fragment programu ma nie być poddany kompilacji.
Rozdzielanie instrukcji znakiem dwukropka stosuje się wtedy, gdy w linii programu występuje więcej niż jedna instrukcja.
Stałe
Stałe w programie umożliwiają przypisanie nazwy dowolnej liczbie, tekstowi lub wyrażeniu. Są bardzo pomocne, gdy używamy tych samych wartości w wielu miejscach programu. Aby zmienić te wartości, trzeba je zmieniać wszędzie tam gdzie występują. Gdy zdefiniujemy je jako stałe, wystarczy tylko zmienić wartość stałej, a kompilator wstawi nowe wartości w odpowiednich miejscach programu. Stałe nie zajmują pamięci przeznaczonej na zmienne, gdyż zawsze podczas kompilacji miejsce nazwy stałej jest wpisywana jej wartość. Składnia instrukcji definiującej stałą jest następująca:
Const nazwa = liczba
Const nazwa = ”tekst”
Const nazwa = wyrażenie
Gdzie:
Nazwa - nazwa identyfikująca stałą
Liczba - wartość liczbowa przypisana stałej
Tekst - wartość tekstowa przypisana stałej
Wyrażenie - dowolne wyrażenie w języku Bascom BASIC.
Przykładowe definicje stałych:
Const H = ”Witaj” 'definicja stałej tekstowej musi być w cudzysłowie,
Const B = 5 'definicja stałej liczbowej,
Const C = &B10011111 'definicja stałej zapisanej binarnie.
Definiowanie aliasów
W programie mogą być stosowane aliasy (nazwy zamienne), które pozwalają na zmianę nazw zmiennych na bardziej przyjazne. Dzięki tej instrukcji można zmienić predefiniowane nazwy rejestrów czy portów procesora na bardziej czytelne. Nie jest wskazane stosowanie aliasów do zdefiniowanych nazw zmiennych. Składnia instrukcji definiującej alias jest następująca:
nowa_nazwa Alias stara_nazwa
gdzie:
stara_nazwa - aktualna nazwa zmiennej lub rejestru
nowa_nazwa - nowa nazwa zmiennej lub rejestru
Przykładowe definicje aliasów:
Wyjscie1 Alias Portb.1 'można używać nazwy Wyjscie1 zamiast Portb.1
Wejście1 Alias Pinb.2 'można używać nazwy Wejscie1 zamiast Pinb.2
Przycisk Alias Pind.1 'można używać nazwy Przycisk zamiast Pind.1.
Zdefiniowanie własnych aliasów znacznie ułatwia pisanie i interpretację programu. Znacznie lepiej jest korzystać z nazwy Przycisk niż z Pind.1 (jedna z linii portu D mikrokontrolera).
Typy zmiennych
Każda ze definiowanych w programie zmiennych musi mieć określony typ. W języku Bascom są predefiniowane następujące typy:
Bit (1/8 bajta) - może przyjmować tylko dwie wartości: 0 i 1
Byte (1 bajt) - może przyjmować wartość dowolnej dodatniej liczby całkowitej z zakresu od 0 do 255
Integer (2 bajty) - może przyjmować wartość dowolnej liczby całkowitej z zakresu od
-32768 do +32767
Long (4 bajty) - może przyjmować wartość dowolnej liczby całkowitej z zakresu od -232 do 232-1
Word (2 bajty) - może przyjmować wartość dowolnej dodatniej liczby całkowitej z zakresu od 0 do 65535
Single (4 bajty) - może przyjmować wartość dowolnej liczby stałoprzecinkowej lub zmiennoprzecinkowej
String (maks. 254 bajty) - przechowuje łańcuch dowolnych znaków o długości nie większej niż 254 znaki, łańcuch jest zawsze zakończony znakiem 0, a więc tekst o długości 20 znaków zajmuje 21 bajtów.
Zmienne typu Byte, Integer, Long, Word i Single są nazywane zmiennymi numerycznymi, a typu String zmiennymi tekstowymi lub łańcuchami znaków. Domyślnie na zmienne zostaje przeznaczony obszar wewnętrznej pamięci SRAM mikrokontrolera. Można to zmienić stosując odpowiednie dyrektywy kompilatora lub określając indywidualnie dla każdej zmiennej obszar pamięci.
Zmienna jest obiektem programu pamiętającym dane. Zmiennej jest przyporządkowany określony obszar pamięci identyfikowany nazwą (identyfikatorem) nadaną jej przez programistę. Wielkość tego obszaru jest ściśle zależna od liczby bajtów potrzebnych na zapamiętanie zmiennej danego typu. W zmiennych numerycznych można przechowywać tylko dane liczbowe. W zmiennych łańcuchowych typu String tylko dane bedące znakami lub łańcuchem znaków. Zmienne tego samego typu mogą być łaczone w większe uporządkowane zbiory, zwane tablicami. Przykłady przypisań zmiennym jakichś wartości:
X = 5 'zmienna X jest typu Byte
Y = 2.6 'zmienna Y jest typu Single
Z = ”lancuch” 'zmienna Z jest typu String
Możliwe jest także przypisanie zmiennej wartości innej zmiennej:
Wartosc1 = wartosc2
Bascom umożliwia zmianę wartości (przypisanie) wybranych bitów w zmiennych oraz rejestrach mikrokontrolera. Zmianę wartości określonego bitu zmiennej (lub rejestru) można wykonać przez dopisanie do nazwy zmiennej (po kropce) numeru zmienianego bitu z zakresu 0…7. Dla zmiennej typu Byte o nazwie Flagi można w następujący sposób zmienić dowolny jej bit:
Flagi.1 = 1 'przypisanie 2. bitowi wartości 1 (numeracja bitów od 0)
Flagi.5 = 0 'przypisanie 6. bitowi wartości 0 (numeracja bitów od 0)
Operacje na bitach rejestrów są często wykonywane na rejestrach sterujących portami mikrokontrolera. Dzięki tej możliwości można bardzo łatwo zmienić stan tylko jednej linii portu.
Zmiennym można także przypisywać wyniki operacji matematycznych:
Temp1 = X + 5
Temp2 = Y + 3.4
Bascom pozwala na przypisanie do zmiennej wyniku jednej operacji matematycznej wykonywanej tylko na dwóch zmiennych. Nie można stosować w jednej instrukcji przypisania więcej niż jednej operacji matematycznej. Na przykład nie prawidłowa jest instrukcja przypisania:
Temp1 = (X + 5) * 5 'kompilator zasygnalizuje błąd
Takie obliczenia trzeba rozłożyć na kilka instrukcji przypisań. Może to być tak jak poniżej:
Temp1 = X + 5 'dodanie do zmiennej X wartości 5
Temp1 = Temp1 * 5 'pomnożenie dodanej wartości przez 5
Nazwy zmiennych w języku Bascom są objęte tymi samymi ograniczeniami, jak nazwy etykiet. Ich długość nie powinna przekraczać 32 znaków. Nazwa może składać się z dowolnych liter i liczb (oprócz polskich znaków) oraz musi się rozpoczynać od litery. Nazwą zmiennej nie może być żadne z zastrzeżonych słów języka Bascom, tj. nazwa instrukcji, rejestru procesora czy dyrektywy. Dla przykładu, podana niżej nazwa zmiennej nie jest prawidłowa, gdyż w języku Bascom jest to słowo zarezerwowane dla operatora sumy logicznej (Or):
Or = 2 'nieprawidłowa nazwa zmiennej
Natomiast prawidłowa jest nazwa zmiennej:
Orr = 2
gdyż nie ma jej na liście słów zastrzeżonych (kluczowych).
Listę wszystkich zastrzeżonych słów można znaleźć w pliku pomocy.
Każda zmienna przed użyciem w programie powinna zostać wcześniej zdefiniowana. Jest to niezbędne, gdyż kompilator musi określić rozmiar pamięci przeznaczony na tę zmienną. Chociaż zmienne można definiować w dowolnym miejscu programu, to zaleca się umieszczenie tych definicji zawsze w części początkowej programu. Zmienne definiuje się instrukcją Dim (rozmiar) o następującej składni:
Dim nazwa [(rozmiar)] As [XRAM ERAM SRAM] typ [At adres] [Overlay]
Gdzie:
nazwa - nazwa identyfikująca zmienną,
rozmiar - parametr zmiennych tablicowych - liczba elementów tablicy,
typ - typ zmiennej,
adres - przypisuje (opcjonalny) adres bezwzględny zmiennej, pod którym ma być umieszczona.
W instrukcji może być wiele parametrów opcjonalnych takich jak: XRAM, ERAM, SRAM, At i Overlay. Zdefiniowane zmienne są domyślnie umieszczane w pamięci SRAM mikrokontrolera, jeśli nie zastosowano parametrów XRAM lub ERAM. Gdy zastosowano parametr XRAM, zmienna zostanie umieszczona w pamięci zewnętrznej mikrokontrolera, natomiast parametr ERAM spowoduje, że zmienna zostanie umieszczona w wewnętrznej pamięci EEPROM mikrokontrolera. Parametr At pozwala na umieszczenie zmiennej w obszarze obszarze początkowym bajcie określonym przez parametr adres. Gdyby pod podanym adresem znajdowała się już jakaś zmienna, to definiowanej zmiennej zostanie przydzielony obszar pod najbliższym wolnym adresem. Parametr Overlay powoduje utworzenie nakładki, co oznacza, że zmienna o wskazanym adresie wykorzystuje bajty zajmowane przez inną zmienną, którą zdefiniowano wcześniej pod podanym adresem. Można w ten sposób odwoływać się (zapisywać, odczytywać) do poszczególnych bajtów (słów) tej zmiennej. Przykładowe definicje zmiennych:
Dim Flaga As Bit - definiowana jest zmienna Flaga typu Bit (bit może mieć wartość 0 lub 1),
Dim A As Byte - definiowana jest zmienna A typu Byte w pamięci SRAM,
Dim Zew As XRAM Long - definiowana jest zmienna Zew typu Long w obszarze pamięci XRAM,
Dim Eep As ERAM Byte - definiowana jest zmienna Eep typu Byte w obszarze pamięci EEPROM,
Dim Zw As Integer - definiowana jest zmienna Zw typu Integer (2 bajty) w pamięci SRAM,
Dim X As Long At &H60 - definiowana jest zmienna X typu Long, która zajmuje obszar o adresach &H60, &H61, &H62, &H63 w pamięci SRAM,
Dim B1 As Byte At &H60 Overlay
- definiowana jest zmienna B1 typu Byte pod adresem &H60, jest ona jednocześnie pierwszym bajtem (nadpisuje go) zmiennej X (ma ten sam adres),
Dim B2 As Byte At &H61 Overlay
- definiowana jest zmienna B2 typu Byte pod adresem &H61, jest ona drugim bajtem zmiennej X,
Dim B3 As Integer At &H62 Overlay
- definiowana jest zmienna B3 typu Integer, jest ona tożsama z dwoma kolejnymi bajtami zmiennej X.
Zmienne B1, B2 oraz B3 w powyższych przykładach nie są samodzielnymi (niezależnymi) zmiennymi. Ich nazwy, przez zastosowanie parametru Overlay, pozwalają odwoływać się bezpośrednio do określonych bajtów zmiennej X lub dowolnych bajtów pamięci, w tym przypadku do bajtów pod adresami &H60, &H61, &H6 i &H63. Zapisując dane pod adres wskazywany przez B1, B2 lub B3, zapisujemy je do obszaru zajmowanego przez zmienną X, gdyż zmienna ta zajmuje bajty pod tymi adresami (typ Long używa 4 bajtów). Można również odczytywać zawartość bajtów wskazywanych przez zmienne B1, B2, B3, które są w istocie bajtami zmiennej X. Na przykład instrukcje:
Lcd B1: Lcd B2: Lcd B3,
powodują wyświetlenie na wyświetlaczu LCD wartości zmiennych B1, B2 i B3.
Używając wskaźników (zmiennych zdefiniowanych z parametrem Overlay) można „manipulować” bajtami tworzącymi „prawdziwe” zmienne. Na przykład:
Dim L As Long At &H60 - definicja zmiennej L typu Long od adresu &H60
Dim W As Word At &H62 Overlay - definicja zmiennej W typu Word od adresu &H62
W tym przykładzie zmienna W wskazuje na dwa bardziej znaczące bajty zmiennej L typu Long.
Zmienne tekstowe typu String wymagają zastosowania dodatkowego parametru określającego ich przewidywaną długość w znakach. Na przykład:
Dim Napis as String * 20 - definiowana jest zmienną Napis typu String o długości do 20 znaków w pamięci SRAM,
Dim S As XRAM String * 10 - definiowana jest zmienną S typu String o długości do 10 znaków w pamięci XRAM.
Zmienne typu String zakończone są dodatkowym bajtem o wartości 0, wskazującym na koniec ciągu znaków. W instrukcji przypisania wartości stałej do zmiennej typu String, należy wartość zmiennej (łańcuch) zapisywać w cudzysłowie:
S = „Bascom” - prawidłowe przypisanie,
S = AVR - przypisanie nieprawidłowe.
W wartości zmiennych typu String mogą występować kody ASCII dowolnych znaków. Jest to bardzo pomocne przy braku jakiegoś znaku na klawiaturze. Wplatany kod znaku ASCII w łańcuch powinien być zawarty w nawiasach {}. Na przykład:
St = „B{097}scom” - do zmiennej St wpisano słowo (łańcuch) Bascom
Znak o kodzie 097 to litera a, a więc zmienna St będzie przechowywać napis Bascom. Należy pamiętać, że zdefiniowane zmienne bitowe mogą być umieszczane tylko w pamięci SRAM (wewnętrznej). Nie można ich definiować w innych pamięciach. Na przykład:
Dim Flag1 As Bit - definicja zmiennej bitowej Flag1 prawidłowa,
Dim Flag2 As ERAM Bit - definicja zmiennej bitowej Flag2 nieprawidłowa,
Dim Flag3 As XRAM Bit - definicja zmiennej bitowej Flag3 nieprawidłowa.
W jednej instrukcji Dim można zdefiniować kilka zmiennych oddzielając je przecinkiem.
Na przykład:
Dim A As Byte, B As Integer - definiowana jest zmienna A typu Byte i zmienna B typu Integer.
Ponieważ wielkość obszaru przeznaczonego na zmienne zależy od typu mikrokontrolera, dlatego zawsze należy „poinformować” kompilator instrukcją Dim o zamiarze używania zmiennej. Jeśli zabraknie miejsca w pamięci na definiowaną zmienną, to kompilator nas o tym powiadomi. Definiowanie zmiennych i informacje zwrotne kompilatora tworzą mechanizm bezpiecznego gospodarowania zasobami pamięci SRAM.
Bascom umożliwia także definiowanie typu użytych w programie zmiennych (nie zdefiniowanych instrukcją Dim), dzięki użyciu następujących instrukcji: Defint (definiuje zmienną typu Integer), Debit (definiuje zmienną typu Bit), Defbyte (definiuje zmienną typu Byte), Defword (definiuje zmienną typu Word), Deflng (definiuje zmienna typu Long) lub Defsng (definiuje zmienną typu Single). Na przykład instrukcja:
Defint A
spowoduje , że wszystkie zmienne użyte w programie, których nazwa zaczyna się literą A, a nie były wcześniej zdefiniowane instrukcją Dim, będą zmiennymi typu Integer. Na przykład:
A = 50 - zmienna typu integer,
Ala = 100 - zmienna typu integer.
Zmienne A oraz Ala będą różnymi zmiennymi (jak byłyby zdefiniowane dwoma instrukcjami Dim).
Na zmiennych zdefiniowanych w pamięci ERAM (EEPROM) nie można wykonywać operacji matematycznych, lecz jedynie zapisywać lub odczytywać wartości. Do takiej zmiennej nie można na przykład, bezpośrednio dodać wartości jak poniżej:
Zm = Zm + 1 - jeśli Zm jest zmienną w pamięci EEPROM, to instrukcja jest błędna.
Tego typu instrukcja (zmienna Zm umieszczona w pamięci EEPROM) będzie powodować błąd kompilatora. Aby wykonać takie działanie matematyczne, należy posłużyć się dodatkową zmienną umieszczoną w pamięci SRAM lub XRAM.
Niektóre mikrokontrolery AVR nie mają wewnętrznej pamięci SRAM, a zamiast niej używa się rejestrów roboczych R0 … R31. Aby w Bascomie można było definiować zmienne w rejestrach mikrokontrolera, należy posłużyć się instrukcją Dim z parametrem IRAM. Na przykład:
Dim X IRAM As Byte - definiuje zmienną X typu Byte w jednym z rejestrów roboczych mikrokontrolera.
Zmienną można zdefiniować także w wybranym rejestrze roboczym mikrokontrolera, korzystając z dodatkowego parametru At. Na przykład:
Dim I As IRAM Byte At 15 - definiuje zmienną I typu Byte w rejestrze roboczym R15 mikrokontrolera.
Ograniczeniem mikrokontrolerów bez pamięci SRAM jest niewielka liczba możliwych do zdefiniowania zmiennych oraz to, że większość Bascomowych instrukcji nie będzie działać. Przy programowaniu mikrokontrolerów bez pamięci SRAM, należy zastosować dyrektywę $TINY, która instruuje kompilator, aby pominął fragment programu ustawiający stos w procedurze inicjalizacji, gdyż Bascom używa pamięci SRAM na potrzeby programowego i sprzętowego stosu, która w niektórych mikrokontrolerach AVR nie występuje.
Zarządzanie pamięcią w Bascom
Każda ze zdefiniowanych w programie zmiennych zajmuje pewien obszar pamięci. Domyślnie jest to wewnętrzna pamięć danych mikrokontrolera zwana SRAM. Pojemność tej pamięci jest ściśle określona i zależna od typu mikrokontrolera. Specjalnym obszarem pamięci SRAM jest obszar zajmowany przez rejestry uniwersalne. Rejestry te, ponumerowane od R0 do R31, zajmują 32 początkowe słowa tej pamięci. Rejestry są w różnym stopniu używane przez instrukcje języka Bascom. Część pamięci SRAM, która nie jest zajęta przez rejestry i zmienne, nie jest używana przez kompilator. Obszar tej pamięci nie zajmowany przez stos sprzętowy i programowy oraz tzw. ramkę. Niektóre z instrukcji Bascoma, mogą używać przestrzeni pamięci SRAM na własne potrzeby. Ponieważ niektóre mikrokontrolery mają niewielkie rozmiary pamięci SRAM, należy nią oszczędnie gospodarować. Tam gdzie jest to możliwe, należy używać zmiennych bitowych lub bajtowych. A tylko tam, gdzie jest to konieczne, należy używać zmiennych zajmujących więcej pamięci. Bascom część dostępnej pamięci SRAM wykorzystuje na stos programowy, który jest używany do przechowywania adresów parametrów procedur i funkcji oraz ich zmiennych lokalnych. Dla każdej zmiennej lokalnej oraz każdego parametru są używane 2 bajty do zapamiętania adresów pamięci. Gdy przykładowo procedura ma 4 zmienne lokalne oraz 5 przekazywanych parametrów, to obszar potrzebny na stos programowy będzie wynosił (5+4)*2=18 bajtów. Jeżeli przygotowany program zajmuje więcej pamięci SRAM niż jest w mikrokontrolerze, można zmniejszyć do minimum rozmiar stosu programowego, obliczając pojemność stosu potrzebnego na zmienne lokalne i parametry procedur w sposób pokazany wyżej.
Wartości zmiennych lokalnych przechowywane są w obszarze tzw. ramki. Jeżeli procedura używa 2 lokalnych zmiennych typu Byte (1 bajt) oraz Integer (2 bajty), zapotrzebowanie pamięci na ramkę wyniesie: 1+2=3 bajty. Zarówno wartości obszaru ramki jak i stosu programowego można określić w opcjach kompilatora w zakładce Chip. Zmniejszając obszar ramki, można także zyskać kilkanaście bajtów pamięci SRAM. Należy jednak zwrócić uwagę, by wartość ramki nie była mniejsza niż 16 bajtów. Z ramki korzystają nie tylko zmienne lokalne definiowane przez programistę, ale również zmienne lokalne tworzone niejawnie przez niektóre instrukcje Bascoma. Z ramki bardzo często korzystają instrukcje konwersji. Na przykład instrukcja: Val(Tekst) zmienia tekstową reprezentację liczby na jej postać dziesiętną, Str(X) zwraca tekstową reprezentację liczby. Ramka jest także wykorzystywana w wielu innych instrukcjach, jak np. Print (wysyła znaki przez RS232), gdyż korzystają z wewnętrznych funkcji konwersji. Instrukcji wykorzystujących ramkę jest wiele i zazwyczaj nie potrzebują one więcej niż 16-bajtowej ramki. Pozostałe bajty ramki są wykorzystywane na dane lokalne.
Do mikrokontrolerów niektórych typów jest możliwe dołączenie zewnętrznej pamieci, która jest nazywana pamięcią XRAM. Na przykład, zewnętrzna pamięć XRAM można w bardzo prosty sposób dołączyć do mikrokontrolera ATmega8515. Gdy dołączona pamięć będzie miała rozmiar 32 kB, jej pierwsza komórka będzie miała adres 0, lecz początkowa część tej pamięci zostanie przykryta przez pamięć SRAM. Pierwsza dostępna komórka pamięci XRAM będzie więc miała adres &H260 (dla ATmega8515). Bardzo często zewnętrzna pamięć będzie wykorzystywana do przechowywania dużych ilości danych, na przykład zebranych z pomiarów. Większość procesorów serii AVR ma wbudowaną pamięć EEPROM. Pamięć tego rodzaju jest oznaczona w języku Bascom skrótem ERAM. Pamięć ERAM bardzo często jest wykorzystywana do przechowywania parametrów konfiguracyjnych zbudowanego urządzenia, które powinny być odtworzone po włączeniu napięcia zasilania. Bascom umożliwia użycie pamięci ERAM tak jak normalnej pamięci SRAM czy XRAM, w której można umieszczać dane lub zmienne. Jednak należy uważać i pamiętać, aby nie lokować zmiennych w ERAM, do których będą często zapisywane dane (często zmieniające się wartości zmiennych), gdyż pamięć EEPROM ma ograniczoną żywotność. Producent gwarantuje tylko 100 000 operacji zapisu. Przekroczenie tej liczby może nastąpić szybko przy często zmieniających się wartościach zmiennych. Wszystkie stałe występujące w programie są zapamiętane w specjalnej tablicy, która jest umieszczona w pamięci przeznaczonej na program (kod wynikowy). Podczas kompilacji jest dokonywana prosta optymalizacja kodu źródłowego programu, polegająca na wykrywaniu powtórzeń stałych.
Przykłady programów sterowania
Do każdego z niżej przedstawionych programów, poniżej podana jest konfiguracja połaczeń pomiędzy wyświetlaczem LCD umieszczonym w stanowisku mikrokontrolera AVR. Wyświetlacz LCD jest podłączony na stałe do odpowiednich portów procesora i po wgraniu każdego programu sterowania wyświetlana jest nazwa programu.
LCD
EN → PD2
RS → PD3
D4 → PD4
D5 → PD5
D6 → PD6
D7 → PD7
L + → VCC
PRZERZUTNIK BISTABILNY
Przewody łączące DIODY LED:
PC4 → D1
PC5 → D2
Przyciśnięcie przycisku S1 powoduje zmianę stanu przerzutnika na logiczne „zero”. Zapala się jednocześnie dioda LED1 a gaśnie LED2. Przyciśnięcie przycisku S2 powoduje zmianę stanu przerzutnika na logiczną „jedynkę”, jednocześnie gaśnie dioda LED1, i zapala się dioda LED2.
$regfile = "m8def.dat"
$crystal = 8000000
' Konfiguracja wyswietlacza LCD
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Config Pinc.0 = Input ' switch 1 "S"
Config Pinc.1 = Input 'switch 2 "R"
Config Pinc.4 = Output 'wyjscie 1 "Q"
Config Pinc.5 = Output 'wyjscie 2 "NIE-Q"
Set Portc.0
Set Portc.1
' petla glowna
Cls
Upperline : Lcd "przerzutnik"
Lowerline : Lcd "bistabilny"
set Portc.4
Set Portc.5
Do
Waitms 25
'stan niedozwolony
If Pinc.1 = 0 And Pinc.0 = 0 Then
Set Portc.4
set Portc.5
Waitms 25
Lowerline : Lcd " NIEDOZWOLONY! "
Else
'set
If Pinc.0 = 0 Then
Set Portc.4
Reset Portc.5
Waitms 25
Lowerline : Lcd " SET! "
End If
'reset
If Pinc.1 = 0 Then
Reset Portc.4
Set Portc.5
Waitms 25
Lowerline : Lcd " RESET ... "
End If
End If
Loop
PRZERZUTNIK MONOSTABILNY
DIODY LED
PC4 → D1
Przerzutnik taki ma jeden stan stabilny. Po przyciśnięciu przycisku zostaje wygenerowany impuls, oraz na czas jego trwania jest zapalana dioda LED.
'nacisniecie SW1 generuje logiczna jedynke na 2 sekundy
' Konfiguracja
$regfile = "m8def.dat"
$crystal = 8000000
' konfiguracja portow
Config Pinc.0 = Input 'przycisk S1 jako port we
Config Pinc.4 = Output 'dioda LED1 jako wy
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Cls
Lcd "przerzutnik"
Lowerline
Lcd "monostabilny"
Set Portc.0
Portc.4 = 1 'wylaczenie diody
Do
If Pinc.0 = 0 Then
Portc.4 = 0 ' załacznie lampki
Wait 4 'odmierza czas ..sek
End If
Portc.4 = 1
Loop
WOLTOMIERZ 1-KANAŁOWY
POTENCJOMETR REG1 → PC2
Program woltomierza cyfrowego prowadzi pomiar jednego napięcia poprzez wbudowany w mikrokontroler przetwornik analogowo-cyfrowy. Przetwornik ten jest 4-kanałowy, w programie wykorzystywany jest tylko jeden kanał.
Układ pomiarowy składa się z potencjometru zasilanego napięciem 5 V, którego wyjście (zaczep środkowy) jest podłączone do wejścia przetwornika. Kręcąc gałką potencjometru zmieniamy napięcie na jego wyjściu w zakresie 0-5 V. Zmiany są na bieżąco wyświetlane w programie.
' uzywamy procesora ATMega8
$regfile = "m8def.dat"
' częstotliwość kwarcu
$crystal = 8000000
' Konfiguracja wyswietlacza LCD
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
' konfiguracja wyjsc
Config Pinc.2 = Input ' wejście przetwornika
Dim Wartosc As Word
Dim Napiecie As Single
Dim Przelicznik As Single
' konfiguracja przetwornika
Config Adc = Single , Prescaler = Auto , Reference = Avcc
' Procedura glowna programu
'=============================================================
'Wystartuj przetwornik
Start Adc
Cursor Off
Upperline : Lcd " Multimetr "
Lowerline : Lcd "Napiecie:" : Lcd Wartosc : Lcd " "
' wartosc przelicznika dla napiecia
Przelicznik = 0.00484282907
'Petla zczytywania przetwornika
Wartosc = 0
Do
'pobieranie wartosci z przetwornika z kanalu drugiego (PA.2)
Wartosc = Getadc(2)
' obliczanie napiecia
Napiecie = Przelicznik * Wartosc
Napiecie = 5 - Napiecie
Lowerline : Lcd "Napiecie:" : Lcd Napiecie : Lcd " "
Loop
KOMPARATOR ANALOGOWY
Poniższy program umożliwia wykorzystanie komparatora analogowego (zawartego wewnątrz struktury mikrokontrolera) dla celów porównywania dwóch wejściowych napięć.
'komparator analogowy
$regfile = "m8def.dat"
$crystal = 8000000
Config Pinb.1 = Output 'linia Pb1 jako wyjscie
Config Aci = On , Compare = Off , Trigger = Falling 'konfiguracja komparatora analogowego
Do
If Acsr.5 = 1 Then ' jesli bit AC0(5) rejestru ACSR rowny 1, to
Set Portb.1 ' zgas diode
Else 'w przeciwnym przypadku
Reset Portb.1 'zapal diode
End If
Loop
End
SILNIK KROKOWY
PB0 → IA
PB1 → IB
PB2 → IC
PB3 → ID
SILNIK KROKOWY
K1 → OA
K2 → OB
K3 → OC
K4 → OD
Wciskając przycisk S1 zębatka zamocowana na wale silnika krokowego zacznie się obracać w lewo.
Wciskając przycisk S2 zębatka zamocowana na wale silnika krokowego zacznie się obracać w prawo.
Układ ULN2803A składa się z ośmiu kanałów wzmacniaczy, przystosowanych do obciążenia elementami o charakterze rezystancyjno-indukcyjnym, dlatego w układzie tym zastosowano odpowiednio połączone diody, schemat połączeń wejść i wyjść tego układu przedstawiono na rysunku 4. Wszystkie wyjścia są typu otwarty kolektor.
Schemat i rozmieszczenie wyprowadzeń układu ULN2803.
Na rysunku 5 przedstawiono schemat pojedynczego kanał wzmacniacza, z wykorzystaniem tranzystorów połączonych w układzie Darlingtona, które wykorzystane są we wzmacniaczu o wspólnym emiterze. Diody służą do eliminacji ładunków gromadzonych w obciążeniu o charakterze indukcyjnym.
Budowa wewnętrzna jednego kanału wzmacniacza ULN2803.
Szczytowy prąd znamionowy obciążenia, jest równy 600mA (500mA ciągły), a maksymalne napięcie zasilania w stanie nieaktywnym wynosi 50V. Wyjścia mogą być łączone równolegle w celu zwiększenia maksymalnego prądu obciążenia.
$regfile = "m8def.dat"
$crystal = 8000000
Config Portb = Output
Config Pinc.0 = Input
Config Pinc.1 = Input
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Dim Time As Byte
Cls
Lcd "silnik krokowy"
Set Portc.0
Set Portc.1
Time = 10
Do
If Pinc.0 = 0 And Pinc.1 = 1 Then ' jeśli nacisniety przycisk S1
Portb = &B0000001
Waitms Time
Portb = &B0000010
Waitms Time
Portb = &B0000100
Waitms Time
Portb = &B0001000
Waitms Time
End If
' a jeśli S2 nacisniety to kombinacje w odwrotnej kolejnosci
If Pinc.1 = 0 And Pinc.0 = 1 Then
Portb = &B0001000
Waitms Time
Portb = &B0000100
Waitms Time
Portb = &B0000010
Waitms Time
Portb = &B0000001
Waitms Time
End If
Loop
SILNIK DC - sterowanie metodą PWM
SILNIK DC
VCC2 → DC1
OA → DC2
IA → PB1
Sterowanie silnikiem DC (wentylatorkiem) następuje na bazie modulacji PWM. Jest to sterowanie współczynnikiem wypełnienia impulsów prostokątnych napięcia, zasilającego silnik.
Przyciśnięcie przycisku S1 powoduje zwiększenie wypełnienia fali prostokątnej, zwiększenie średniego napięcia podawanego na silnik, a tym samym zwiększenie prędkości obrotowej silnika.
Przyciśnięcie przycisku S2 powoduje zmniejszenie wypełnienia fali prostokątnej, zmniejszenie średniego napięcia podawanego na silnik, a tym samym zmniejszenie prędkości obrotowej silnika.
$regfile = "m8def.dat"
$crystal = 8000000
' konfiguracja portow
Config Pinc.0 = Input
Config Pinc.1 = Input
Config Pinb.1 = Output
Config Timer1 = Pwm , Pwm = 8 , Prescale = 64 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Dim Wypelnienie As Byte
Cls
Lcd "silnik DC"
Set Portc.0
Set Portc.1
Pwm1a = 0
' Procedura glowna programu
Do
' jesli nacisne S1 to przyspiesz
If Pinc.0 = 0 Then
Waitms 15
If Pinc.0 = 0 Then
Incr Wypelnienie
' minimalnie
If Wypelnienie = 0 Then
Wypelnienie = 255
End If
Pwm1a = Wypelnienie
Waitms 15
End If
End If
' jesli nacisne S2 to zwolnij (zmiejsz wypelnienie)
If Pinc.1 = 0 Then
Waitms 15
If Pinc.1 = 0 Then
Decr Wypelnienie
' maksymalnie 255
If Wypelnienie = 255 Then
Wypelnienie = 0
End If
Pwm1a = Wypelnienie
Waitms 15
End If
End If
Loop
End
GENERATOR 2-TONOWY
BUZZER
BZ1 → PC3
Generator 2-tonowy generuje tony o dwóch różnych częstotliwościach.
Naciśnięcie i przytrzymanie przycisku S1 powoduje generowanie pierwszego tonu.
Naciśnięcie i przytrzymanie przycisku S2 powoduje generowanie drugiego tonu.
'GENERATOR 2-tonowy - wykorzystanie polecenia Sound
' Konfiguracja
$regfile = "m8def.dat"
$crystal = 8000000
Config Pinc.3 = Output 'przetwornik piezo jako wyjście
Config Pinc.5 = Output
Config Pinc.0 = Input
Config Pinc.1 = Input
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Cls
Lcd "generator"
Lowerline
Lcd "2-tonowy"
Set Portc.0
Set Portc.1
Do 'petla nieskonczona
If Pinc.0 = 0 Then ' pierwszy przycisk nacisniety
Waitms 30
Sound Portc.3 , 1000 , 500 'typowy sygnal
Toggle Portc.5
End If
If Pinc.1 = 0 Then ' drugi przycisk nacisniety
Waitms 30
Sound Portc.3 , 1000 , 1000
Toggle Portc.5
End If
Loop
End
KLAWIATURA PC
KLAWIATURA
DAT → PD0
CLK → PD1
Klawiatura komputerowa jest podłączona przez magistralę I2C. Pisany na klawiaturze PC tekst jest odczytywany przez mikrokontroler i wyświetlany na wyświetlaczu LCD.
$regfile = "m8def.dat"
$crystal = 8000000
'The GetATKBD() function does not use an interrupt.
'But it waits until a key was pressed!
'configure the pins to use for the clock and data
'can be any pin that can serve as an input
'Keydata is the label of the key translation table
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Config Keyboard = Pind.1 , Data = Pind.0 , Keydata = Keydata
'Dim some used variables
Dim S As String * 12
Dim B As Byte
Dim Prompt As String * 6
Cls
Lcd "klawiatura AT"
Wait 2
Prompt = ""
Cls
'Show the program is running
Lcd Prompt
Do
'The following code is remarked but show how to use the GetATKBD() function
' B = Getatkbd() 'get a byte and store it into byte variable
'When no real key is pressed the result is 0
'So test if the result was > 0
' If B > 0 Then
' Print B ; Chr(b)
' End If
'The purpose of this sample was how to use a PC AT keyboard
'The input that normally comes from the serial port is redirected to the
'external keyboard so you use it to type
B = Getatkbd()
If B > 0 Then
If B > 31 And B < 127 Then
Lcd Chr(b)
End If
If B = 44 Then
Cls
Lcd Prompt
End If
If B = 13 Then
Lowerline
Lcd Prompt
End If
If B = 8 Then
Shiftcursor Left
Lcd " "
Shiftcursor Left
End If
End If
Loop
End
'Since we do a redirection we call the routine from the redirection routine
'
Kbdinput:
'we come here when input is required from the COM port
'So we pass the key into R24 with the GetATkbd function
' We need some ASM code to save the registers used by the function
$asm
push r16 ; save used register
push r25
push r26
push r27
Kbdinput1:
rCall _getatkbd ; call the function
tst r24 ; check for zero
breq Kbdinput1 ; yes so try again
pop r27 ; we got a valid key so restore registers
pop r26
pop r25
pop r16
$end Asm
'just return
Return
'The tricky part is that you MUST include a normal call to the routine
'otherwise you get an error
'This is no clean solution and will be changed
B = Getatkbd()
'This is the key translation table
Keydata:
'normal keys lower case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &H5E , 0
Data 0 , 0 , 0 , 0 , 0 , 113 , 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32 , 118 , 102 , 116 , 114 , 53 , 0
Data 0 , 110 , 98 , 104 , 103 , 121 , 54 , 7 , 8 , 44 , 109 , 106 , 117 , 55 , 56 , 0
Data 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0 , 0 , 46 , 45 , 108 , 48 , 112 , 43 , 0
Data 0 , 0 , 0 , 0 , 0 , 92 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 92 , 0 , 0
Data 0 , 60 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0
'shifted keys UPPER case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 0 , 0 , 0 , 0 , 0 , 81 , 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 34 , 0
Data 0 , 67 , 88 , 68 , 69 , 0 , 35 , 0 , 0 , 32 , 86 , 70 , 84 , 82 , 37 , 0
Data 0 , 78 , 66 , 72 , 71 , 89 , 38 , 0 , 0 , 76 , 77 , 74 , 85 , 47 , 40 , 0
Data 0 , 59 , 75 , 73 , 79 , 61 , 41 , 0 , 0 , 58 , 95 , 76 , 48 , 80 , 63 , 0
Data 0 , 0 , 0 , 0 , 0 , 96 , 0 , 0 , 0 , 0 , 13 , 94 , 0 , 42 , 0 , 0
Data 0 , 62 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0
WYŚWIETLACZ 7-SEGMENTOWY
WYŚWIETLACZ 7-SEGMENTOWY
a → OA
b → OB
c → OC
d → OD
e → OE
f → OF
g → OG
h → OH
w1 → PC2
w2 → PC3
w3 → PC4
w4 → PC5
PB0 → IA
PB1 → IB
PB2 → IC
PB3 → ID
PB4 → IE
PB5 → IF
PD0 → IG
PD1 → IH
Obsługa wyświetlacza sprowadza się do manipulacji dwoma przyciskami.
S1 - powoduje zmianę „aktywnej” cyfry, tzn. tej, którą można inkrementować przyciskiem S2. jeśli aktywna jest ostatnia cyfra, to naciśnięcie tego przycisku
S2 - inkrementuje aktywną cyfrę. Aktywowanie kolejnej cyfry odbywa się przyciskiem S1.
$regfile = "m8def.dat"
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Config Portb = Output
Config Pinc.4 = Output
Config Pinc.5 = Output
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Timer0 = Timer , Prescale = 256
Cls
Lcd "7-segm"
Declare Sub Pobr_znaku(cyfra As Byte)
On Timer0 Mult_wysw
Dim A As Byte , B As Byte , C As Byte , D As Byte
Dim Time As Byte
Dim Nr_wysw As Byte
Dim Kr1 As Bit , Kr2 As Bit , Kr3 As Bit , Kr4 As Bit
Dim Licz_8ms As Byte
Dim Sek As Byte
Dim Wart As Byte
W1 Alias Portc.4
W2 Alias Portc.5
W3 Alias Portc.6
W4 Alias Portc.7
Time = 250 ' nie zmieniaj, bo 1sek nie zostanie dobrze odmierzona
' 8MHz/256/250/125
Enable Interrupts
Enable Timer0
Load Timer0 , Time
' początkowe wartości do wyświetlenia
' w formacie ABCD
A = 10
B = 10
C = 10
D = 0
Wait 1
Do
Incr D
If D = 10 Then
D = 0
Incr C
End If
If C > 10 Then
C = C - 10
End If
Waitms 200
Loop
End
Sub Pobr_znaku(cyfra As Byte)
If Cyfra < 10 Then
Portb = Lookup(cyfra , Kody7seg)
Else
Portb = 0
End If
End Sub
Mult_wysw:
Load Timer0 , Time
Set W1
Set W2
Set W3
Set W4
Select Case Nr_wysw
Case 0:
Call Pobr_znaku(a)
Portb.7 = Kr1
Reset W1
Case 1:
Call Pobr_znaku(b)
Portb.7 = Kr2
Reset W2
Case 2:
Call Pobr_znaku(c)
Portb.7 = Kr3
Reset W3
Case 3:
Call Pobr_znaku(d)
Portb.7 = Kr4
Reset W4
End Select
Incr Nr_wysw
If Nr_wysw = 4 Then
Nr_wysw = 0
End If
Incr Licz_8ms
If Licz_8ms = 125 Then
Licz_8ms = 0
Incr Sek
End If
Return
Kody7seg:
Data &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110
Data &B01101101 , &B01111101 , &B00000111 , &B01111111 , &B01101111
TABLETKA DALLAS (3C0000082989BB01)
TABLETKA DALLAS
1WIRE → PB0
DG → PC4
DR → PC5
Przyłożenie tabletki Dallas (używanej jako elementu identyfikacji użytkownika, w różnych systemach zabezpieczeń) do czytnika powoduje wyświetlenie jej numeru seryjnego oraz zmianę koloru świecenia diody LED z czerwonego na zielony.
$regfile = "m8def.dat"
$crystal = 8000000
'lcd
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
Config 1wire = Portb.0
Config Pinc.4 = Output
Config Pinc.5 = Output
Dim Flagagotowosci As Byte
Dim B As Byte
Dim C(8) As Byte
Reset Portc.4
Set Portc.5
Flagagotowosci = 1
Waitms 200
Cls
Lcd "przyloz tabletke"
Do
Err = 1
1wreset 'inicjalizacja magistrali 1-wire
If Err = 0 Then 'jezeli poprawna odpowiedz skocz do "Czytanie"
Exit Do
End If
Loop
Do
Flagagotowosci = 1
1wwrite &H33 'wyslij na magistrale 1-wire
For B = 1 To 8 'zadanie podania kodu tabletki
C(b) = 1wread() 'odczytaj kolejne bajty numeru tabletki
If C(b) <> 255 Then
If C(b) <> 0 Then
Flagagotowosci = 0
Set Portc.4
Reset Portc.5
End If
End If
Next B
If C(5) = 8 Then
Set Portc.4
Reset Portc.5
End If
If Flagagotowosci = 0 Then
Cls
Lcd "iButton number:"
Lowerline
For B = 8 To 1 Step -1
Lcd Hex(c(b)) 'zapisz w pamieci kolejne bajty pod ktore zapisujemy dane
Next B
Wait 2
End If
Wait 1
Loop
End
TERMOMETR CYFROWY 1-wire
'--------------------------------------------------------------
' CYFROWY REGULATOR TEMPERATURY
'--------------------------------------------------------------
$regfile "8535def.dat" 'deklarcja typu mikrokontrolera
'deklarcja typu mikrokontrolera
$crystal = 9216000 'deklaracja częstotliwości rezonatora
$baud = 9600 'deklaracja prędkości transmisji zlącza RS232
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2
Rem Deklaracja podlączenia wyświetlacza LCD do końcówek mikrokontrolera, tryb pracy 4-bitowej
Config Lcd = 20 * 2 'deklaracja typu LCD 20 znaków , 2 wiersze
'***************************************************************
Config 1wire = Portb.0
Declare Sub Odcz_temp
Dim Temperatura(2) As Byte
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
Do
Call Odcz_temp
CLS
If Temperatura(2) = 0 Then
Lcd "Temp: " ; Temperatura(1) ; Chr(0) ; "C"
Else
Lcd "Temp: -" ; Temperatura(1) ; Chr(0) ; "C"
End If
Loop
End
Sub Odcz_temp
1wreset
1wwrite &HCC
1wwrite &H44
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE
Temperatura(1) = 1wread(2)
1wreset
If Err = 1 Then
Cls
Lcd "Brak ukladu DS1820.."
Do
Loop
End If
If Temperatura(2) > 0 Then
Temperatura(1) = 256 - Temperatura(1)
End If
Temperatura(1) = Temperatura(1) / 2
End Sub