środa, 6 czerwca 2012

Podstawowe dyrektywy języka BASCOM.



      
     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:


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 
                               Options - Compiler - Communication - w oknie Frequency wybieramy 4000000

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.

1 komentarz:

  1. Ś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ń