[PIC programování] – 5. díl
Zdravím u pátého dílu v sérii o programování mikrokontrolérů PIC!
V tomto díle si ukážeme, jak používat “vlastní proměnné” a řekneme si, jaké zrady přitom mohou nastat. Také se podíváme na definici maker.
Proměnné nebudou nic jiného, než námi pojmenované registry. Tak, jako jsme měli například registry TRISx, PORTx, LATx a jiné…
Deklarace proměnné
Vytvoření proměnné nazýváme deklarace. V jazycích vyšších úrovní (C, C++, Java, C# apod.) se při deklaraci ještě určuje datový typ (např.: byte – celé číslo v rozsahu 28 – nebo char – znak). V assembleru však pracujeme pouze s celými čísly ve velikosti od 0 do 255, tedy vlastně byte). Způsobů, jak deklarovat proměnnou je hned několik.
Prvním způsobem je pomocí preprocesorové instrukce #define. Tuto instrukci nepoužíváme pouze pro deklaraci proměnných, ale definujeme i konstanty. Funguje to tak, že kdybychom například vytvořili konstantu X a přiřadili jí hodnotu Y, tak si kompilátor při kompilaci všechny X nahradí hodnotou Y. Je to podobné, jako když v nějakém textovém editoru dáte nahradit textový řetězec.
Pojďme si to ukázat na příkladu:
Už zde nebudu uvádět nastavení konfiguračních bitů, vnitřního oscilátoru apod. V případě nejasností vás odkazuji na druhý díl série PIC programování, uvítám i dotazy v komentářích.
1 |
#define PROMENNA 0x20 |
Tímto řádkem jsem vytvořil konstantu, která zastupuje adresu 0x20 v paměti RAM. (Opět, pokud máte nejasnosti, odkazuji na druhý díl série PIC programování).
Nyní s ní mohu zacházet stejně jako například s registrem TRISC:
1 2 3 |
movlw b'00000000' banksel PROMENNA movwf PROMENNA |
Nebo bych mohl její obsah přesunout přímo do registru TRISC. K tomu zde použiju novou instrukci:
- movfw [MOVe F to W] – přesune obsah registru F do registru W
1 2 3 |
movfw PROMENNA banksel TRISC movwf TRISC |
Samozřejmě je to naprosto neužitečný a zbytečný kód, ale pro demonstrační účely nám to bohatě poslouží. Tímto krkolomným způsobem jsme si nastavili celý port C jako výstupy.
Celý kód tohoto způsobu deklarace proměnné (ve skutečnosti konstanty) vypadá takto:
1 2 3 4 5 6 7 8 9 10 11 12 |
... #define PROMENNA 0x20 movlw b'00000000' banksel PROMENNA movwf PROMENNA movfw PROMENNA banksel TRISC movwf TRISC end |
Proč stále dokola zmiňuji, že je to vlastně konstanta? Podívejte se, co bych také mohl udělat:
1 2 3 4 5 6 7 |
#define PROMENNA 0x20 movlw PROMENNA banksel TRISC movwf TRISC end |
Teď jsem naší “proměnnou” použil jako konstantu a registru 0x20 jsem se vůbec nedotkl. Pouze jsem vzal hodnotu 0x20 (= b’100000′ – viz první díl série PIC programování) a přiřadil jsem ji do registru TRISC. Tahle věc je trochu zrádná, proto si vždycky při programování raději ujasněte, co děláte – jestli konstantu nebo proměnnou.
Pojďme si ukázat další způsob deklarace a tím je příkaz EQU. EQU se chová velmi podobně jako #define. Je zde ale podstatný rozdíl. Pojďme si ale nejprve ukázat kód:
1 2 3 4 5 6 7 |
PROMENNA EQU 0x20 movlw b'00000000' banksel PROMENNA movwf PROMENNA end |
Asi si říkáte, jaký je tedy rozdíl mezi #define a equ? Pomocí equ přiřazujeme pouze číselné hodnoty, kdežto u #define můžeme přiřadit cokoliv. Podívejte se, jak se dá udělat takové malé makro:
1 2 3 4 5 6 7 8 9 10 |
PROMENNA EQU 0x20 #define MAKRO1 movlw b'00000000' #define MAKRO2 banksel PROMENNA #define MAKRO3 movwf PROMENNA MAKRO1 MAKRO2 MAKRO3 end |
Co se stane? Kompilátor nahradí konstanty MAKRO<1-3> jejich hodnotami a proces vykoná instrukce. I takto si můžeme zjednodušit práci, pokud třeba nějaký dlouhý příkaz vykonáváme často. Pojďme si ještě ukázat alternativu pro EQU a tím je CBLOCK:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
CBLOCK 0x20 PROMENNA1 DALSIPROMENNA ADALSI JESTEJEDNA ENDC movlw b'00000000' banksel PROMENNA1 movwf PROMENNA1 movwf DALSIPROMENNA movwf ADALSI movwf JESTEJEDNA end |
CBLOCK slouží pro deklaraci více proměnných. Samozřejmě s ním lze deklarovat i pouze jednu proměnnou. Funguje to tak, že příkazem CBLOCK zahájíte deklarování proměnných od určité adresy (v našem případě 0x20). PROMENNA1 tedy bude mít hodnotu 0x20, DALSIPROMENNA hodnotu 0x21 atd.Celý blok se ukončuje příkazem ENDC. V ukázce výše jsem při přesunu hodnoty do patřičných registrů neměnil banky, protože vím, že všechny proměnné jsou ve stejné bance.
A to by bylo k deklaracím vše. A protože jsem se ještě nerozhodl, na jaké téma bude příští díl, budete mít alespoň překvapení! Do té doby se mějte. Pokud by byly nějaké nejasnosti, budu rád za zpětnou vazbu v komentářích.