Kterak získat další výstup z PIC12Cxxx.

Při použití PIC12C671 mi najednou chyběl jeden výstup. Uvědomíme-li si, že chipy PIC12Cxxx mají jen 8 nožiček a 2 jsou použity pro napájení, zbývá nám jen 6 pinů, z nichž je jeden jen vstupní, tedy GP3. GP3 se dá využívat jen v případě, že využijete vnitřní reset PICu a ne pin /MCLR. Ve své aplikaci jsem navíc potřeboval přesné časování a tak jsem zavrhl taktování interním RC oscilátorem a to znamená připojit krystal a tak ztratit další 2 piny. Zbylo mi tedy jen GP0,GP1,GP2 a GP3 z nichž poslední jmenovaný je jen vstupem. Teď si asi říkáte, že jsem jako výstup mohl použít jiný pin a určitě jsem měl něco připojovat jako vstup, tak je to vlastně OK. Jenže nebylo. 12C671 obsahuje prevodník analog-digital a ten se dá použít pouze ze 4 pinů a GP3 jím právě není. A když jsem chtěl použít 2 analogové vstupy a 2 digitální výstupy, bylo nutné přesvědčit GP3, aby se choval jako výstup. Co s tím a jaké to způsobí komplikace, to je to, co chci právě popsat.

Jak na to ?

Z elektronického hlediska je nutné nějak získat změny stavu pinu GP3. Jediná změna zvenčí patrná je připojení a odpojení pull-up odporu, tedy odporu od + napájení k pinu. Normálně se používá proto, aby bylo možno vynechat odpor při testování třeba tlačítka od pinu k zemi bez použití vnějšího odporu. U PIC12Cxxx je onen pull-up volitelný v registru OPTION a lze jej připojit a odpojit. Bohužel jen u bran GP0, GP1 a GP3 současně. Protože je pull-up vytvořen jako unipolární tranzistor, není jeho hodnota daná, ale mění se s proudem z pinu do země. Je nutné podotknout, že onen pull-up má dost velkou hodnotu a tak připojení přes odpor k zemi a přímé buzení např. hradla z GP3 není dost dobře možné. V 5_004.PDF na strankách Microchipu je popsáno sice jak GP3 jako výstup použít, ale tak jak je to zapojeno se to může hodit pouze v aplikacích, kde nějaká desetina sekundy nehraje žádnou roli, kód je použitelný. No uznejte, líbí se Vám nabíjet 220n kapacitu přes pull-up a vybíjet přes 820k ? To asi nebude moc rychlé že ? Já jsem GP3 zapojil dle schématu na začátku této stránky. Jak je patrné, tranzistoru stačí pro otevření i to co pull-up dodá. Pak po připojení a odpojení pull-up odporu nastavováním bitu v registru OPTION dosáhneme výstupu už lépe použitelného. Připojený pull-up znamená výstup z tranzistoru v 0, bez pull-up v 1.

Část použitého kódu pro 12C671 může nyní vypadat následovně:

bsf STATUS,RP0 ;bank 1

movlw b'00000000' ;povolit pullup - bit 7 je v 0

movwf OPTION_REG ;Zapsat do OPTION registru


Tady jsme otevřeli tranzistor a výstup je tedy v zemi, tedy 0.


Nebo pro výstup v 1:


bsf STATUS,RP0 ;bank 1

movlw b'10000000'

movwf OPTION_REG ;Vystup z GP3 pres tranzistor nahozen - bez pull-up


BSF STATUS,RP0 přepíná banku registrů, jelikož OPTION je u 12C671 v bance 1.

Je třeba si jen dát pozor na OPTION registr, abychom si nepřepli něco co nechceme. Tady je rozdíl mezi 12C5xx a 12C67x, kde 12c5xx plní OPTION registr speciální instrukcí OPTION, kdežto např. u 12C671 je OPTION registr dostupný přímo v bance registrů jedna (po resetu je aktivní nultá). Ale to už je jiná věc, kterou jsem zde popisovat nechtěl. Zkrátka jak nahodit ten pull-up může být u různých typů 12Cxxx různé, ale praktický výsledek je stejný. Já to zkoušel na 12C671 a OPTION registr obsahoval v celém programu totéž až na jeden bit ovládající pull-up a tak jsem klidně zapisoval celý OPTION registr i když uznávám, že u 12C671 nastavovat jen konkrétní bit /GPPU by stačilo.

Pozor ! Bit /GPPU registru OPTION je u 12C508 bit 6, u 12C671 je to bit 7. Tedy nahlédnout do PDF souboru ke konkrétnímu chipu je více než dobré.

Má to ale háček.

Protože se nastaví zároveň pull-up i pro další 2 piny, musíme s tím počítat. Pokud jsou GP0 a GP1 jako výstup, jsme bez problému. Pokud jako vstup, musíme zajistit, aby pull-up nevadil ani odpojený ani připojený a to asi také není problém. Problémem je, když GP0 a GP1 použijeme jako AN0 a AN1, tedy jako vstup ADC (převodník analog-digital) např. u 12C671. To by mohlo znemožnit přesné měření napětí na nich a tedy znehodnotit funkci ADC. Ale i to se dá obejít. Prostě se AN0 a AN1 pomocí ADC převádějí jen v době, kdy je pull-up odpojen, je tedy možné připojit třeba jezdec potenciometru k AN0 (GP0) a vždy převádět v době, kdy je pull-up odpojen, což v některých aplikacích nevadí, u některých to vyžaduje ještě inverzi výstupu GP3 navíc z důvodu, že měřit potřebujeme právě v opačné úrovni výstupu a v některých aplikacích by to asi nešlo vůbec. V každém případě to znamená při psaní programu na to stále myslet.

Závěr.

Toto řešení je jistě méně pohodlné než rovnou použít některý výstup, vyžaduje dodatečné součástky a hodí se tedy především v nouzi s výstupními piny. Ale při počtu pinů 12Cxxx docházejí piny velice rychle a tak si myslím, že uvedené řešení má význam. Měřením na osciloskopu jsem shledal průběh pulsu generovaného pomocí GP2 a z GP3 přes tranzistor jako totožné. Jen je třeba si uvědomit, že výstup z GP2 je v 1 i 0 tvrdý, kdežto z GP3 v zapojení přes tranzistor je v 1 přes 4k7 odpor a v 0 tvrdý. Já jsem tento princip využil u servotesteru se kterým se budete moci brzy seznámit na těchto stránkách.

Autorův e-mail: jiri@bezstarosti.cz