BASCOM 8051 i AVR
BASCOM to program, który tłumaczy (kompiluje) napisany przez człowieka program na język zrozumiały dla procesora. Programuje się dosyć łatwo, ponadto BASCOM sam wykrywa błędy i mówi, co jest źle. Jak już napiszesz jakiś program, przed przetestowaniem należy go zapisać na dysku. Następnie wciskasz F7 i on szuka błędów. Po stwierdzeniu braku błędów, możesz wcisnąć F2. Przeniesie cię do okna symulatora. Zanim wciśniesz "play" warto zwrócić uwagę na ikonę przedstawiającą dłoń nad kartką papieru. Jeśli nie jest aktywna to program podczas symulacji nie będzie pokazywał zmian na portach (nieładnie mówiąc - lampkach), co jest dość ważne. Po prostu warto, aby ikonka była zawsze aktywna. Ostatnie, co potrzebujesz w oknie symulatora to ikona z napisem "LCD". Wewnątrz znajdziesz wyświetlacz, oraz sygnalizatory portów. I to by było na tyle, jeśli chodzi o orientację w programie. Warto zauważyć, że będziesz używał dwóch wersji programu; 8051 i AVR. Warto mieć je ściągnąć.
Ściągnij BASCOM 8051
Ściągnij BASCOM AVR
Deklaracja zmiennych
Dość ważna rzecz. Aby zaoszczędzić miejsce stosuje się wiele rodzajów zmiennych. Powiedzmy, że chcesz wpisać do pamięci wartość "1". Możesz ją zapisać jako zmienna "bit" i stracić mało pamięci, albo jako "byte" w postaci "00000001" i stracić osiem razy więcej. Oczywiście nie należy tak robić. Poniżej wypisałem wszystkie zmienne, przedziały w których znajdują się zbiory ich wartości, oraz zajętość pamięci.
Dim x as bit Dim x as byte Dim x as word Dim x as integer Dim x as long Dim x as single Dim x as string * y
x ∈ {0, 1} x ∈ N: <0, 255> x ∈ N: <0, 65535> x ∈ C: <-65535, 65535> x ∈ C: <-2147483647, 2147483647> x ∈ R: <-2147483647, 2147483647> x ∈ alfanumeryczne
1 bit 2 bajty 2 bajty 2 bajty 4 bajty 4 bajty y bajtów
Bit, byte i word mogą przedstawiać liczby nieujemne całkowite, integer, long i single mogą być ujemne, ale tylko single może być ułamkiem. Ułamki polecam wpisywać w postaci dzielenia przez dziesięć, sto, tysiąc i tak dalej. Zmienna string może zawierać tekst. Przy deklaracji zamiast "y" należy wpisać liczbę o jeden większą od ilości znaków w zmiennej. Dla "Technical Site" będzie to piętnaście.
Komendy
Lista komend. Nie będę ich opisywał szczegółowo, ponieważ łatwo załapać o co chodzi, oglądając przykłady programów poniżej.
$sim Dim Q As Byte, V As Byte Q = 5 V = &H0F X = &B11010101 Incr Q Decr Q Shift Q, Left Shift V, Right P1 = Q Portb = Q Print Q Print "tekst" Print Q ; "kota" ; V ; "ala" Do [...] Loop For Q=0 To 100 [...] Next If Q = 60 Then [...] End if If V = X Then [...] Else [...] End if Declare sub nazwa Sub [nazwa] [...] End sub Config Lcd = 16*1 Cursor off Cls Lcd Q Lcd ; "kot" ; V ; "ali" ; Q ; Locate 1,7 Lcd Q nazwa: Data: 11, &H1A, &B110110001 Q = Lookup(v , nazwa) Home End
Symulacja (zawsze na początku kodu) Deklaracja zmiennych. Zmienna Q przyjmuje wartość pięć. V wartość heksadecymalną 0F. X binarną 11010101. Zwiększa zmienną Q o jeden. Zmniejsza Q o jeden. Przesuwa bity zmiennej Q w lewo. To samo ale w prawo. [8051] Wysyła wartość Q na port 1. [AVR] To samo. Wypisuje wartość zmiennej Q na ekran. Wypisuje tekst podany w cudzysłowach. Wypisuje Q, potem tekst, V i znowu tekst w jednej linii. Początek nieskończonej pętli. Polecenia do wykonania. Koniec pętli. Dla Q równego 0 do 100 wykonaj pętlę. Wpisane tu polecenia wykonają się UWAGA! 101 razy. Koniec pętli. Jeżeli Q jest równe 60 wykonaj. Polecenia. Koniec. Jeżeli V jest równe Q wykonaj Polecenia. Jeżeli V nie było równe Q to wykonaj. Polecenia. Koniec. Deklaracja podprogramu "nazwa". Początek podprogramu "nazwa" Polecenia. Koniec podprogramu. Ustaw wyświetlacz 16x1. Wyłącz kursor. Wyczyść LCD. Wyświetl zmienną Q na wyświetlaczu. Wyświetla tekst "kot" potem V, potem "ala" i Q w jednej linii. Lokalizuje pozycję 7 w 1 wierszu. Wyświetla Q rozpoczynając od 1,7. Tablica o nazwie "nazwa". Elementy tablicy. Podstaw pod zmienną Q element numer v z tablicy "nazwa". Powrót na początek programu. Koniec programu.
Powyższy zbiór pochodzi z wszystkich lekcji, w kolejności mniej-więcej chronologicznej.
Zajęcia I
Pierwszym programem jaki będziesz pisać, będzie mniej więcej polegał na uzyskaniu efektu lampek choinkowych. Symulacyjny "procesor" BASCOM ma osiem specjalnych wyjść, nazywanych portem. Chodzi o to, aby na zmianę "świeciły się" pierwsze cztery wyjścia, a następnie cztery ostatnie i od nowa. Wystarczy na zmianę wpuszczać tam jedynki, a następnie zera. P=11110000 (240), po chwili P=00001111 (15). Problem polega na tym, że procesor działa bardzo szybko, i tych zmian może dokonywać tysiące razy na sekundę (albo i więcej, zależy od kompa). Dlatego należy użyć [pod]programu opóźniającego.
$sim Dim P As Byte, Q As Byte Declare Sub Czekaj Do Q = &H0F P1 = Q Czekaj Q = &HF0 P1 = Q Czekaj Loop Sub Czekaj For P = 0 To 250 Next End Sub
Symulacja Deklaracja zmiennych P i Q jako bajt Deklaracja podprogramu o nazwie "Czekaj" Start pętli Zmienna Q przyjmuje wartość hex 0F czyli 15 Wysłanie wartości Q na wyjścia P1 Podprogram "Czekaj" Q przyjmuje wartość F0 czyli 11110000 Wysłanie wartości Q na wyjścia P1 Podprogram "Czekaj" Zakończenie pętli Ustalenie podprogramu "Czekaj" Pętla Koniec pętli Koniec podprogramu
W podprogramie "czekaj" wykonuje się 251 razy (tak, tak, od 0 do 250 będzie 251 i to trzeba wiedzieć na kolokwium) pętla, która nic nie robi, opóźniając czas przeskoku stanów na wyjściach pierwszego portu. Im większą liczbę tam podasz, tym dłużej "lampki" będą świecić. W pracowni wystarczy 100, lub 300, ale w domku raczej spotyka się lepsze komputery i należy podać więcej. :)
Jako zadanie domowe, trzeba wykonać podobny program, ale mają "świecić się" wyjścia nieparzyste, a następnie parzyste i od nowa. P=10101010 (170), po chwili P=01010101 (85). Oczywiście wystarczy podmienić wartości zmiennych z poprzedniego zadania i już będzie śmigać. Jednak wymagane jest użycie funkcji "Shift" (przesunięcie). Działa w dwa sposoby; albo w lewo, albo w prawo. Polega to na tym, że przesuwa bity danej wartości w wskazany kierunek, a pierwszy i ostatni bit zamieniają się miejscami. Kiedy P=10101010 "shiftniemy" w prawo, otrzymamy P=01010101. Nie jestem pewien, ale chyba funkcja "shift" jest tańsza pamięciowo, niż nadpisanie zmiennej.
W animacji pominięto "czekaje". Przypomnij sobie teraz rejestry. Czuć podobieństwo? Twoje bity trzymane są w rejestrach procesora, a w razie potrzeby przesuwa się je w lewo lub w prawo (na UTK tylko w jednym kierunku). Ale zobaczmy jak to będzie wyglądało w pełnym programie.
$sim Dim Q As Byte, P As Byte Q = &B01010101 Declare Sub Czekaj Do P1 = Q Czekaj Shift Q , Right P1 = Q Czekaj Shift Q , Right Loop Sub Czekaj For P = 0 To 100 Next End Sub
Symulacja Deklaracja zmiennych Q i P jako bajt Zmienna Q przyjmuje wartość 01010101 Deklaracja podprogramu o nazwie "Czekaj" Start pętli Wysłanie wartości Q na wyjścia P1 Podprogram "Czekaj" Przesunięcie bitów zmiennej Q w prawo Wysłanie wartości Q na wyjścia P1 Podprogram "Czekaj" Przesunięcie bitów zmiennej Q w prawo Zakończenie pętli Ustalenie podprogramu "Czekaj" Pętla Koniec pętli Koniec podprogramu
Sporo jak na jedne zajęcia, nie?
Zajęcia II
Na drugich zajęciach gwoździem programu będzie komenda "print", oraz wyświetlacz LCD. Pierwsze zadanie polega na napisaniu programu pseudo-zegarka, czyli czegoś, co bardzo szybko będzie liczyć w górę, podając sekundy, minuty i godziny. Pierw trzeba się zastanowić, jak działa zegarek-stoper. Cały czas zwiększa liczbę sekund o jeden. Jeśli zmienna reprezentująca sekundy, będzie równa 60, to zwiększy się zmienna minut, a sekundowa spadnie do zera i od nowa będzie się zwiększać. Jeśli zaś minuty osiągną 60, to godziny rosną, a minuty spadają do zera. Teraz wytłumacz to procesorowi. ;)
$sim Dim S As Byte , M As Byte , G As Byte , C As Byte Declare Sub Czekaj Do Print S ; " sek " ; M ; " min " ; G ; " godz " Incr S If S = 60 Then Incr M S = 0 End If If M = 60 Then Incr G M = 0 End If If G = 24 Then G = 0 End If Czekaj Loop Sub Czekaj For C = 0 To 100 Next End Sub
Symulacja Ustalanie zmiennych Deklaracja podprogramu Początek pętli Wyświetlenie stanu stopera (to w jednej linii!) Zwiększenie sekund Jeśli sekundy dotarły do 60, to: Zwiększ minuty Sekundy zmniejsz do zera Koniec warunkowania Jeśli minuty dotarły do 60, to: Zwiększ godziny Zeruj minuty Koniec warunkowania Jeżeli godziny dotarły do 24, to: Zeruj godziny Koniec warunkowania Opóźnienie Koniec pętli Podprogram Czekaj Pętla powtórzy się 101 razy Koniec pętli Koniec podprogramu
Komenda "print" nazywa się "print" (drukuj), ponieważ raz wyświetlonej (wydrukowanej) treści nie zmienisz. Testując program widziałeś niekończący się ciąg linijek. Trochę to mało estetyczne. Dlatego jest wyświetlacz LCD. Za jego pomocą można przedstawić aktualny stan stopera, bardzo podobnie jak na cyfrowych zegarkach. Użyję wyświetlacza 16*1. Najpierw trzeba rozplanować, co i gdzie będzie się wyświetlać.
Pierwsze cztery komórki opuszczam, żeby było ładnie. ;) W komórce siódmej i dziesiątej są dwukropki i nigdy się nie zmieniają. Reszta jest oczywista. Tak naprawdę, największym problemem w tym zegarku jest sposób wyświetlania liczb poniżej dziesięciu. Jeśli każesz mu wyrzucić "24" na pierwszej komórce, to on wyświetli w pierwszej "2", a w sąsiedniej "4". Jeśli zaś ma wyświetlić "5", to tak zrobi. My jednak chcielibyśmy, aby liczby jednocyfrowe wyświetlał jako "01, 02, 03..." i tak dalej. W tym celu, należy użyć warunkowania. Jeżeli liczba będzie większa od "10", to niech wyświetli w komórce numer jeden. Jeśli mniejsza, niech wyświetli w komórce numer dwa, a w pierwszej zero.
$sim Config Lcd = 16 * 1 Cursor Off Cls Dim S As Byte , M As Byte , G As Byte , C As Byte Declare Sub Czekaj Locate 1 , 7 Lcd ":" Locate 1 , 10 Lcd ":" Do If S = 60 Then Incr M S = 0 End If If M = 60 Then Incr G M = 0 End If If G = 24 Then G = 0 End If If S < 10 Then Locate 1 , 11 Lcd 0 Locate 1 , 12 Lcd S Else Locate 1 , 11 Lcd S End If If M < 10 Then Locate 1 , 8 Lcd 0 Locate 1 , 9 Lcd M Else Locate 1 , 8 Lcd M End If If G < 10 Then Locate 1 , 5 Lcd 0 Locate 1 , 6 Lcd G Else Locate 1 , 5 Lcd G End If Incr S Czekaj Loop Sub Czekaj For C = 0 To 250 Next End Sub
Symulacja Ustawienie LCD Wyłączenie kursora Wyczyszczenie LCD Ustawienie zmiennych Deklaracja podprogramu Komórka siódma "na warsztat" Wyświetl w tej komórce dwukropek Komórka dziesiąta "na warsztat" Wyświetl w tej komórce dwukropek Pętla nieskończona Jeżeli sekundy osiągneły "60", to: Zwiększ minuty Zeruj sekundy Koniec warunkowania Jeżeli minuty osiągneły "60", to: Zwiększ godziny Zeruj minuty Koniec warunkowania Jeżeli godziny osiągneły "24", to: Zeruj godziny Koniec warunkowania Jeżeli sekundy są mniejsze od "10", to: Komórka jedenasta "na warsztat" Wyświetl w tej komórce zero Komórka dwunasta "na warsztat" Wyświetl w tej komórce wartość sekund W przeciwnym wypadku: Komórka jedenasta "na warsztat" Wyświetl w tej komórce wartość sekund Koniec warunkowania Jeżeli minuty są mniejsze od "10", to: Komórka ósma "na warsztat" Wyświetl w tej komórce zero Komórka dziewiąta "na warsztat" Wyświetl w tej komórce wartość minut W przeciwnym wypadku: Komórka ósma "na warsztat" Wyświetl w tej komórce wartość minut Koniec warunkowania Jeżeli godziny są mniejsze od "10", to: Komórka piąta "na warsztat" Wyświetl w tej komórce zero Komórka szósta "na warsztat" Wyświetl w tej komórce wartość godzin W przeciwnym wypadku: Komórka piąta "na warsztat" Wyświetl w tej komórce wartość godzin Koniec warunkowania Zwiększ sekundy o jeden Opóźnienie Koniec pętli Podprogram opóźniający Pętla powtórzy się 251 razy Koniec pętli Koniec podprogramu
Pierw program na stałe wyrzuca na pozycje siódmą i dziesiątą dwukropki. Następnie wchodzi do pętli, która na początku sprawdza, czy zmienne nie przekroczyły swojego progu. Jeśli tak, to zwiększa wartość wyższej jednostki i się zeruje. Kolejne trzy funkcje warunkują, czy zmienna jest mniejsza od dziesięciu. Jeśli tak, to przed wartością zmiennej wrzuca zero. Jeśli nie - zamiast zera wrzuca właśnie zmienną. Dzięki temu zegarek lepiej wygląda. Dopiero na samym końcu pętli znajduje się komenda przyrostu sekund oraz dobrze znane "czekaj".
Zajęcia III
Zadanie podobne, jak na pierwszych zajęciach. Chcę na porcie otrzymać efekt piłeczek, ale przy pisaniu programu muszę skorzystać z tablicy. Tablica, to taka duża zmienna, zawierająca zmienne. Przykładowo, tablica o nazwie "Klasa 1Ic", zawiera 32 wartości - uczniów. Każdy uczeń ma numer, i po tymże numerze można go wywołać z tablicy. Dlaczego jest to lepsze od rozwiązania z pierwszych zajęć? Ponieważ tam zmienne są wpisane do procesora, i bez wgrywania programu od nowa ich nie zmienisz, w przeciwieństwie do tablicy.
$sim Dim A As Byte , B As Byte , C As Word Declare Sub Moment Do For A = 0 To 5 B = Lookup(a , Tablica) Portb = B Moment Next Loop Sub Moment For C = 0 To 150 Next End Sub Tablica: Data 24 , 36 , 66 , 129 , 66 , 36
Symulacja Deklaracja zmiennych Deklaracja podprogramu Pętla Powtóż 6 razy, zwiększając zmienną "a" Zmienna B = element "a" z "Tablica" Wysyła wartość zmiennej B na port Opóźnienie Powtóż Koniec pętli Podprogram opóźniający Pętla powtórzy się 151 razy Koniec pętli Koniec podprogramu Tablica o nazwie "Tablica": Elementy (w jednej linii!)
Drugim i ostatnim zadaniem było to samo, ale na sześciu portach na raz.
$sim Dim X As Byte , Y As Byte , K As Byte Declare Sub Moment! Do For X = 0 To 5 K = Lookup(x , Tablica0) P0 = K P1 = K P2 = K P3 = K P4 = K P5 = K Moment! Next Loop Sub Moment! For Y = 0 To 150 Next End Sub Tablica0: Data 24 , 36 , 66 , 129 , 66 , 36
Tym razem kod bez komentarzy. Teraz nie są Ci już potrzebne. ;)