logo_elektromys.eu

/ STM8 GPIO IV.|

/ Úvod |

Touto kapitolou opustíme tématiku vstupů. Vysvětlíme zde poslední zajímavou funkci vstupů STM8 - vnitřní pull-up rezistory.

/ Interní pull-up |

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.

Cv.1 Vytvořte program, který stiskem jednoho tlačítka ("ON") rozsvítí LEDku, stiskem druhého tlačítka ("OFF") ji zhasne. LEDku použijte vestavěnou na Nucleo kitu (pin PC5). Tlačítka "ON" připojte k pinu PG4, tlačítko "OFF" k pinu PG5. Pro přehlednost je ve schematu níže znázorněno zapojení vnitřních pullup rezistorů v našem mikrokontroléru.



Vše potřebné už známe. Konfiguraci pinů PG4 a PG5 provedeme pomocí funkce GPIO_Init s argumentem GPIO_MODE_IN_PU_NO_IT - tedy jako vstup se zapnutým vnitřním pullup rezistorem. Program bude stále dokola číst stav tlačítka ON i OFF a porovnávat ho s předchozím stavem aby rozpoznal "okamžik stisknutí" (tento koncept už také znáte). Jakmile zjistí stisknutí tlačítka ON, rozsvítí LEDku. Když zachytí stisk tlačítka OFF tak ji zhasne. Všimněte si, že všechny proměnné pro práci s tlačítkem jsou typu _Bool. Tento datový typ může nabývat pouze hodnoty 0 a 1 (nebo TRUE a FALSE jak chcete) a v paměti je uložen jako jeden bit. Jeho použitím jednak uspoříme trochu paměti, ale hlavně zlepšíme čitelnost programu. Protože už při deklaraci proměnné (to je řádek _Bool minuly_stav_on_tlacitka=0;) dáváme jasně najevo že může nabývat pouze dvou hodnot. Kdybychom použili napříkald typ uint8_t (tedy bajt), mohl by si čtenář našeho kódu myslet, že do proměnné budeme ukládat i jiné hodnoty než 0 a 1 a to by mu komplikovalo pochopení našeho programu.

#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; 
 }
}

Cv.2 Připravte jednoduchý program, který nastaví pin PG4 jako vstup s pull-up rezistorem a nahrajte ho do mikrokontroléru. Připojujte postupně mezi pin PG4 a GND rezistory Rx o odporu 22k, 68k a 100k a měřte napětí na pinu. Změřte napájecí napětí čipu (Unap) a pokuste se dopočítat přibližný odpor vnitřního pullup rezistoru (Rp).



Ke stanovení hodnoty odporu Rp nám stačí Ohmovy a Kirchhoffovy zákony. Vezmeme to postupně. Ze známé hodnoty Rx a známého napětí na Rx (Ux - to jste měřili) můžeme spočítat proud I tekoucí odporem Rx (a tedy i Rp). Ten je roven
I = Ux/Rx
Z Kirchhoffova zákona můžeme spočítat napětí na Up odporu Rp jako
Up=Unap-Ux
Z napětí Up (na odporu Rp) a proudu který skrze něj protéká (I) můžeme stanovit hodnotu odporu Rp.
Rp = Up/I = (Unap-Ux)/(Ux/Rx) = Rx*(Unap-Ux)/Ux
Mě se podařilo změřit následující trojici hodnot:
Ux = 1.58V pro Rx=22k a Rp mi vyšel 48.9k
Ux = 2.93V pro Rx=68k a Rp mi vyšel 50.1k
Ux = 3.34V pro Rx=100k a Rp mi vyšel 52.4k
Vaše výsledky se budou od těch mých jistě lišit (pamatujete si že vnitřní pullupy mají velkou toleranci). Měření s menším odporem jsou přesnější, protože se méně uplatňuje vnitřní odpor voltmetru.
Odpor vnitřního pullup rezistoru je přibližně 49kOhm.

/ Detaily pro "zvídavé" |

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.


Zákmity tlačítka při stisku

/ K zapamatování |

| Odkazy /

Home
| V1.01 29.4.2020 /
| By Michal Dudka (m.dudka@seznam.cz) /