← Kursens material Binärt och logiska grundfunktioner · område 3 Område 3

Område 3 · lektion 11

Binärt och logiska grundfunktioner

Ditt bygge har hittills haft en insignal. Nu ska det få två, och då uppstår en fråga som inte fanns förut: vad betyder de tillsammans? Svaret på den frågan har ett eget namn och en egen notation, och den är äldre än datorn.

Mål

Genomgång

Två nivåer, och varför det räcker

En sladd kan bära vilken spänning som helst mellan 0 och 5 V. Ändå bestämde sig den som konstruerade kortet för att bara använda två av dem. Det ser ut som slöseri, och det är motsatsen.

Databladet för ATmega328P – chippet på ditt kort – anger inte två spänningar utan två områden, räknade som andelar av matningsspänningen. En ingång läses som LOW under 0,3 av matningen och som HIGH över 0,6 av den. Med 5 V blir det:

LOW: U ≤ 0,3 · 5 V = 1,5 V

HIGH: U ≥ 0,6 · 5 V = 3,0 V

Mellan 1,5 och 3,0 V är svaret odefinierat – chippet får läsa vad det vill. Det gapet på 1,5 V är hela poängen. En störning som lyfter en nollsignal med en halv volt gör den till 0,5 V, som fortfarande är entydigt LOW. Skulle sladden i stället bära ett mätvärde hade samma störning förvanskat värdet med tio procent utan att någon märkte det.

Robusthet, inte enkelhet Två nivåer valdes inte för att de var lätta att räkna med. De valdes för att en signal som bara har två giltiga lägen kan återställas i varje steg: varje grind läser en smutsig signal och skickar vidare en ren. Ett mätvärde kan aldrig återställas på samma sätt – det du tappat i brus är borta. Därför är världens signaler analoga men världens styrsystem digitala.

Binärt: att räkna med två siffror

Med bara siffrorna 0 och 1 fungerar räknandet precis som vanligt, men varje position är värd dubbelt så mycket som den till höger i stället för tio gånger. Positionerna är alltså 1, 2, 4, 8, 16 och så vidare.

Position8421
Talet 10111011
Bidrar med8021

1011₂ = 8 + 0 + 2 + 1 = 11

Åt andra hållet: hur många olika värden ryms i ett visst antal bitar? Varje bit fördubblar antalet, så n bitar ger 2ⁿ kombinationer.

1 bit: 2¹ = 2 · 2 bitar: 2² = 4 · 3 bitar: 2³ = 8 · 8 bitar: 2⁸ = 256

Det där sista talet har du redan sett: byte i språkreferensens typtabell rymmer 0 till 255, alltså 256 värden.

Samma räkning gäller insignaler. Två knappar kan stå i 2² = 4 lägen tillsammans. Tre knappar ger 2³ = 8. Det är därför en sanningstabell för två insignaler alltid har exakt fyra rader – varken fler eller färre – och det är också måttet på hur mycket du behöver testa när bygget är klart.

De fyra grundfunktionerna

En grind är en krets som tar en eller två insignaler och lämnar en utsignal. Symbolerna nedan är de som står i scheman och i datablad.

Symbolerna för fyra logiska grindar, ordnade i två rader om två. Uppe till vänster AND, ritad som en rektangel med halvcirkelformad högersida, med två ingångar A och B till vänster och utgången U till höger. Uppe till höger OR, ritad med inbuktad vänstersida och spetsig högersida, med samma anslutningar. Nere till vänster XOR, samma form som OR men med en extra båge utanför vänstersidan. Nere till höger NOT, ritad som en triangel med en liten ring på spetsen, med bara en ingång A. A B U A B U A B U A U AND OR XOR NOT

Sanningstabellerna

En sanningstabell räknar upp alla lägen ingångarna kan stå i och vad utgången blir i vart och ett. Med två ingångar är det fyra rader, av skälet som räknades ut ovan. Tabellen är inte en beskrivning av grinden – den är grinden. Två kretsar med samma sanningstabell gör samma sak, hur olika de än är byggda.

ABA AND BA OR BA XOR B
00000
01011
10011
11110

NOT har bara en ingång och därför bara två rader:

ANOT A
01
10

Läs den stora tabellen kolumnvis en gång och lägg märke till tre saker. AND-kolumnen har en enda etta, längst ned. OR-kolumnen har en enda nolla, längst upp. Och XOR skiljer sig från OR i exakt en rad: den sista, där båda är ettor. Det är hela skillnaden mellan "minst en" och "precis en av dem".

Ordningen på raderna är ingen slump Skriv alltid raderna som 00, 01, 10, 11. Det är talen 0, 1, 2 och 3 skrivna binärt, i ordning – samma räkning som i förra avsnittet. Gör du det får du aldrig en tabell med en glömd eller dubblerad rad, och en granskare kan läsa den utan att kontrollräkna.

Samma funktioner uttryckta i kod

En grind är hårdvara. I ditt bygge finns ingen grind – där finns en styrenhet som gör samma sak i mjukvara, med tre tecken som du redan sett i språkreferensens jämförelsetabell.

GrindI C++Uttalas
AND&&och
OR||eller
NOT!inte
XOR!=skilt från

Den sista raden ser fel ut och är rätt. C++ har ingen egen operator för logiskt XOR. Men "A och B är olika" är precis vad != säger, och för två sanningsvärden är det samma funktion som XOR-tabellen ovan.

En AND-grind mellan två knappar och en lysdiod blir alltså det här, med konstanterna deklarerade överst i filen som vanligt:

const int KNAPP_A_PIN = 2;
const int KNAPP_B_PIN = 3;
const int LAMPA_PIN   = 8;

// ... och inne i loop():
if (digitalRead(KNAPP_A_PIN) == LOW && digitalRead(KNAPP_B_PIN) == LOW) {
  // båda nedtryckta – LOW betyder nedtryckt med INPUT_PULLUP
  digitalWrite(LAMPA_PIN, HIGH);
} else {
  digitalWrite(LAMPA_PIN, LOW);
}

Två saker att lägga märke till redan nu. Det står två et-tecken, inte ett – ett ensamt & är en annan operator som gör en annan sak, och kompilatorn säger ingenting. Och villkoret testar LOW, eftersom knappen med intern pull-up är nedtryckt när den ligger på noll. Inversionen från förra området gäller fortfarande, och den blir bara mer förvirrande när den möter en logisk regel.

Nästa guide går igenom operatorerna ordentligt, inklusive vad det ensamma et-tecknet faktiskt gör.

I industrin och i vardagen

I industrin: innan styrenheter blev billiga byggdes maskinlogik av fysiska komponenter, och den byggs fortfarande så där det måste gå fort eller vara enkelt att granska. En krets som 74HC08 innehåller fyra AND-grindar i en kapsel med fjorton ben, och en grind i den svarar på en insignal inom storleksordningen tio nanosekunder. Samma funktion byggdes i äldre maskinskåp med reläer: ett relä per grind, med en omslagstid i storleksordningen tio millisekunder. Skillnaden är

10 ms / 10 ns = 0,01 s / 0,00000001 s = 1 000 000 gånger

En miljon gångers skillnad i snabbhet – och ändå sitter reläer kvar i säkerhetskretsar än i dag, av precis det skäl som gör dem långsamma: ett relä är en fysisk kontakt som går att se, mäta och tvångsstyra. Ett säkerhetsrelä där kontakterna är mekaniskt hopkopplade kan inte fastna i "sluten" utan att det syns på en annan kontakt. En grind i ett chip kan det.

I vardagen: hallen hemma har troligen två strömbrytare till samma lampa, en vid varje dörr. Den kopplingen är en XOR som ingen kallar för en XOR. Två växelströmbrytare ger 2² = 4 kombinationer, och lampan lyser i två av dem – de två där brytarna står i olika lägen. Beroende på hur de två ledarna mellan brytarna dras kan det bli XOR eller dess motsats XNOR, och för den som bor i huset spelar det ingen roll: den enda egenskap man bryr sig om är att vippa på endera brytaren alltid byter lampans läge, och det gäller i båda fallen. Det finns ingen elektronik i kopplingen alls – logiken sitter i hur sladdarna är dragna, vilket är den äldsta formen av logisk grundfunktion som finns i ett hem.

Prova själv

  1. Skriv sanningstabellerna för AND, OR, XOR och NOT ur minnet på ett papper. Rader i ordningen 00, 01, 10, 11. Jämför sedan med tabellerna ovan och rätta.
  2. Räkna om 1101, 0110 och 10000 till decimala tal. Kontrollera genom att addera positionsvärdena. Facit finns bland kontrollfrågorna.
  3. Koppla in två tryckknappar, en på D2 och en på D3, båda mellan pinnen och GND. Ställ in båda med INPUT_PULLUP.
  4. Skriv en sketch som skriver ut båda knapparnas lägen till seriemonitorn ungefär fem gånger i sekunden, som två siffror på samma rad. Tryck knapparna i alla fyra kombinationerna och kontrollera att du ser 11, 10, 01 och 00. Kom ihåg att en uppsläppt knapp visar 1 på grund av pull-upen.
  5. Lägg till en lysdiod på D8 och låt den lysa enligt AND: bara när båda knapparna är nedtryckta. Byt sedan villkoret till OR och kontrollera att beteendet ändras som tabellen säger.
  6. Sista steget, och det är svårare än det låter: få lysdioden att följa XOR, alltså lysa när precis en av knapparna är nedtryckt. Du behöver inte fler än en rad, och != är den raden.

Kontrollfrågor

Vad blir 1101, 0110 och 10000 som decimala tal?

1101 = 8 + 4 + 0 + 1 = 13. 0110 = 0 + 4 + 2 + 0 = 6. 10000 = 16 + 0 + 0 + 0 + 0 = 16. Kontrollen är enkel: ett tal med en etta längst till vänster och bara nollor efter är alltid en jämn tvåpotens.

Hur många rader har sanningstabellen för fyra insignaler, och varför?

2⁴ = 16 rader. Varje ny insignal fördubblar antalet kombinationer, eftersom varje rad som fanns förut nu finns i två versioner – en där den nya signalen är 0 och en där den är 1.

En ingång på ditt kort ligger på 2,2 V. Vad läser digitalRead()?

Det går inte att säga. 2,2 V ligger i gapet mellan 1,5 V och 3,0 V, där databladet inte lovar någonting. Du kan få HIGH, LOW, eller olika svar från gång till gång. En signal som hamnar där är alltid ett fel i kopplingen, inte ett fall att hantera i koden – den vanligaste orsaken är en ingång utan pull-up.

Vilken enda rad skiljer XOR från OR?

Raden där båda ingångarna är ettor. OR ger 1 där, XOR ger 0. I alla tre andra rader är de identiska. Det är därför XOR ibland läses som "eller, men inte båda".

Två knappar ska öppna en lucka bara när ingen av dem är nedtryckt. Vilken funktion är det, uttryckt med grindarna du kan?

Det är NOT applicerat på OR, alltså NOR: !(A || B). Den är sann i exakt en av de fyra raderna – den översta, där båda är nollor. Samma sak kan skrivas !A && !B, vilket är samma funktion uttryckt som en AND mellan två inverteringar.

Varför spelar det gap på 1,5 V mellan nivåerna någon roll när signalen ändå kommer fram?

Därför att sladdar plockar upp störningar. Gapet är den marginal en störning får ta i anspråk innan signalen blir feltolkad. Ju längre sladd och ju mer elektrisk smuts i miljön, desto mer marginal behövs – och det är därför industrikretsar ofta arbetar på 24 V i stället för 5 V. Samma andelar, större absolut marginal.

Vanliga fel

Vidare

Kapitlet Villkor i språkreferensen hör till den här guiden, särskilt tabellen som ställer Pythons and, or och not mot C++:s tecken. Typer och variabler innehåller storlekarna som gör 2⁸ och 2¹⁶ till praktiska tal och inte bara matematik.

Nästa guide är Villkor i C++. Där flyttar sanningstabellerna in i koden, och de två operatorer som ser nästan likadana ut får varsin behandling.