Operácie

AVR Bit Magic

Z SensorWiki

Verzia z 06:36, 1. október 2010, ktorú vytvoril Balogh (diskusia | príspevky) (Vstupy)

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:

MMP Cvicenie2 Input.png

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))

Príslušná konštrukcia v C potom bude

if ( PIND & BIT(3))          // PIND & 0000 1000

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.



MMP Cvicenie2 Output.png


Further reading