Operácie

AVR Bit Magic: Rozdiel medzi revíziami

Z SensorWiki

d
(Vstupy)
Riadok 17: Riadok 17:
 
  if ( PIND & 0x08)          // PIND & 0000 1000
 
  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:
+
To, že chceme pracovať s tretím bitom sa dá okrem priameho zápisu 0x08 zapísať aj takto (0x01<<3).
(0x01<<3)
 
 
 
 
Príslušná konštrukcia v C potom bude
 
Príslušná konštrukcia v C potom bude
 
  if ( PIND & (0x01<<3))          // PIND & 0000 1000
 
  if ( PIND & (0x01<<3))          // PIND & 0000 1000
Riadok 25: Riadok 23:
 
Pričom je užitočné zadefinovať si na tento účel makro (v skutočnosti už také makro s názvom _BV(x) existuje)
 
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))
 
  #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>)
 
Podobne sú zadefinované aj tieto dve užitočné makrá (pozri <avr/sfr_defs.h>)
Riadok 32: Riadok 33:
 
  #define Switch 3
 
  #define Switch 3
 
  if ( bit_is_set(PIND, Switch) )          // test, ci je tlacitko stlacene...
 
  if ( bit_is_set(PIND, Switch) )          // test, ci je tlacitko stlacene...
 
 
 
  
 
== Výstupy ==
 
== Výstupy ==

Verzia zo dňa a času 06:36, 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:

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