Operácie

AVR Bit Magic

Z SensorWiki

Verzia z 06:45, 1. október 2010, ktorú vytvoril Balogh (diskusia | príspevky) (Výstupy)

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. Ani v tomto prípade v assembleri problém neexistuje:

sbi PORTB,LED1        ; Set Bit LED1 na porte PB
cbi PORTB,LED1		; Set Bit LED1 na porte PB

Keďže v C pracujeme s celým bajtom, musíme dávať pozor, aby sme nezmenili stav tých ostatných bitov, ktoré meniť nechceme. Preto najprv prečítame obsah príslušného registra a pomocou masky v ňom zmeníme práve ten jeden požadovaný bit. Budeme rozlišovať, či chceme nastaviť bit do jednotky, alebo vynulovať ho.


Pre nastavenie do nuly (resp. zhodenie, vynulovanie)

MMP Cvicenie2 Output0.png


MMP Cvicenie2 Output1.png

Further reading