好用的按键代码

代码原型基于Siliconlabs EFR32MG Zigbee协议栈的button interface plugin进行优化。

优化后每个按键仅使用一个timer event就可以完成按键功能的实现,每个按键都需要一个timer event,以下源码默认可以支持4个按键的独立操作实现。

按键功能支持低电平、高电平、短按、长按、按住上电、连击、持续按下。

按键功能描述:

1、电平低回调(按键引脚电平变化为低时,已去抖,默认20ms);

WEAK(void w_HalButton_LowCallback(uint8_t buttonIndex))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推。

2、电平高回调(按键引脚电平变化为高时,已去抖,默认20ms);

WEAK(void w_HalButton_HighCallback(uint8_t buttonIndex))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推。

3、短按回调(默认按下到松开的时间小于1000ms为短按);

WEAK(void w_HalButton_PressedShortCallback(uint8_t buttonIndex, uint16_t pressedTime))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推;pressedTime为按下的时间,单位ms。

4、长按回调(默认按下到松开的时间大于等于于1000ms为长按);

WEAK(void w_HalButton_PressedLongCallback(uint8_t buttonIndex, uint16_t pressedTime))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推;pressedTime为按下的时间,单位ms。

5、开机上电按下回调(类似于长按,但仅在开机的条件下执行);

WEAK(void w_HalButton_PressedHoldPowerOnCallback(uint8_t buttonIndex, uint16_t pressedTime))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推;pressedTime为按下的时间,单位ms。

6、连击回调(默认两次短按时间间隔低于500ms为连击计数);

WEAK(void w_HalButton_ContinuousPressedShortCallback(uint8_t buttonIndex, uint8_t pressesNum))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推;pressesNum为连击的次数。

7、持续按下回调(持续按下超过1000ms后,每1000ms产生一个回调);

WEAK(uint8_t w_HalButton_PressingCallback(uint8_t buttonIndex, uint8_t pressingNum))

回调函数为弱函数的形式,使用者可以根据实际情况决定是否更改重写函数,buttonIndex为按键索引,0为第一个按键,以此类推;pressingNum为按下的默认时间1000ms的倍数。常用于长按超过n秒时执行某些动作,而不用等到按键松开后才知道是否需要执行某些动作;若是休眠设备是不需要长时间的保持按键状态扫描,可以设置长按n秒后返回0值,停止该按键的持续扫描定时事件。

例:(以下示例重写了w_HalButton_PressingCallback函数)

/******************************************************************************
 * Description : Button pressing callback.
 * Parameter   : @buttonIndex
 * 				@pressingNum
 * Return      : nContinue: 0 is stop, 1 is continue.
 *****************************************************************************/
uint8_t w_HalButton_PressingCallback(uint8_t buttonIndex, uint8_t pressingNum)
{
	uint8_t nContinue = 1;

	if (pressingNum >= 10)
	{
		nContinue = 0;
	}

	if (buttonIndex == 0)
	{
		//TODO: ……函数功能1……
	}
	else if (buttonIndex == 1)
	{
        //TODO: ……函数功能2……
        
		if (pressingNum >= 3)
		{
			nContinue = 0;
		}
	}
	else if (buttonIndex == 2)
	{
        //TODO: ……函数功能3……

		nContinue = 0;
	}

	return nContinue;
}

源码HalButton.c

/***********************************************************************************
* File        : HalButton.c
* Description : Hardware Button function.
* Author      : Chilli
* Date        : 2022.12.15
* Version     : 1.0.1
***********************************************************************************/


//==================================================================================
// Include head file
#include "app/framework/include/af.h"

#include "HalGPIO.h"
#include "HalButton.h"
//==================================================================================
// Macro definition
#if (DHB_BUTTON_NUMBER == 0)
void HalButton_Init(void)
{
	// None
}

WEAK(void w_HalButton_IsrHandle(uint8_t buttonIndex, uint8_t state))
{
	// None
}

WEAK(void w_HalButton_DebounceLowCallback(uint8_t buttonIndex))
{
	// None
}

WEAK(void w_HalButton_DebounceHighCallback(uint8_t buttonIndex))
{
	// None
}

WEAK(void w_HalButton_LowCallback(uint8_t buttonIndex))
{
	// None
}

WEAK(void w_HalButton_HighCallback(uint8_t buttonIndex))
{
	// None
}

WEAK(void w_HalButton_PressedShortCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	// None
}

WEAK(void w_HalButton_PressedLongCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	// None
}

WEAK(void w_HalButton_PressedHoldPowerOnCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	// None
}

WEAK(void w_HalButton_ContinuousPressedShortCallback(uint8_t buttonIndex, uint8_t pressesNum))
{
	// None
}

WEAK(uint8_t w_HalButton_PressingCallback(uint8_t buttonIndex, uint8_t pressingNum))
{
	// None
	return 0;
}
#else
//==================================================================================
// Variable declaration
//-----------------------------------------------------------------------------
// Enumeration
typedef enum {
	E_BUTTON_NONE = 0,
	E_BUTTON_LOW = 0,
	E_BUTTON_HIGH,
	E_BUTTON_PRE_RELEASE,
	E_BUTTON_RELEASED,
	E_BUTTON_PRE_PRESS,
	E_BUTTON_PRESSED,
	E_BUTTON_PRESSING,
	E_BUTTON_CONTINUOUS_PRESSES,
	E_BUTTON_PRESSED_SHORT,
	E_BUTTON_PRESSED_LONG,
	E_BUTTON_UNKNOWN,
} teButtonState;

//-----------------------------------------------------------------------------
// Structure
typedef struct {
	GPIO_Port_TypeDef	port;
	unsigned int		pin;
	uint8_t				mode;
	bool				dout;
	bool				polarity;
} tsButtonGpio;

typedef struct {
	uint8_t		u8InitState;
	uint8_t		u8LastState;
	uint8_t		u8NextState;
	uint8_t		u8PressingCount;
	uint8_t		u8ContinuousPressesCount;
	uint16_t	u16PressTime;
} tsButtonStatus;

//-----------------------------------------------------------------------------
// Local variable
EmberEventControl HalButton0EventControl;
EmberEventControl HalButton1EventControl;
EmberEventControl HalButton2EventControl;
EmberEventControl HalButton3EventControl;

static const tsButtonGpio sButtonGpio[DHB_BUTTON_NUMBER] = DHAL_BUTTON_INIT;
static tsButtonStatus sButtonStatus[DHB_BUTTON_NUMBER];

//==================================================================================
// Local function declaration
uint8_t halButton_PinIndex(uint8_t pin);
void halButton_IsrCallback(uint8_t pinIntNo);
uint32_t halButton_StatusHandle(uint8_t buttonIndex);

//==================================================================================
// Event function declaration
void HalButton0EventFunction(void);
void HalButton1EventFunction(void);
void HalButton2EventFunction(void);
void HalButton3EventFunction(void);

//==================================================================================
// Local function
/******************************************************************************
 * Description : Finds the Index of the pins in the sButtonGpio[] array.
 * Parameter   : @pin
 * Return      : @i - Pin index
 *****************************************************************************/
uint8_t halButton_PinIndex(uint8_t pin)
{
	uint8_t i;
	for (i = 0; i < DHAL_BUTTON_NUMBER; i++)
	{
		if (sButtonGpio[i].pin == pin)
		{
			break;
		}
	}
	return i;
}

/******************************************************************************
 * Description : Button interrupt ISR callback function.
 * Parameter   : @pinIntNo - Pin Interrupt number index
 * Return      : void
 *****************************************************************************/
void halButton_IsrCallback(uint8_t pinIntNo)
{
	uint8_t pinIntIndex = 0;
	uint8_t buttonStateCurrent = 0;

	pinIntIndex = halButton_PinIndex(pinIntNo);
	//HalButtonPrintln("halButton_IsrCallback pinIntIndex=%d", pinIntIndex);
	buttonStateCurrent = GPIO_PinInGet(sButtonGpio[pinIntIndex].port, sButtonGpio[pinIntIndex].pin);

#if (DHB_BUTTON_DEBOUNCE_COUNT > 0)
	uint8_t buttonStateLast = 0;
	uint32_t debounceCount = 0;
	for (debounceCount = 0; debounceCount < DHB_BUTTON_DEBOUNCE_COUNT; debounceCount++)
	{
		if (buttonStateCurrent != buttonStateLast)
		{
			debounceCount = 0;
		}
		buttonStateLast = buttonStateCurrent;
		buttonStateCurrent = GPIO_PinInGet(sButtonGpio[pinIntIndex].port, sButtonGpio[pinIntIndex].pin);
	}
#endif //(DHB_BUTTON_DEBOUNCE_COUNT > 0)

	w_HalButton_IsrHandle(pinIntIndex, buttonStateCurrent);
}

/******************************************************************************
 * Description : Button status handle function.
 * Parameter   : @buttonIndex
 * Return      : @nRetTimeMs - The event next running time
 *****************************************************************************/
uint32_t halButton_StatusHandle(uint8_t buttonIndex)
{
	uint8_t nButtonState = 0;
	uint16_t nPressedTime = 0;
	uint16_t nCurrentU16Tick = 0;
	uint32_t nCurrentU32Tick = 0;
	uint32_t nRetTimeMs = 0;

	if(buttonIndex >= DHAL_BUTTON_NUMBER)
	{
		return nRetTimeMs;
	}

	nCurrentU16Tick = halCommonGetInt16uMillisecondTick();
	nCurrentU32Tick = halCommonGetInt32uMillisecondTick();
	nButtonState = GPIO_PinInGet(sButtonGpio[buttonIndex].port, sButtonGpio[buttonIndex].pin);
	switch (sButtonStatus[buttonIndex].u8NextState)
	{
	case E_BUTTON_NONE:
		break;

	case E_BUTTON_PRE_RELEASE:
		if (sButtonGpio[buttonIndex].polarity == DHB_BUTTON_LOW_POLARITY)
		{
			if (nButtonState == DHB_BUTTON_HIGH_LEVEL)
			{
				if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_PRESSED)
				{
					w_HalButton_HighCallback(buttonIndex);
					sButtonStatus[buttonIndex].u8LastState = E_BUTTON_RELEASED;
					sButtonStatus[buttonIndex].u8NextState = E_BUTTON_NONE;
					// Negative overflow: For example 119 - 65470 = -65351 Convert uint16_t = 185
					nPressedTime = nCurrentU16Tick - sButtonStatus[buttonIndex].u16PressTime;
					if (nPressedTime <= DHB_BUTTON_PRESSED_SHORT_TIME_MS)
					{
						w_HalButton_PressedShortCallback(buttonIndex, nPressedTime);

						#if (DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS != 0)
							sButtonStatus[buttonIndex].u8ContinuousPressesCount++;
							sButtonStatus[buttonIndex].u8NextState = E_BUTTON_CONTINUOUS_PRESSES;
							nRetTimeMs = DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS;
						#endif
					}
					else
					{
						w_HalButton_PressedLongCallback(buttonIndex, nPressedTime);

						sButtonStatus[buttonIndex].u8ContinuousPressesCount = 0;
						if((nCurrentU32Tick <= DHB_BUTTON_PRESSED_POWER_ON_TIME_MS)
							&& (sButtonStatus[buttonIndex].u8InitState == DHB_BUTTON_LOW_POLARITY))
						{
							w_HalButton_PressedHoldPowerOnCallback(buttonIndex, nPressedTime);
						}
					}
					sButtonStatus[buttonIndex].u8InitState = E_BUTTON_UNKNOWN;
					sButtonStatus[buttonIndex].u8PressingCount = 0;
				}
			}
		}
		else // polarity == DHB_BUTTON_HIGH_POLARITY
		{
			if (nButtonState == DHB_BUTTON_LOW_LEVEL)
			{
				if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_PRESSED)
				{
					w_HalButton_LowCallback(buttonIndex);
					sButtonStatus[buttonIndex].u8LastState = E_BUTTON_RELEASED;
					sButtonStatus[buttonIndex].u8NextState = E_BUTTON_NONE;

					// Negative overflow: For example 119 - 65470 = -65351 Convert uint16_t = 185
					nPressedTime = nCurrentU16Tick - sButtonStatus[buttonIndex].u16PressTime;
					if (nPressedTime <= DHB_BUTTON_PRESSED_SHORT_TIME_MS)
					{
						w_HalButton_PressedShortCallback(buttonIndex, nPressedTime);

						#if (DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS != 0)
							sButtonStatus[buttonIndex].u8ContinuousPressesCount++;
							sButtonStatus[buttonIndex].u8NextState = E_BUTTON_CONTINUOUS_PRESSES;
							nRetTimeMs = DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS;
						#endif
					}
					else
					{
						w_HalButton_PressedLongCallback(buttonIndex, nPressedTime);

						sButtonStatus[buttonIndex].u8ContinuousPressesCount = 0;
						if((nCurrentU32Tick <= DHB_BUTTON_PRESSED_POWER_ON_TIME_MS)
							&& (sButtonStatus[buttonIndex].u8InitState == DHB_BUTTON_HIGH_POLARITY))
						{
							w_HalButton_PressedHoldPowerOnCallback(buttonIndex, nPressedTime);
						}
					}
					sButtonStatus[buttonIndex].u8InitState = E_BUTTON_UNKNOWN;
					sButtonStatus[buttonIndex].u8PressingCount = 0;
				}
			}
		}
		break;

	case E_BUTTON_PRE_PRESS:
		if (sButtonGpio[buttonIndex].polarity == DHB_BUTTON_LOW_POLARITY)
		{
			if (nButtonState == DHB_BUTTON_LOW_LEVEL)
			{
				if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_RELEASED)
				{
					w_HalButton_LowCallback(buttonIndex);
					sButtonStatus[buttonIndex].u8LastState = E_BUTTON_PRESSED;
					sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRESSING;
					sButtonStatus[buttonIndex].u16PressTime = nCurrentU16Tick;
					nRetTimeMs = DHB_BUTTON_PRESSING_TIME_MS;
				}
			}
		}
		else // polarity == DHB_BUTTON_HIGH_POLARITY
		{
			if (nButtonState == DHB_BUTTON_HIGH_LEVEL)
			{
				if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_RELEASED)
				{
					w_HalButton_HighCallback(buttonIndex);
					sButtonStatus[buttonIndex].u8LastState = E_BUTTON_PRESSED;
					sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRESSING;
					sButtonStatus[buttonIndex].u16PressTime = nCurrentU16Tick ;
					nRetTimeMs = DHB_BUTTON_PRESSING_TIME_MS;
				}
			}
		}
		break;

	case E_BUTTON_PRESSING:
		sButtonStatus[buttonIndex].u8PressingCount++;
		if (sButtonStatus[buttonIndex].u8PressingCount >= 255)
		{
			w_HalButton_PressingCallback(buttonIndex, sButtonStatus[buttonIndex].u8PressingCount);
			sButtonStatus[buttonIndex].u8PressingCount = 0;
			nRetTimeMs = 0;
		}
		else
		{
			if (w_HalButton_PressingCallback(buttonIndex, sButtonStatus[buttonIndex].u8PressingCount))
			{
				nRetTimeMs = DHB_BUTTON_PRESSING_TIME_MS;
			}
			else
			{
				nRetTimeMs = 0;
			}
		}

		#if (DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS != 0)
			if(sButtonStatus[buttonIndex].u8ContinuousPressesCount >= 2) // Press the key more than twice consecutively.
			{
				w_HalButton_ContinuousPressedShortCallback(buttonIndex, sButtonStatus[buttonIndex].u8ContinuousPressesCount);
			}
		#endif
		sButtonStatus[buttonIndex].u8ContinuousPressesCount = 0;
		break;

	case E_BUTTON_CONTINUOUS_PRESSES:
		#if (DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS != 0)
			if(sButtonStatus[buttonIndex].u8ContinuousPressesCount >= 2) // Press the key more than twice consecutively.
			{
				w_HalButton_ContinuousPressedShortCallback(buttonIndex, sButtonStatus[buttonIndex].u8ContinuousPressesCount);
			}
		#endif
		sButtonStatus[buttonIndex].u8NextState = E_BUTTON_NONE;
		sButtonStatus[buttonIndex].u8ContinuousPressesCount = 0;
		break;

	default:
		break;
	}

	return nRetTimeMs;
}



//==================================================================================
// Event function
/******************************************************************************
 * Description : Button0 event function.
 * Parameter   : void
 * Return      : void
 *****************************************************************************/
void HalButton0EventFunction(void)
{
	emberEventControlSetInactive(HalButton0EventControl);

#if (DHAL_BUTTON_NUMBER >= 1)
	uint32_t nNextTimeMs = halButton_StatusHandle(0);
	if (nNextTimeMs > 0)
	{
		emberEventControlSetDelayMS(HalButton0EventControl, nNextTimeMs);
	}
	//HalButtonPrintln("HalButton0EventFunction nNextTimeMs=%d", nNextTimeMs);
#endif // DHAL_BUTTON_NUMBER >= 1
}

/******************************************************************************
 * Description : Button1 event function.
 * Parameter   : void
 * Return      : void
 *****************************************************************************/
void HalButton1EventFunction(void)
{
	emberEventControlSetInactive(HalButton1EventControl);

#if (DHAL_BUTTON_NUMBER >= 2)
	uint32_t nNextTimeMs = halButton_StatusHandle(1);
	if (nNextTimeMs > 0)
	{
		emberEventControlSetDelayMS(HalButton1EventControl, nNextTimeMs);
	}
	//HalButtonPrintln("HalButton1EventFunction nNextTimeMs=%d", nNextTimeMs);
#endif // DHAL_BUTTON_NUMBER >= 2
}

/******************************************************************************
 * Description : Button2 event function.
 * Parameter   : void
 * Return      : void
 *****************************************************************************/
void HalButton2EventFunction(void)
{
	emberEventControlSetInactive(HalButton2EventControl);

#if (DHAL_BUTTON_NUMBER >= 3)
	uint32_t nNextTimeMs = halButton_StatusHandle(2);
	if (nNextTimeMs > 0)
	{
		emberEventControlSetDelayMS(HalButton2EventControl, nNextTimeMs);
	}
	//HalButtonPrintln("HalButton2EventFunction nNextTimeMs=%d", nNextTimeMs);
#endif // DHAL_BUTTON_NUMBER >= 3
}

/******************************************************************************
 * Description : Button3 event function.
 * Parameter   : void
 * Return      : void
 *****************************************************************************/
void HalButton3EventFunction(void)
{
	emberEventControlSetInactive(HalButton3EventControl);

#if (DHAL_BUTTON_NUMBER >= 4)
	uint32_t nNextTimeMs = halButton_StatusHandle(3);
	if (nNextTimeMs > 0)
	{
		emberEventControlSetDelayMS(HalButton3EventControl, nNextTimeMs);
	}
	//HalButtonPrintln("HalButton3EventFunction nNextTimeMs=%d", nNextTimeMs);
#endif // DHAL_BUTTON_NUMBER >= 4
}



//==================================================================================
// Extend function
/******************************************************************************
 * Description : Button Initialization.
 * Parameter   : void
 * Return      : void
 *****************************************************************************/
void HalButton_Init(void)
{
	// Initialize GPIO interrupt dispatcher
	GPIOINT_Init();

	// Enable GPIO in CMU
	#if !defined(_SILICON_LABS_32B_SERIES_2)
		CMU_ClockEnable(cmuClock_HFPER, true);
	#endif //!defined(_SILICON_LABS_32B_SERIES_2)
		CMU_ClockEnable(cmuClock_GPIO, true);

	for (uint8_t i = 0; i < DHB_BUTTON_NUMBER; i++)
	{
		// Configure pin as input
		GPIO_PinModeSet(sButtonGpio[i].port,
						sButtonGpio[i].pin,
						sButtonGpio[i].mode,
						sButtonGpio[i].dout);

		// Register callbacks before setting up and enabling pin interrupt.
		GPIOINT_CallbackRegister(sButtonGpio[i].pin, halButton_IsrCallback);

		// Set rising and falling edge interrupts
		GPIO_ExtIntConfig(sButtonGpio[i].port,
						sButtonGpio[i].pin,
						sButtonGpio[i].pin,
						true,
						true,
						true);
	}

	HalButtonPrintln("HalButton_Init ButtonNum=%d", DHB_BUTTON_NUMBER);

	for (uint8_t i = 0; i < DHB_BUTTON_NUMBER; i++)
	{
		sButtonStatus[i].u8LastState = E_BUTTON_RELEASED;
		sButtonStatus[i].u8NextState = E_BUTTON_NONE;
		sButtonStatus[i].u8PressingCount = 0;
		sButtonStatus[i].u8ContinuousPressesCount = 0;
		sButtonStatus[i].u16PressTime = 0;

		sButtonStatus[i].u8InitState = GPIO_PinInGet(sButtonGpio[i].port, sButtonGpio[i].pin);
		w_HalButton_IsrHandle(i, sButtonStatus[i].u8InitState);
	}
}

/******************************************************************************
 * Description : Button ISR handle.
 * Parameter   : @buttonIndex
 * 				@state - DHB_BUTTON_LOW_LEVEL or DHB_BUTTON_HIGH_LEVEL
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_IsrHandle(uint8_t buttonIndex, uint8_t state))
{
#if (DHAL_BUTTON_NUMBER > 0)
	if(buttonIndex >= DHAL_BUTTON_NUMBER)
	{
		return;
	}

	if (state == DHB_BUTTON_LOW_LEVEL)
	{
		w_HalButton_DebounceLowCallback(buttonIndex);
		if (sButtonGpio[buttonIndex].polarity == DHB_BUTTON_LOW_POLARITY)
		{
			sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRE_PRESS;
			if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_NONE)
			{
				sButtonStatus[buttonIndex].u8LastState = E_BUTTON_RELEASED;
			}
		}
		else // polarity == DHB_BUTTON_HIGH_POLARITY
		{
			sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRE_RELEASE;
			if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_NONE)
			{
				sButtonStatus[buttonIndex].u8LastState = E_BUTTON_PRESSED;
			}
		}
	}
	else // state == DHB_BUTTON_HIGH_LEVEL
	{
		w_HalButton_DebounceHighCallback(buttonIndex);
		if (sButtonGpio[buttonIndex].polarity == DHB_BUTTON_LOW_POLARITY)
		{
			sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRE_RELEASE;
			if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_NONE)
			{
				sButtonStatus[buttonIndex].u8LastState = E_BUTTON_PRESSED;
			}
		}
		else // polarity == DHB_BUTTON_HIGH_POLARITY
		{
			sButtonStatus[buttonIndex].u8NextState = E_BUTTON_PRE_PRESS;
			if (sButtonStatus[buttonIndex].u8LastState == E_BUTTON_NONE)
			{
				sButtonStatus[buttonIndex].u8LastState = E_BUTTON_RELEASED;
			}
		}
	}

	#if (DHAL_BUTTON_NUMBER >= 1)
		if (buttonIndex == 0)
		{
			emberEventControlSetDelayMS(HalButton0EventControl, DHB_BUTTON0_DEBOUNCE_TIME_MS);
		}
	#endif // DHAL_BUTTON_NUMBER >= 1

	#if (DHAL_BUTTON_NUMBER >= 2)
		if (buttonIndex == 1)
		{
			emberEventControlSetDelayMS(HalButton1EventControl, DHB_BUTTON1_DEBOUNCE_TIME_MS);
		}
	#endif // DHAL_BUTTON_NUMBER >= 2

	#if (DHAL_BUTTON_NUMBER >= 3)
		if (buttonIndex == 2)
		{
			emberEventControlSetDelayMS(HalButton2EventControl, DHB_BUTTON2_DEBOUNCE_TIME_MS);
		}
	#endif // DHAL_BUTTON_NUMBER >= 3


	#if (DHAL_BUTTON_NUMBER >= 4)
		if (buttonIndex == 3)
		{
			emberEventControlSetDelayMS(HalButton3EventControl, DHB_BUTTON3_DEBOUNCE_TIME_MS);
		}
	#endif // DHAL_BUTTON_NUMBER >= 4

#endif // DHAL_BUTTON_NUMBER > 0
}

/******************************************************************************
 * Description : Button debounce low callback.
 * Parameter   : @buttonIndex
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_DebounceLowCallback(uint8_t buttonIndex))
{
	//HalButtonPrintln("HB--w_HalButton_DebounceLowCallback buttonIndex=%d", buttonIndex);
}

/******************************************************************************
 * Description : Button debounce high callback.
 * Parameter   : @buttonIndex
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_DebounceHighCallback(uint8_t buttonIndex))
{
	//HalButtonPrintln("HB--w_HalButton_DebounceHighCallback buttonIndex=%d", buttonIndex);
}

/******************************************************************************
 * Description : Button low callback.
 * Parameter   : @buttonIndex
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_LowCallback(uint8_t buttonIndex))
{
	HalButtonPrintln("HB--w_HalButton_LowCallback buttonIndex=%d", buttonIndex);
}

/******************************************************************************
 * Description : Button high callback.
 * Parameter   : @buttonIndex
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_HighCallback(uint8_t buttonIndex))
{
	HalButtonPrintln("HB--w_HalButton_HighCallback buttonIndex=%d", buttonIndex);
}

/******************************************************************************
 * Description : Button pressed short callback.
 * Parameter   : @buttonIndex
 * 				@pressedTime - The time the button is pressed, unit milliseconds
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_PressedShortCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	HalButtonPrintln("HB--w_HalButton_PressedShortCallback buttonIndex=%d,pressedTime=%d", buttonIndex, pressedTime);
}

/******************************************************************************
 * Description : Button pressed long callback.
 * Parameter   : @buttonIndex
 * 				@pressedTime - The time the button is pressed, unit milliseconds
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_PressedLongCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	HalButtonPrintln("HB--w_HalButton_PressedLongCallback buttonIndex=%d,pressedTime=%d", buttonIndex, pressedTime);
}

/******************************************************************************
 * Description : Button pressed hold power on callback.
 * Parameter   : @buttonIndex
 * 				@pressedTime - The time the button is pressed, unit milliseconds
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_PressedHoldPowerOnCallback(uint8_t buttonIndex, uint16_t pressedTime))
{
	HalButtonPrintln("HB--w_HalButton_PressedHoldPowerOnCallback buttonIndex=%d,pressedTime=%d", buttonIndex, pressedTime);
}

/******************************************************************************
 * Description : Button continuous pressed short callback.
 * Parameter   : @buttonIndex
 * 				@pressesNum - Number of consecutive short button presses
 * Return      : void
 *****************************************************************************/
WEAK(void w_HalButton_ContinuousPressedShortCallback(uint8_t buttonIndex, uint8_t pressesNum))
{
	HalButtonPrintln("HB--w_HalButton_ContinuousPressedShortCallback buttonIndex=%d,pressesNum=%d", buttonIndex, pressesNum);
}

/******************************************************************************
 * Description : Button pressing callback.
 * Parameter   : @buttonIndex
 * 				@pressingNum
 * Return      : nContinue: 0 is stop, 1 is continue.
 *****************************************************************************/
WEAK(uint8_t w_HalButton_PressingCallback(uint8_t buttonIndex, uint8_t pressingNum))
{
	uint8_t nContinue = 1;
	HalButtonPrintln("HB--w_HalButton_PressingCallback buttonIndex=%d,pressingNum=%d", buttonIndex, pressingNum);
	return nContinue;
}
#endif // DHB_BUTTON_NUMBER

源码HalButton.h

/***********************************************************************************
* File        : HalButton.h
* Description : Hardware Button function.
* Author      : Chilli
* Date        : 2022.2.7
* Version     : 1.0.1
***********************************************************************************/
#ifndef HAL_BUTTON_H_
#define HAL_BUTTON_H_

//==================================================================================
// Include head file


//==================================================================================
// Macro definition
// DHB(Define Hal Button)
#ifndef DHB_BUTTON_CONFIG_METHODS
	#define DHB_BUTTON_CONFIG_METHODS						1			// Button Configuration Methods: 0 is SDK Plugin, 1 is User Config
#endif

#if defined(DHB_BUTTON_CONFIG_METHODS)
	#ifndef DHB_BUTTON0_DEBOUNCE_TIME_MS
		#define DHB_BUTTON0_DEBOUNCE_TIME_MS				20			// Button0 of Button debounce time, Units ms
	#endif

	#ifndef DHB_BUTTON1_DEBOUNCE_TIME_MS
		#define DHB_BUTTON1_DEBOUNCE_TIME_MS				20			// Button1 of Button debounce time, Units ms
	#endif

	#ifndef DHB_BUTTON2_DEBOUNCE_TIME_MS
		#define DHB_BUTTON2_DEBOUNCE_TIME_MS				20			// Button2 of Button debounce time, Units ms
	#endif

	#ifndef DHB_BUTTON3_DEBOUNCE_TIME_MS
		#define DHB_BUTTON3_DEBOUNCE_TIME_MS				20			// Button3 of Button debounce time, Units ms
	#endif

	#ifndef DHB_BUTTON_PRESSING_MAX_NUM
		#define DHB_BUTTON_PRESSING_MAX_NUM					20			// Button pressing max number
	#endif

	#ifndef DHB_BUTTON_PRESSING_TIME_MS
		#define DHB_BUTTON_PRESSING_TIME_MS					1000		// Button pressing timing interval, Units ms
	#endif

	#ifndef DHB_BUTTON_PRESSED_SHORT_TIME_MS
		#define DHB_BUTTON_PRESSED_SHORT_TIME_MS			1000		// Button short pressed time out, Units ms
	#endif

	#ifndef DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS
		#define DHB_BUTTON_CONTINUOUS_PRESSED_SHORT_TIME_MS	500		// Button continouns short pressed time out, Units ms
	#endif

	#ifndef DHB_BUTTON_PRESSED_POWER_ON_TIME_MS
		#define DHB_BUTTON_PRESSED_POWER_ON_TIME_MS			3000		// Button pressed power-on time, Units ms
	#endif

	#if (DHB_BUTTON_CONFIG_METHODS == 0)
		
	#elif (DHB_BUTTON_CONFIG_METHODS == 1)
		#define DHB_BUTTON_HIGH_LEVEL						1			// High level
		#define DHB_BUTTON_LOW_LEVEL						0			// Low level

		#define DHB_BUTTON_HIGH_POLARITY					1			// High polarity
		#define DHB_BUTTON_LOW_POLARITY						0			// Low polarity

		#ifndef DHB_BUTTON_NUMBER
			#define DHB_BUTTON_NUMBER						0			// Number of Button
		#endif

		#ifndef DHB_BUTTON_DEBOUNCE_COUNT
			#define DHB_BUTTON_DEBOUNCE_COUNT				5			// Button bebounce count times
		#endif
	#endif
#endif // DHB_BUTTON_CONFIG_METHODS




//==================================================================================
// Variable declaration
//-----------------------------------------------------------------------------
// Enumeration

//-----------------------------------------------------------------------------
// Structure

//-----------------------------------------------------------------------------
// Extend variable


//==================================================================================
// Extend function declaration
void HalButton_Init(void);

void w_HalButton_IsrHandle(uint8_t buttonIndex, uint8_t state);
void w_HalButton_DebounceLowCallback(uint8_t buttonIndex);
void w_HalButton_DebounceHighCallback(uint8_t buttonIndex);
void w_HalButton_LowCallback(uint8_t buttonIndex);
void w_HalButton_HighCallback(uint8_t buttonIndex);
void w_HalButton_PressedShortCallback(uint8_t buttonIndex, uint16_t pressedTime);
void w_HalButton_PressedLongCallback(uint8_t buttonIndex, uint16_t pressedTime);
void w_HalButton_PressedHoldPowerOnCallback(uint8_t buttonIndex, uint16_t pressedTime);
void w_HalButton_ContinuousPressedShortCallback(uint8_t buttonIndex, uint8_t pressesNum);
uint8_t w_HalButton_PressingCallback(uint8_t buttonIndex, uint8_t pressingNum);

#endif // HAL_BUTTON_H_




芯片引脚宏定义

// BUTTON >>>
#define DHAL_BUTTON_NUMBER							3			// Number of Button
#define DHB_BUTTON_NUMBER							DHAL_BUTTON_NUMBER

#if (DHAL_BUTTON_NUMBER >= 1)
	#if defined(CORTEXM3_EM3585)
	#elif defined(CORTEXM3_EFR32)
		#define DHAL_BUTTON0_PIN_INDEX				0
		#define DHAL_BUTTON0_PORT					(gpioPortF)
		#define DHAL_BUTTON0_PIN					(5U)
		#define DHAL_BUTTON0_PINS					PORTF_PIN(5)
		#define DHAL_BUTTON0_GPIO_MODE				gpioModeInput // gpioModeInput,gpioModeInputPull,gpioModeInputPullFilter
		#define DHAL_BUTTON0_GPIO_DOUT				1			// 0 is Low, 1 is High
		#define DHAL_BUTTON0_POLARITY				0			// 0 is Low active, 1 is High active
	#endif
#endif // DHAL_BUTTON_NUMBER >= 1

#if (DHAL_BUTTON_NUMBER >= 2)
	#if defined(CORTEXM3_EM3585)
	#elif defined(CORTEXM3_EFR32)
		#define DHAL_BUTTON1_PIN_INDEX				1
		#define DHAL_BUTTON1_PORT					(gpioPortD)
		#define DHAL_BUTTON1_PIN					(14U)
		#define DHAL_BUTTON1_PINS					PORTD_PIN(14)
		#define DHAL_BUTTON1_GPIO_MODE				gpioModeInput // gpioModeInput,gpioModeInputPull,gpioModeInputPullFilter
		#define DHAL_BUTTON1_GPIO_DOUT				1			// 0 is Low, 1 is High
		#define DHAL_BUTTON1_POLARITY				0			// 0 is Low active, 1 is High active
	#endif
#endif // DHAL_BUTTON_NUMBER >= 2

#if (DHAL_BUTTON_NUMBER >= 3)
	#if defined(CORTEXM3_EM3585)
	#elif defined(CORTEXM3_EFR32)
		#define DHAL_BUTTON2_PIN_INDEX				0
		#define DHAL_BUTTON2_PORT					(gpioPortF)
		#define DHAL_BUTTON2_PIN					(4U)
		#define DHAL_BUTTON2_PINS					PORTF_PIN(4)
		#define DHAL_BUTTON2_GPIO_MODE				gpioModeInput // gpioModeInput,gpioModeInputPull,gpioModeInputPullFilter
		#define DHAL_BUTTON2_GPIO_DOUT				1			// 0 is Low, 1 is High
		#define DHAL_BUTTON2_POLARITY				0			// 0 is Low active, 1 is High active
	#endif
#endif // DHAL_BUTTON_NUMBER >= 3

#if (DHAL_BUTTON_NUMBER >= 4)
	#if defined(CORTEXM3_EM3585)
	#elif defined(CORTEXM3_EFR32)
		#define DHAL_BUTTON3_PIN_INDEX				0
		#define DHAL_BUTTON3_PORT					(gpioPortA)
		#define DHAL_BUTTON3_PIN					(4U)
		#define DHAL_BUTTON3_PINS					PORTA_PIN(4)
		#define DHAL_BUTTON3_GPIO_MODE				gpioModeInput // gpioModeInput,gpioModeInputPull,gpioModeInputPullFilter
		#define DHAL_BUTTON3_GPIO_DOUT				1			// 0 is Low, 1 is High
		#define DHAL_BUTTON3_POLARITY				0			// 0 is Low active, 1 is High active
	#endif
#endif // DHAL_BUTTON_NUMBER >= 4

#if (DHAL_BUTTON_NUMBER == 1)
	#define DHAL_BUTTON_INIT						{{DHAL_BUTTON0_PORT, DHAL_BUTTON0_PIN, DHAL_BUTTON0_GPIO_MODE, DHAL_BUTTON0_GPIO_DOUT, DHAL_BUTTON0_POLARITY}}
#elif (DHAL_BUTTON_NUMBER == 2)
	#define DHAL_BUTTON_INIT						{{DHAL_BUTTON0_PORT, DHAL_BUTTON0_PIN, DHAL_BUTTON0_GPIO_MODE, DHAL_BUTTON0_GPIO_DOUT, DHAL_BUTTON0_POLARITY},\
													 {DHAL_BUTTON1_PORT, DHAL_BUTTON1_PIN, DHAL_BUTTON1_GPIO_MODE, DHAL_BUTTON1_GPIO_DOUT, DHAL_BUTTON1_POLARITY}}
#elif (DHAL_BUTTON_NUMBER == 3)
	#define DHAL_BUTTON_INIT						{{DHAL_BUTTON0_PORT, DHAL_BUTTON0_PIN, DHAL_BUTTON0_GPIO_MODE, DHAL_BUTTON0_GPIO_DOUT, DHAL_BUTTON0_POLARITY},\
													 {DHAL_BUTTON1_PORT, DHAL_BUTTON1_PIN, DHAL_BUTTON1_GPIO_MODE, DHAL_BUTTON1_GPIO_DOUT, DHAL_BUTTON1_POLARITY},\
													 {DHAL_BUTTON2_PORT, DHAL_BUTTON2_PIN, DHAL_BUTTON2_GPIO_MODE, DHAL_BUTTON2_GPIO_DOUT, DHAL_BUTTON2_POLARITY}}
#elif (DHAL_BUTTON_NUMBER == 4)
	#define DHAL_BUTTON_INIT						{{DHAL_BUTTON0_PORT, DHAL_BUTTON0_PIN, DHAL_BUTTON0_GPIO_MODE, DHAL_BUTTON0_GPIO_DOUT, DHAL_BUTTON0_POLARITY},\
													 {DHAL_BUTTON1_PORT, DHAL_BUTTON1_PIN, DHAL_BUTTON1_GPIO_MODE, DHAL_BUTTON1_GPIO_DOUT, DHAL_BUTTON1_POLARITY},\
													 {DHAL_BUTTON2_PORT, DHAL_BUTTON2_PIN, DHAL_BUTTON2_GPIO_MODE, DHAL_BUTTON2_GPIO_DOUT, DHAL_BUTTON2_POLARITY},\
													 {DHAL_BUTTON3_PORT, DHAL_BUTTON3_PIN, DHAL_BUTTON3_GPIO_MODE, DHAL_BUTTON3_GPIO_DOUT, DHAL_BUTTON3_POLARITY}}
#endif
// BUTTON <<<

Debug打印宏设置

// DUMA(Define User Main Application)
#define DUMA_PRINT_ENABLE
#ifdef DUMA_PRINT_ENABLE
	#define DebugPrintln(ENABLE, ...)							\
		if(ENABLE)												\
		{														\
			emberAfPrintln(EMBER_AF_PRINT_APP,  __VA_ARGS__);	\
		}	

	#define DebugBufferPrintln(ENABLE, buffer, len, withSpace)						\
		if(ENABLE)																	\
		{																			\
			emberAfPrint(EMBER_AF_PRINT_APP,  "[");									\
			emberAfPrintBuffer(EMBER_AF_PRINT_APP, (buffer), (len), (withSpace));	\
			emberAfPrint(EMBER_AF_PRINT_APP,  "]\r\n");								\
		}

	#define DebugBufferPrint(ENABLE, buffer, len, withSpace)						\
		if(ENABLE)																	\
		{																			\
			emberAfPrintBuffer(EMBER_AF_PRINT_APP, (buffer), (len), (withSpace));	\
		}
#else
	#define DebugPrintln(ENABLE, ...)
	#define DebugBufferPrintln(ENABLE, buffer, len, withSpace)
	#define DebugBufferPrint(ENABLE, buffer, len, withSpace)
#endif // DUMA_PRINT_ENABLE

//-------------------------------------------------------------------
// Debug print enable. 0 is disable, 1 is enable.
#define DUMA_PRINT_HAL_ADC_ENABLE							0
#define DUMA_PRINT_HAL_GPIO_ENABLE							0
#define DUMA_PRINT_HAL_BUTTON_ENABLE						1
#define DUMA_PRINT_HAL_LED_ENABLE							0
#define DUMA_PRINT_BUFFER_ENABLE							1

#define HalAdcPrintln(...)									DebugPrintln(DUMA_PRINT_HAL_ADC_ENABLE, __VA_ARGS__)
#define HalGpioPrintln(...)									DebugPrintln(DUMA_PRINT_HAL_GPIO_ENABLE, __VA_ARGS__)
#define HalButtonPrintln(...)								DebugPrintln(DUMA_PRINT_HAL_BUTTON_ENABLE, __VA_ARGS__)
#define HalLedPrintln(...)									DebugPrintln(DUMA_PRINT_HAL_LED_ENABLE, __VA_ARGS__)
#define UserBufferPrint(buffer, len, withSpace)				DebugBufferPrint(DUMA_PRINT_BUFFER_ENABLE, (buffer), (len), (withSpace))

注:

宏定义中支持的设置:

1、按键独立的去抖时间,默认20ms;

2、持续按下的最大次数,默认20次(应避免休眠设备长时间扫描按键状态);

3、持续按下的回调时间间隔,默认1000ms;

4、短按的超时时间,默认1000ms;

5、连击的时间间隔,默认500ms;

6、按键的数量设置,默认0,但Timer Event仍然需要配置;

7、按键引脚端口及极性;

其他抖动的高低电平回调函数仅用于调试验证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值