hamik158

13. díl – OctopusLAB – poznáváme elektroniku

V dalších pokračováních seriálu o jednoduchém mikrokontroléru ATtiny si v rychlosti zopakujeme základní logické operace. Navážeme pak na datové sběrnice se zaměřením na práci se sběrnicí I2C. A ve finále si sestrojíme jednoduchý emulátor logických hradel a základních klopných obvodů.

Logické operace – hradla a práce s bity

Opět vzhledem k omezenému prostoru si pouze velmi stručně zopakujeme nejdůležitější poznatky. Na následujícím obrázku je přehled základních logických operací a jejich HW interpretace pomocí logických hradel.

Modře je uvedena používaná zkratka operace nebo hradla.
Schematická značka je uvedena hned pod zkratkou. S oblibou se používá dnes již zastaralá US symbolika, moderní hradla jsou podle normy ISO zjednodušené na pouhé obdélníky a druh je rozlišen dovnitř vepsaným „1“, „&“ nebo „=1“, na obrázku šedě pod značkou hradel.
Logický výraz, reprezentován logickým operátorem, uvádíme zeleně.
Pro AND se uvádí i tečka, hvězdička (operace odpovídá násobení) nebo znak &. Negace je v zápisu reprezentována čárkou nad symbolem a ve schématu je to kroužek (viz symbol NOT).
Rozšířené logické operace vznikají kombinací základních, například:
NAND = AND + NOT.
Každá operace je popsána pravdivostní tabulkou (jednotlivým vstupům A, B odpovídá výstup Q).

Na dalším zapojení je zobrazena nejjednodušší simulace jednoho logického hradla pomocí mikrokontroléru. Výhodou je jednoduchost a možnost sestavit libovolné hradlo, částečně i jejich kombinace. Nevýhodou je oproti klasickému hradlu jistá pomalost, kterou ale při testování pomocí tlačítek a svítivé diody nejsme schopni postřehnout.

Pro obecné hradlo jsme použili obdélník (bez označení – bude se měnit podle programu). Na vstupech A, B máme tlačítka (nebo spínače či senzory – libovolný digitální vstup) a jako výstup nám slouží LED dioda, ale signál se dá opět použít pro další část jiného obvodu. Pro jednoduchost ukážeme hlavní část kódu pro hradlo AND:

void setup() {  
  DDRB = 0b00000010; //Data Direction (PB1 = out)  
  PORTB = 0b0011000; //pull-up for PB3, BB4 (in) 
  } 

void loop() { 
  if ((PINB & 0b00001000) && (PINB & 0b00010000)) //A, B  
  {  
    PORTB |= 0b00000010; //PB1 to HIGH (LED on) 
  } 
  else  {  
    PORTB &= 0b11111101; //PB1 to LOW (LED off)
  } 
}

Pro častější experimentování se nám mohou hodit makra pro práci s jednotlivými bity:

#define bitset(byte,nbit)   ((byte) |=  (1<<(nbit))) 
#define bitclear(byte,nbit) ((byte) &= ~(1<<(nbit))) 
#define bitflip(byte,nbit)  ((byte) ^=  (1<<(nbit))) 
#define bitcheck(byte,nbit) ((byte) &   (1<<(nbit)))  
//example:
if (bitcheck(PINB, 3)) {bitset(PORTB,2);} //PB3->PB2 

Povšimněte si použití logických funkcí: negace „~“, AND „&“, OR „|“, XOR „^“ a také bitového posunu „<<“ / „>>“. Například metoda, která se nazývá „maskování“, využívá AND tak, že „propustí“ jen hodnotu, kde má maska log. „1“.

PINB & 0b00001000  // vrací PB3 (zprava: 0,1,2,3)
AND (&) přes masku vrací hodnotu na pinu 3, je to stejné jako:  
PINB  &  1<<(3)  // zde bit třikrát posuneme (rotace), alternativní získání "masky". 

V příštím díle pokračujeme sběrnicemi a bitovým expandérem.