#define BUTTONS_MAX 1
#define BUTTON_INTEG_MAX 10
#define CLR( A ) {A[0]=0;}
#define SET( A ) {A[0]=1;}
#define BCK( A ) {A[1]=A[0];}
#define isRUP( A ) (A[0] && !A[1])
#define isFDW( A ) (!A[0] && A[1])
#define isHLD( A ) (A[0] && A[1])
struct sBUTTON {
GPIO_TypeDef* port;
uint16_t pin;
uint8_t pressValue;
uint32_t portClk;
int8_t integ;
int8_t state[2];
void (*actionRUP)( void );
void (*actionHLD)( void );
void (*actionFDW)( void );
};
void action1( void );
void action2( void );
void action3( void );
struct sBUTTON sButtons[ BUTTONS_MAX ] = {
{ BTN_A_PORT, BTN_A_PIN, Bit_SET, BTN_A_CLK, 0, {0,0}, action1, action2, action3 }
};
void DoButtons( void ){
uint8_t i = 0;
for( i = 0 ; i < BUTTONS_MAX ; i++ ){
// Integrate
if( sButtons[i].pressValue == GPIO_ReadInputDataBit( sButtons[i].port, sButtons[i].pin ) ){
sButtons[i].integ++;
}else{
sButtons[i].integ--;
}
// Limit
if( sButtons[i].integ > BUTTON_INTEG_MAX ){
sButtons[i].integ = BUTTON_INTEG_MAX;
}else if( sButtons[i].integ < -BUTTON_INTEG_MAX ){
sButtons[i].integ = -BUTTON_INTEG_MAX;
}
// Hysteresis
if( sButtons[i].integ > BUTTON_INTEG_MAX / 2 ){
SET( sButtons[i].state );
}else if( sButtons[i].integ < -BUTTON_INTEG_MAX / 2 ){
CLR( sButtons[i].state );
}
// Rise-Up/Falling-Down edge detection
if( isRUP( sButtons[i].state ) ){
// RUP action perform
if( NULL != sButtons[i].actionRUP ){
sButtons[i].actionRUP();
}
}else if( isFDW( sButtons[i].state ) ){
// FDW action perform
if( NULL != sButtons[i].actionFDW ){
sButtons[i].actionFDW();
}
}else if( isHLD( sButtons[i].state ) ){
// HLD action perform
if( NULL != sButtons[i].actionHLD ){
sButtons[i].actionHLD();
}
}
// Backup state
BCK( sButtons[i].state );
}
}
void action1( void ){
A = 1;
A = 0;
}
void action2( void ){
B = 1;
B = 0;
}
void action3( void ){
C = 1;
C = 0;
}
void main(){
InitButtons();
while(1){
DoButtons();
Delay_mS(10);
}
}