// příklad detekce stisku tlačítka s ošetřením zákmitů pomocí milis s měřením délky stisku // každých 25ms kontroluje stav tlačítek // měří délku stisku k okamžiku uvolnění tlačítka - po úpravě lze využít jako "analogový vstup" (čím déle stisknuto, tím větší hodnota něčeho) // lze použít pokud v hlavní smyčce není žádný proces který by dlouhodobě (víc jak cca 25ms) blokoval vlákno. #include "stm8s.h" #include "milis.h" #define SCAN_PERIOD 25 // čas mezi skenováním stavů tlačítek (v ms) #define LONG_PRESS_TIME 1000 // minimální trvání stisku který má být vyhodnocen jako "dlouhý" void scan_buttons(void); void main(void){ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz z interního RC oscilátoru init_milis(); GPIO_Init(GPIOE,GPIO_PIN_4,GPIO_MODE_IN_PU_NO_IT); // inicializovat pin tlačítka GPIO_Init(GPIOC,GPIO_PIN_5,GPIO_MODE_OUT_PP_LOW_SLOW); // LEDka pro modelový příklad "nějaké akce" while (1){ scan_buttons(); // obsluhuj skenování tlačítek // dělej další "procesy" } } // po uplynutí každých SCAN_PERIOD skenuje stav tlačítka (tlačítek) a reaguje na stisk void scan_buttons(void){ static uint16_t last_time=0; // kdy naposled jsme stav tlačítek skenovali static bool last_button_status=1; // minuly stav tlačítka (0=stisk, 1=uvolněno) static uint16_t button1_time; // ukládáme si okamžik stisknutí pro vyhodnocení délky stisku if((milis() - last_time) > SCAN_PERIOD){ // pokud uplynul požadovaný čas, tak skenujeme stav tlačítek last_time = milis(); // zapamatuj si kdy jsi skenoval stav tlačítek // detekujeme okamžik stisku (tlačítko bylo minule uvolněné a teď je stisknuté) if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_4)==RESET && last_button_status==1){ last_button_status = 0; // zapamatuj si že teď je tlačítko stisknuté button1_time = milis(); // uložím si čas kdy bylo tlačítko stisknuto } // detekujeme okamžik uvolnení (tlačítko bylo minule stisknuté a teď je uvolněné) if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_4)!=RESET && last_button_status==0){ last_button_status=1; // zapamatuj si že teď je tlačítko uvolněné if( (milis()-button1_time) >= LONG_PRESS_TIME){ // byl to dlouhý stisk - udělej nějakou akci GPIO_WriteLow(GPIOC,GPIO_PIN_5); }else{ // byl to krátký stisk - udělej nějakou akci GPIO_WriteHigh(GPIOC,GPIO_PIN_5); } } } }