Touto kapitolou opustíme tématiku vstupů. Vysvětlíme zde poslední zajímavou funkci vstupů STM8 - vnitřní pull-up rezistory.
Funkci pull-up rezistoru jsme si probrali v dílu o používání tlačítka. Pokud si dobře pamatujete jako pull-up tam sloužil rezistor 4k7 připojený mezi tlačítko a napájecí napětí. Měl za úkol přivádět 5V na vstup mikrokontroléru v situaci kdy bylo tlačítko uvolněné (rozpojené). Pokud si budete chtít k mikrokontroléru připojit vlastní tlačítka, nebo přepínače, budete každý vstup muset vybavit takovým pull-up rezistorem. Naštěstí má naše STM8 zabudované vnitřní "pullupy", takže místo otravného připojování rezistorů si je prostě jen "zapneme". Odpor vnitřních "pullupů" je někde mezi 30-80kOhmy, takže jeho přesnou hodnotu ani zdaleka neznáte. To vás ale nemusí trápit, protože k většině účelů není přesná hodnota zajímavá. Zapnutí nebo vypnutí pullup rezistoru provádíme při konfiguraci pinu. Chceme-li nastavit pin jako vstup se zapnutým pullup rezistorem, zavoláme funkci GPIO_Init s argumentem GPIO_MODE_IN_PU_NO_IT. Zkratka PU znamená Pull Up. Použití pullupů je z pohledu programování naprosto jednoduché, takže si to procvičíme.
#include "stm8s.h" // makra pro rozsvěcení a zhasínání LEDky #define ZAPNOUT_LED GPIO_WriteHigh(GPIOC,GPIO_PIN_5) #define VYPNOUT_LED GPIO_WriteLow(GPIOC,GPIO_PIN_5) _Bool minuly_stav_on_tlacitka=0; // 0=tlačítko bylo minule uvolněné, 1=tlačítko bylo minule stisknuté _Bool minuly_stav_off_tlacitka=0; // 0=tlačítko bylo minule uvolněné, 1=tlačítko bylo minule stisknuté _Bool aktualni_stav_tlacitka=0; // 0=tlačítko je uvolněné, 1= tlačítko je stisknuté void main(void){ GPIO_Init(GPIOG,GPIO_PIN_4,GPIO_MODE_IN_PU_NO_IT); // nastavíme pin PG4 jako vstup s vnitřním pull-up rezistorem GPIO_Init(GPIOG,GPIO_PIN_5,GPIO_MODE_IN_PU_NO_IT); // nastavíme pin PG5 jako vstup s vnitřním pull-up rezistorem GPIO_Init(GPIOC,GPIO_PIN_5,GPIO_MODE_OUT_PP_LOW_SLOW); // nastavíme pin PC5 jako výstup typu push-pull while (1){ // zjistíme stav "ON" tlačítka if(GPIO_ReadInputPin(GPIOG,GPIO_PIN_4)==RESET){ // pokud je na vstupu od "ON" tlačítka log.0 tak... aktualni_stav_tlacitka=1; // ...je tlačítko stisknuté } else{ // jinak je ... aktualni_stav_tlacitka=0; // ...tlačítko uvolněné } // zjišťujeme jestli nastal "okamžik stisku" if(minuly_stav_on_tlacitka==0 && aktualni_stav_tlacitka==1){ ZAPNOUT_LED; // pokud ano, rozsvítíme LEDku } minuly_stav_on_tlacitka = aktualni_stav_tlacitka; // přepíšeme minulý stav tlačítka aktuálním // úplně stejnou akci provedeme pro OFF tlačítko // zjistíme stav "OFF" tlačítka if(GPIO_ReadInputPin(GPIOG,GPIO_PIN_5)==RESET){ aktualni_stav_tlacitka=1; } else{ aktualni_stav_tlacitka=0; } // detekujeme okamžik stisku "OFF" tlačítka if(minuly_stav_off_tlacitka==0 && aktualni_stav_tlacitka==1){ VYPNOUT_LED; } minuly_stav_off_tlacitka = aktualni_stav_tlacitka; } }
Možná jste si vzpomněli, že tlačítko na Nucleo kitu krom vnějšího pullup rezistoru obsahuje také paralelně připojenou kombinaci 100Ohm rezistoru a 100nF kondenzátoru. My jsme tam teď ale nic takového neměli a program pracoval správně, takže jsou snad tyto součástky zbytečné ? Jsou i nejsou. Náš program byl naštěstí tak jednoduchý že mu nevadily tzv. "zákmity" tlačítka (anglicky bouncing). Schválně se podívejte na oscilogram níže, jak ve skutečnosti vypadá stisk tlačítka. Žádný jeden přechod z log.1 do log.0, ale spousta škaredých přechodů tam a zpátky jak se tlačítko postupně přibližuje a jeho kontakty se spojují. Tento nepříjemný jev lze ošetřit buď externím obvodem (například onou kombinací rezistoru a kondenzátoru), ale také softwarově (což je asi lepší řešení). Jak na to si ukážeme někdy později.
Home
| V1.01 29.4.2020 /
| By Michal Dudka (m.dudka@seznam.cz) /