[PIC programování] – 11. díl – bonus

Vítám vás u malého bonusu k 11. dílu!

Napadlo mě malé kosmetické vylepšení našeho programu. Pokud je zobrazované číslo na displeji menší než 16, pak je v šestnáctkové soustavě jednociferné. Doposud jsme na displeji i jednociferné číslo zobrazovali jako dvojciferné, akorát s nulou na začátku. Toto chování můžeme snadno upravit využitím Carry bitu v registru STATUS (zmíněném v minulém bonusu).

Pro jasnost kódu vysvětlím chování Carry bitu. Pokud budem přičítat a dojde k přetečení registru, pak Carry bit bude roven 1, pokud k tomu nedojde, bude naopak Carry roven 0. V případě odčítání má Carry bit opačnou logiku. Při podtečení registru, nebo pokud je výsledek nulový, bude Carry = 0, jinak 1.

Odčítání má toto chování proto, poněvadž se provádí jako sčítání první hodnoty s dvojkovým doplňkem druhé hodnoty.

Co je proboha dvojkový doplněk?

Dvojkový doplněk (v angličtině Two’s complement) je způsob kódování záporného čísla v binární podobě). Pokud máme 8-bitové číslo, můžeme jej buď reprezentovat hodnotami 0 až 255 nebo -128 až 127. Např. v jazyce C se rozlišuje typ signed (znaménkový) a unsigned (bezznaménkový).

Ukážu pár čísel v různých reprezentacích:

8-bit binární forma 8-bit signed 8-bit unsigned
b’11111110′ -2 254
b’11111111′ -1 255
b’00000000′ 0 0
b’00000001′ 1 1
b’00000010′ 2 2

Znaménková reprezentace dává smysl, protože pokud bychom od nuly odečetli 1, dojde k podtečení na hodnotu 0xFF (b’11111111′). Nyní se nabízí otázka, jak ke kladnému číslu vypočítám záporné? Jednoduše. Vezmu bitovou negaci čísla a přičtu k ní jedničku.

Pojďme si ukázat příklad na čísle 1 = b’00000001′ = 0x01

Nejprve negace: ~1 = ~b’00000001′ = b’11111110′ = 254
Potom inkrementace: 254 + 1 = 255 = b’11111111′

Hm… Ono to funguje! Sedí nám to s tabulkou nahoře! Operaci, kterou jsme právě udělali se říká dvojkový doplněk. A to je celá magie.

Tak si pojďme ukázat chování Carry bitu s reprezentací sublw jako addlw s dvojkovým doplňkem. Vezmeme případ, kdy se obě čísla rovnají a my je odčítáme:

máme WREG = b’00000100′ = 4
pokud provedeme sublw 4 (= sublw b’00000100′), je to stejné jako dvě operace addlw b’11111011′, incf WREG, tedy:

Abych to nějak zjednodušil: Carry = 1 jen v případě, že dojde k přetečení registru. Jestliže k tomu nedojde (ani po nahrazení sublw instrukcí addlw), Carry = 0. Doufám, že se jsem to vysvětlil dostatečně srozumitelně. Pokud ne, pište prosím do komentářů.

Takže stačí, když do hlavního programu přidáme pod návěští __mpx_d1 (část kódu obsluhující první cifru/displej) tento kód:

Myslím, že komentáře mluví za vše. Kód je jednoduchý, ale je třeba se nad ním pořádně zamyslet, než jej člověk pochopí.

A zde je pro jistotu celý program:

A to je pro tento bonus vše!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.