W tym artykule zajmę się opisywaniem podstawowych dyrektyw języka BASCOM bez których program nie mógł by działać. Wszystkie kody źródłowe zamieszczone w tej serii artykułów są kompatybilne z mikrokontrolerem Attiny2313 lub Atmega88 (ewentualny zamiennik to Atmega8A). Pierwsze ćwiczenia zostaną zrealizowane na Attiny 2313, natomiast kolejne (już bardziej zaawansowane) na Atmedze88. Najprawdopodobniej ukażę się także prezentacja płytki testowej stworzonej specjalnie na potrzeby tego cyklu artykułów. Będzie to istotne kiedy przejdziemy do ćwiczeń praktycznych.
Pierwszą z wcześniej wspomnianych dyrektyw jest polecenie config służące do ustalenia które bity danych portów mają zostać wejściami a które wyjściami. Polecenie Input oznacza wejście ,a Output wyjście. Wejście jak sama nazwa wskazuje stanie się nogą procesora odbierającą informacje (będą tam więc podłączone np. przyciski lub czujniki) , natomiast wyjścia będą wysyłać dane (podłączymy tam np. diody LED lub też tranzystory sterujące - np. silnikami itp.) Przykład takiej konfiguracji to:
Config Pind.0 = Input
Config Pind.1 = Input
Config Pind.2 = Input
Config Pind.3 = Input
Config Pind.4 = Input
Config Pind.5 = Input
Config Pind.6 = Output
Config Pinb.0 = Input
Config Pinb.1 = Input
Config Pinb.2 = Input
Config Pinb.3 = Input
Config Pinb.4 = Output
Config Pinb.5 = Output
Config Pinb.6 = Output
Config Pinb.7 = Output
Z wyżej przedstawionego fragmentu programu wynika ,że nóżki o numerach od 0 do 5 portu d staną się wejściami. Jedynie nóżka 6 portu d zostanie wejściem. W porcie b bity od 0 do 3 są wejściami, natomiast od 4 do 7 wyjściami. Zwróć uwagę, że mikrokontroler Attiny2313 posiada 7 bitów portu d oraz 8 bitów portu b. Taka konfiguracja zajmuje bardzo dużo miejsca w programie (w pamięci FLASH zajmie tyle samo ile niżej przedstawione rozwiązania ,ale chodziło mi o to ,że zmniejsza czytelność zapisu - lepiej zrobić to krócej) Istnieje więc możliwość skonfigurowania całego portu za jednym razem.
Config
Portd = Input
Config
Portb = Output
Takie rozwiązanie wygląda już znacznie bardziej
elegancko ,jednak nie daje nam możliwości niezależnego kontrolowania
poszczególnych bitów. Możemy jedynie zdecydować ,aby wszystkie nóżki
mikrokontrolera należące do danego portu zostały wyjściami bądź wejściami. W wyżej przedstawionej sytuacji cały
port d przeznaczyłem jako wejście a port b jako wyjście.
Istnieje jednak sposób na niezależne konfigurowanie poszczególnych bitów a przy tym zachowanie krótkiego zapisu, który wykorzystuje system zero-jedynkowy. Cyfra 0 oznacza tu wejście natomiast wyjście to cyfra 1. Polecenie to wygląda w następujący sposób:
Istnieje jednak sposób na niezależne konfigurowanie poszczególnych bitów a przy tym zachowanie krótkiego zapisu, który wykorzystuje system zero-jedynkowy. Cyfra 0 oznacza tu wejście natomiast wyjście to cyfra 1. Polecenie to wygląda w następujący sposób:
Config Portd = &B1000000
Config Portb = &B11110000
Powyższy
zapis oznacza to samo co pierwszy a przy tym jest o wiele krótszy. Bit nr 0
(najmłodszy) to ten ,który został umieszczony jako pierwszy z prawej strony.
Kolejne cyfry oznaczają kolejne piny
danego portu. Znaki &B uprzedzają
kompilator ,że liczba która za nimi stoi zapisana jest w systemie binarnym.
Istnieje bowiem możliwość jeszcze krótszego zapisu z wykorzystaniem systemu
dziesiętnego. Po prostu zamieniamy system zapisu z zero-jedynkowego na
dziesiętny i usuwamy znaki &B.
Config
Portd = 63
Config
Portd = 15
To wszystkie z możliwości konfiguracji wejść i wyjść w
języku BASCOM. Z których będziesz korzystać musisz zdecydować sam. Ja używam
przedostatniego sposobu ze względu na dość wysoką czytelność przy krótkim
zapisie. Sposób ten jest preferowany nie tylko przeze mnie ale i zapewne przez większość ludzi zajmujących się pisaniem takich programów.
Poza konfiguracją portów na początku pisania programu należy
zdecydować także jaki stan spoczynkowy będą posiadać nóżki naszego
mikroprocesora. Są to stany wysokie(1) lub niskie(0) które przybiorą bity wyjść
i wejść zaraz po uruchomieniu programu. Jeśli dana noga procesora przyjmie stan niski (0) oznacza to ,że posiądzie potencjał masy - a więc jeśli będzie do niej podłączony przewód do plusa to popłynie prąd (w przeciwnym razie nie). I analogicznie w drugim wypadku. Jeśli dana noga procesora przyjmie stan wysoki (1) oznacza to ,że stanie się jakby "plusem" - a więc jeśli będzie do niej podłączony przewód do masy to popłynie prąd (w przeciwnym razie nie).Podczas jego działania mogą one zmieniać swoje wartości (wszystko zależy od programu).Można to zrobić w
dwojaki sposób.
Portd.0
= 0
Portd.1
= 0
Portd.2
= 0
Portd.3
= 0
Portd.4
= 0
Portd.5
= 0
Portd.6
= 0
Portb.0
= 1
Portb.1
= 1
Portb.2
= 1
Portb.3
= 1
Portb.4
= 1
Portb.5
= 0
Portb.6
= 0
Portb.7
= 0
Albo krótszy zapis, który ja preferuję:
Portd
= &B0000000
Portb
= &B0001111
Podobnie jak przy konfiguracji możemy to zapisać w jeszcze
krótszy sposób z udziałem systemu dziesiętnego. Obowiązują tu takie same zasady
tzn. usuwamy znaki &B.
Portd
= 0
Portb
= 15
Kolejną bardzo ważna dyrektywą jest polecenie Do…Loop . Jest to nieskończona pętla.
Polecenia zawarte pomiędzy członem Do a
Loop są wykonywane w kółko.
Przyjrzyjmy się poniższej części kodu:
Do
Polecenie
1
Polecenie
2
Polecenie
3
Loop
Taki zapis oznacza że procesor najpierw wykona polecenie
pierwsze ,potem drugie , następnie trzecie i wróci na początek pętli by znowu
wykonywać polecenie pierwsze itd. Gdybyśmy nie zastosowali pętli Do…Loop wówczas polecenia zostały by
wykonane a następnie procesor przestałby pracować. Należało by go zresetować
,aby ponownie wykonał program. W późniejszych artykułach ,kiedy zajmę się
praktycznym wykorzystaniem poznanej wiedzy dobrze zrozumiesz sens tej dyrektywy.
Ostatnie z ważnych poleceń jest dyrektywa End. Kończy ona po prostu program.
Należy umieścić ją na końcu kodu źródłowego. Chodź nie zawsze. Bowiem jeśli wykorzystujemy przerwania lub podprogramy to one znajdują się na końcu. Lepiej jest więc stwierdzić ,że umieszczamy polecenie End zawsze zaraz za poleceniem Loop.
Przy pisaniu programu niezwykle pomocne, choć nie niezbędne
są komentarze. Pozwalają one w „ludzki” sposób opatrzyć dane polecenia programu
wyjaśnieniami co miałeś na myśli. Aby napisać komentarz należy użyć znaku „ ’ ” lub polecenia Rem. W komentarzach możemy napisać co chcemy i nie wpływa to na
działanie programu. Po prostu ułatwiają one późniejszą analizę programu.
Na zakończenie chciałbym przedstawić najprostszy (w zasadzie nie jest najprostszy ,ale możemy tak przyjąć ponieważ będzie stanowił dla nas niejako bazę do tworzenia kolejnych programów) możliwy
program. Mikrokontroler zaprogramowany w ten sposób nie będzie jednak wykonywać żadnych zadań.
Config
Portd = &B1000000 ‘konfiguuruję
portd
Portd
= &B0000000 ‘ustawiam stany spoczynkowe
Config
Portb = &B11110000 ‘konfiguruję portb
Portb
= &B0001111 ‘ustawiam stany spoczynkowe
Do Rem początek pętli
Loop ‘koniec pętli
End ‘koniec programu
W zasadzie polecenie Do…Loop
jest tu niepotrzebne, ale chciałem
wykorzystać wszystkie dyrektywy ,które poznaliśmy w tym artykule. Myślę ,że nie ma sensu wgrywać go do procesora ,ponieważ i tak nie zauważymy różnicy w jego działaniu.
Na koniec warto wspomnieć jeszcze o dwóch poleceniach kompilatora odpowiedzialnych za ustawienie zewnętrznego taktowania i typu procesora. Są to
$regfile
(określa model mikrokontrolera) i $crystal
(określa częstotliwość kwarcu wyrażoną w hz). Polecenia te wpisujemy na początku programu np. : $regfile =
"2313def.dat"
$crystal =
4000000
Powyższy zapis oznacza ,że pracujemy na uC - attiny2313 z taktowaniem 4Mhz = 4000000hz. Należy również pamiętać, że do nazwy procesora dodajemy rozszerzenie .dat . Ja jednak nie umieszczam tych informacji w programie. Zamiast wpisywać te polecenia w tekst programu wygodniej dokonać koniecznych zmian w zakładce "Options" (ikona zębatki na górnym pasku menu). Mamy tam możliwość wskazania procesora ,który używamy oraz taktowania współpracującego z nim kwarcu (bądź też oscylatora wewnętrznego czy np. generatora częstotliwości)
Options - Compiler - Chip - w oknie Chip wybieramy 2313.dat
Jeśli w programie wpiszemy sprzeczne dane względem tych zawartych w ustawieniach to dane w ustawieniach zostaną zignorowane.Należy jednak zaznaczyć, że polecenie nie ingeruje w fusebity mikrokontrolera i nie spowoduje przestawienia kwarcu (należy to zrobić za pomocą AVR studio tak jak pokazałem w ostatnim artykule). To polecenie jedynie informuje BASCOMA z jakim kwarcem będzie współpracował. Ma to istotne znacznie zwłaszcza przy obsłudze poleceń takich jak wait, waitms , waitus, lcd itp.Dokładnie przyczynę tego zjawiska omówię w kolejnych częściach artykułu.
Świetny poradnik. A mógłbyś napisać kolejną część tego artykułu używając dyrektyw szesnastkowych ? bo nie ma za dużo poradników o bajtach...
OdpowiedzUsuń