AVR Bit Magic: Rozdiel medzi revíziami
Z SensorWiki
d |
|||
Riadok 1: | Riadok 1: | ||
− | V assembleri existuje pre manipuláciu s bitmi dostatok inštrukcií. V prvom cvičení sme napríklad na test stlačenia | + | V assembleri existuje pre manipuláciu s bitmi dostatok inštrukcií. To v C-čku štandardne nie je, preto sa musíme naučiť s bitmi manipulovať. |
+ | |||
+ | |||
+ | == Vstupy == | ||
+ | |||
+ | V prvom cvičení sme napríklad na test stlačenia | ||
tlačidla mohli použiť inštrukciu | tlačidla mohli použiť inštrukciu | ||
sbis PIND,3 ; sbis = Skip if Bit Is Set, preskoc ak je PIND.3 nastaveny (=1) | sbis PIND,3 ; sbis = Skip if Bit Is Set, preskoc ak je PIND.3 nastaveny (=1) | ||
V jazyku C ale typ bit neexistuje (hoci niektoré kompilátory takýto typ zaviedli), preto môžeme pracovať len s bajtmi, a musíme si nejako vypomôcť. Pri rozumnom zápise však kompilátor rozpozná, že chceme pracovať s bitom a preloží našu konštrukciu správne. | V jazyku C ale typ bit neexistuje (hoci niektoré kompilátory takýto typ zaviedli), preto môžeme pracovať len s bajtmi, a musíme si nejako vypomôcť. Pri rozumnom zápise však kompilátor rozpozná, že chceme pracovať s bitom a preloží našu konštrukciu správne. | ||
+ | |||
Ak chceme testovať stav jedného bitu v bajte, musíme ostatné zakryť, zamaskovať. To sa robí tzv. maskou: | Ak chceme testovať stav jedného bitu v bajte, musíme ostatné zakryť, zamaskovať. To sa robí tzv. maskou: | ||
Riadok 20: | Riadok 26: | ||
#define BIT(x) (0x01<<(x)) | #define BIT(x) (0x01<<(x)) | ||
− | Podobne sú zadefinované aj tieto dve užitočné makrá | + | Podobne sú zadefinované aj tieto dve užitočné makrá (pozri <avr/sfr_defs.h>) |
− | + | #define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit)) | |
+ | #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit))) | ||
+ | Takže napokon konštrukcia môže vyzerať takto: | ||
+ | #define Switch 3 | ||
+ | if ( bit_is_set(PIND, Switch) ) // test, ci je tlacitko stlacene... | ||
+ | |||
+ | |||
+ | |||
+ | == Výstupy == | ||
+ | Obdobný problém nastáva, ak chceme nastaviť jeden jediný bit v celom osembitovom registri, či porte. Musíme dávať pozor, aby sme | ||
+ | nezmenili stav tých ostatných bitov, ktoré meniť nechceme. | ||
+ | Budeme rozlišovať, či chceme nastaviť bit do jednotky, alebo vynulovať ho. | ||
Riadok 32: | Riadok 49: | ||
− | + | == Further reading == | |
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37871 Bit manipulation (AKA "Programming 101")] | * [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37871 Bit manipulation (AKA "Programming 101")] |
Verzia zo dňa a času 06:35, 1. október 2010
V assembleri existuje pre manipuláciu s bitmi dostatok inštrukcií. To v C-čku štandardne nie je, preto sa musíme naučiť s bitmi manipulovať.
Vstupy
V prvom cvičení sme napríklad na test stlačenia tlačidla mohli použiť inštrukciu
sbis PIND,3 ; sbis = Skip if Bit Is Set, preskoc ak je PIND.3 nastaveny (=1)
V jazyku C ale typ bit neexistuje (hoci niektoré kompilátory takýto typ zaviedli), preto môžeme pracovať len s bajtmi, a musíme si nejako vypomôcť. Pri rozumnom zápise však kompilátor rozpozná, že chceme pracovať s bitom a preloží našu konštrukciu správne.
Ak chceme testovať stav jedného bitu v bajte, musíme ostatné zakryť, zamaskovať. To sa robí tzv. maskou:
Príslušná konštrukcia v C potom bude
if ( PIND & 0x08) // PIND & 0000 1000
To, že chceme pracovať s tretím bitom sa dá okrem priameho zápisu 0x08 zapísať aj takto:
(0x01<<3)
Príslušná konštrukcia v C potom bude
if ( PIND & (0x01<<3)) // PIND & 0000 1000
Pričom je užitočné zadefinovať si na tento účel makro (v skutočnosti už také makro s názvom _BV(x) existuje)
#define BIT(x) (0x01<<(x))
Podobne sú zadefinované aj tieto dve užitočné makrá (pozri <avr/sfr_defs.h>)
#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit)) #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
Takže napokon konštrukcia môže vyzerať takto:
#define Switch 3 if ( bit_is_set(PIND, Switch) ) // test, ci je tlacitko stlacene...
Výstupy
Obdobný problém nastáva, ak chceme nastaviť jeden jediný bit v celom osembitovom registri, či porte. Musíme dávať pozor, aby sme nezmenili stav tých ostatných bitov, ktoré meniť nechceme. Budeme rozlišovať, či chceme nastaviť bit do jednotky, alebo vynulovať ho.