// příklad detekce krátkého a dlouhého stisku varianta 2 // každých 25ms přečte stav tlačítka, porovná s předchozím stavem a reaguje na stisknutí // při krátkém stisku reaguje na uvolněné tlačítka, při dlouhém stisku reaguje ihned po uplynutí "LONG_PRESS_TICKS" // 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_TICKS (1000/SCAN_PERIOD) // minimální trvání stisku který má být vyhodnocen jako "dlouhý" (v milisekundách, dělí se periodou,max 255*SCAN_PERIOD) 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 uint8_t last_button_status=1; // minuly stav tlačítka (0=stisk, 1=uvolněno, 2=uplynul dlouhý stisk) static uint8_t button_counter; // zde čítáme dobu 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é button_counter = 0; } // je tlačítko teď stisknuté a bylo i minule ? Tedy stisk trvá ? if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_4)==RESET && last_button_status==0){ if(button_counter < LONG_PRESS_TICKS){button_counter++;} // pokud stisk netrvá ještě dost dlouho else{ // stisk trval dostatečně dlouho - bereme tento okamžik za "konec" detekce a reagujeme last_button_status=2; // jsme ve stavu že proběhl dlouhý stisk (nyní chceme detekovat jen fyzické uvolnění tlačítka) // udělej nějakou akci GPIO_WriteLow(GPIOC,GPIO_PIN_5); } } if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_4)!=RESET){ if(last_button_status == 0){ // proběhl krátký stisk GPIO_WriteHigh(GPIOC,GPIO_PIN_5); } last_button_status=1; // zapamatuj si že teď je tlačítko uvolněné } } }