141 lines
3.2 KiB
C
141 lines
3.2 KiB
C
|
|
#include "DS_Button.h"
|
|
|
|
void DS_ButtonInit(DS_Button* Button, GPIO_TypeDef *Port, uint16_t Pin)
|
|
{
|
|
Button->Port = Port;
|
|
Button->Pin = Pin;
|
|
Button->Pressed = false;
|
|
Button->Released = false;
|
|
Button->PrevTick = 0;
|
|
Button->Storage = 5;
|
|
Button->PressedLong = false;
|
|
Button->PressStartTick = 0;
|
|
|
|
Button->FallingEdge = false;
|
|
Button->RisingEdge = false;
|
|
}
|
|
|
|
void DS_ButtonUpdate(DS_Button *Button)
|
|
{
|
|
//создаём переменную
|
|
//устанавливаем для неё границы от 0 до 10
|
|
//если кнопка нажата - увеличиваем значение переменной, пока не доберемся до максимального (10)
|
|
//если отпущена - уменьшаем, стремясь к нулю
|
|
//опрос состояния делаем не чаще чем 1 раз в 10 миллисекунд
|
|
//первое изменение делаем большим - 5 (имитация гистерезиса)
|
|
//по достижении нуля - устанавливаем флаг что кнопка отпущена
|
|
//по достижении 10 - флаг кнопка нажата
|
|
|
|
uint32_t CurrentTick = HAL_GetTick();
|
|
if ((CurrentTick - Button->PrevTick)<10)
|
|
return;
|
|
|
|
Button->PrevTick = CurrentTick;
|
|
|
|
|
|
GPIO_PinState PinState = HAL_GPIO_ReadPin(Button->Port, Button->Pin);
|
|
if (PinState == GPIO_PIN_SET)
|
|
{
|
|
if(Button->Storage == 0)
|
|
Button->Storage +=5;
|
|
else if(Button->Storage<=10)
|
|
Button->Storage++;
|
|
|
|
if(Button->PressStartTick == 0)
|
|
Button->PressStartTick = CurrentTick;
|
|
else if ((CurrentTick - Button->PressStartTick)>1000)
|
|
Button->PressedLong = true;
|
|
}
|
|
else
|
|
{
|
|
if(Button->Storage == 10)
|
|
Button->Storage -=5;
|
|
else if(Button->Storage > 0)
|
|
Button->Storage--;
|
|
|
|
Button->PressStartTick = 0;
|
|
Button->PressedLong = false;
|
|
}
|
|
|
|
switch (Button->Storage)
|
|
{
|
|
case 0:
|
|
|
|
if (Button->Released == false)
|
|
{
|
|
Button->FallingEdge = true;
|
|
}
|
|
|
|
Button->Pressed = false;
|
|
Button->Released = true;
|
|
break;
|
|
case 10:
|
|
|
|
if (Button->Pressed == false)
|
|
{
|
|
Button->RisingEdge = true;
|
|
}
|
|
|
|
Button->Pressed = true;
|
|
Button->Released = false;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
bool DS_ButtonPressed(DS_Button *Button)
|
|
{
|
|
if (Button->Pressed)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DS_ButtonReleased(DS_Button *Button)
|
|
{
|
|
if(Button->Released)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DS_Button_PressedLong(DS_Button *Button)
|
|
{
|
|
if(Button->PressedLong)
|
|
{
|
|
Button->PressedLong = false;
|
|
Button->PressStartTick = 0;
|
|
return true;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DS_ButtonRisingEdge(DS_Button *Button)
|
|
{
|
|
if (Button->RisingEdge)
|
|
{
|
|
Button->RisingEdge = false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DS_ButtonFallingEdge(DS_Button *Button)
|
|
{
|
|
if (Button->FallingEdge)
|
|
{
|
|
Button->FallingEdge = false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|