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.