Operácie

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 ===
+
== 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:

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

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