代码拉取完成,页面将自动刷新
/************************************************************
* @brief button_drive
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0.1
* @note button.c
***********************************************************/
#include "button.h"
#ifdef PKG_USING_BUTTON
/*******************************************************************
* Variable Declaration
*******************************************************************/
static struct button* Head_Button = RT_NULL;
/*******************************************************************
* Function Declaration
*******************************************************************/
static char *StrnCopy(char *dst, const char *src, rt_uint32_t n);
static void Print_Btn_Info(Button_t* btn);
static void Add_Button(Button_t* btn);
/************************************************************
* @brief Create a Button
* @param name:button name
* @param btn:button structure
* @param read_btn_level:Button trigger level reading function,
* Return the level of the rt_uint8_t type by yourself
* @param btn_trigger_level:Button trigger level
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Button_Create(const char *name,
Button_t *btn,
rt_uint8_t(*read_btn_level)(void),
rt_uint8_t btn_trigger_level)
{
if( btn == RT_NULL)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("struct button is RT_NULL!"));
}
memset(btn, 0, sizeof(struct button)); //Clear structure information
StrnCopy(btn->Name, name, BTN_NAME_MAX); //button name
btn->Button_State = NONE_TRIGGER; //Button status
btn->Button_Last_State = NONE_TRIGGER; //Button last status
btn->Button_Trigger_Event = NONE_TRIGGER; //Button trigger event
btn->Read_Button_Level = read_btn_level; //Button trigger level reading function
btn->Button_Trigger_Level = btn_trigger_level; //Button trigger level
btn->Button_Last_Level = btn->Read_Button_Level(); //Button current level
btn->Debounce_Time = 0;
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button create success!"));
Add_Button(btn); //Added to the singly linked list when button created
Print_Btn_Info(btn); //printf info
}
/************************************************************
* @brief burron trigger events are attach to callback function
* @param btn:button structure
* @param btn_event:button events
* @param btn_callback : Callback handler after the button is triggered.Need user implementation
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
void Button_Attach(Button_t *btn,Button_Event btn_event,Button_CallBack btn_callback)
{
if( btn == RT_NULL)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("struct button is RT_NULL!"));
}
if(BUTTON_ALL_RIGGER == btn_event)
{
for(rt_uint8_t i = 0 ; i < number_of_event-1 ; i++)
/*A callback function triggered by a button event ,Used to handle button events */
btn->CallBack_Function[i] = btn_callback;
}
else
{
btn->CallBack_Function[btn_event] = btn_callback;
}
}
/************************************************************
* @brief Delete an already created button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Button_Delete(Button_t *btn)
{
struct button** curr;
for(curr = &Head_Button; *curr;)
{
struct button* entry = *curr;
if (entry == btn)
{
*curr = entry->Next;
}
else
{
curr = &entry->Next;
}
}
}
/************************************************************
* @brief Get Button Event Info
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
void Get_Button_EventInfo(Button_t *btn)
{
for(rt_uint8_t i = 0 ; i < number_of_event-1 ; i++)
{
if(btn->CallBack_Function[i] != 0)
{
/* print */
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Button_Event:%d",i));
}
}
}
/************************************************************
* @brief Get Button Event
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
rt_uint8_t Get_Button_Event(Button_t *btn)
{
return (rt_uint8_t)(btn->Button_Trigger_Event);
}
/************************************************************
* @brief Get Button State
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
rt_uint8_t Get_Button_State(Button_t *btn)
{
return (rt_uint8_t)(btn->Button_State);
}
/************************************************************
* @brief button cycle processing function
* @param btn:button structure
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note This function must be called in a certain period. The recommended period is 20~50ms.
***********************************************************/
void Button_Cycle_Process(Button_t *btn)
{
/* Get the current button level */
rt_uint8_t current_level = (rt_uint8_t)btn->Read_Button_Level();
/* Button level changes, debounce */
if((current_level != btn->Button_Last_Level)&&(++(btn->Debounce_Time) >= BUTTON_DEBOUNCE_TIME))
{
/* Update current button level */
btn->Button_Last_Level = current_level;
/* button is pressed */
btn->Debounce_Time = 0;
/* If the button is not pressed, change the button state to press (first press / double trigger) */
if((btn->Button_State == NONE_TRIGGER)||(btn->Button_State == BUTTON_DOUBLE))
{
btn->Button_State = BUTTON_DOWM;
}
//free button
else if(btn->Button_State == BUTTON_DOWM)
{
btn->Button_State = BUTTON_UP;
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button release"));
}
}
switch(btn->Button_State)
{
/* button dowm */
case BUTTON_DOWM :
{
if(btn->Button_Last_Level == btn->Button_Trigger_Level)
{
/* Support continuous triggering */
#ifdef CONTINUOS_TRIGGER
if(++(btn->Button_Cycle) >= BUTTON_CONTINUOS_CYCLE)
{
btn->Button_Cycle = 0;
btn->Button_Trigger_Event = BUTTON_CONTINUOS;
/* continuous triggering */
TRIGGER_CB(BUTTON_CONTINUOS);
RT_DEBUG_LOG(RT_DEBUG_THREAD,("continuous triggering"));
}
#else
btn->Button_Trigger_Event = BUTTON_DOWM;
/* Update the trigger event before releasing the button as long press */
if(++(btn->Long_Time) >= BUTTON_LONG_TIME)
{
#ifdef LONG_FREE_TRIGGER
btn->Button_Trigger_Event = BUTTON_LONG;
#else
/* Continuous triggering of long press cycles */
if(++(btn->Button_Cycle) >= BUTTON_LONG_CYCLE)
{
btn->Button_Cycle = 0;
btn->Button_Trigger_Event = BUTTON_LONG;
/* long triggering */
TRIGGER_CB(BUTTON_LONG);
}
#endif
/* Update time overflow */
if(btn->Long_Time == 0xFF)
{
btn->Long_Time = BUTTON_LONG_TIME;
}
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Long press"));
}
#endif
}
break;
}
/* button up */
case BUTTON_UP :
{
/* Trigger click */
if(btn->Button_Trigger_Event == BUTTON_DOWM)
{
/* double click */
if((btn->Timer_Count <= BUTTON_DOUBLE_TIME)&&(btn->Button_Last_State == BUTTON_DOUBLE))
{
btn->Button_Trigger_Event = BUTTON_DOUBLE;
TRIGGER_CB(BUTTON_DOUBLE);
RT_DEBUG_LOG(RT_DEBUG_THREAD,("double click"));
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = NONE_TRIGGER;
}
else
{
btn->Timer_Count=0;
/* Detection long press failed, clear 0 */
btn->Long_Time = 0;
#ifndef SINGLE_AND_DOUBLE_TRIGGER
/* click */
TRIGGER_CB(BUTTON_DOWM);
#endif
btn->Button_State = BUTTON_DOUBLE;
btn->Button_Last_State = BUTTON_DOUBLE;
}
}
else if(btn->Button_Trigger_Event == BUTTON_LONG)
{
#ifdef LONG_FREE_TRIGGER
/* Long press */
TRIGGER_CB(BUTTON_LONG);
#else
/* Long press free */
TRIGGER_CB(BUTTON_LONG_FREE);
#endif
btn->Long_Time = 0;
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_LONG;
}
#ifdef CONTINUOS_TRIGGER
/* Press continuously */
else if(btn->Button_Trigger_Event == BUTTON_CONTINUOS)
{
btn->Long_Time = 0;
/* Press continuously free */
TRIGGER_CB(BUTTON_CONTINUOS_FREE);
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_CONTINUOS;
}
#endif
break;
}
case BUTTON_DOUBLE :
{
/* Update time */
btn->Timer_Count++;
if(btn->Timer_Count>=BUTTON_DOUBLE_TIME)
{
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = NONE_TRIGGER;
}
#ifdef SINGLE_AND_DOUBLE_TRIGGER
if((btn->Timer_Count>=BUTTON_DOUBLE_TIME)&&(btn->Button_Last_State != BUTTON_DOWM))
{
btn->Timer_Count=0;
TRIGGER_CB(BUTTON_DOWM);
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_DOWM;
}
#endif
break;
}
default :
break;
}
}
/************************************************************
* @brief Traversing the way to scan the button without losing each button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note This function is called periodically, it is recommended to call 20-50ms once.
***********************************************************/
void Button_Process(void)
{
struct button* pass_btn;
for(pass_btn = Head_Button; pass_btn != RT_NULL; pass_btn = pass_btn->Next)
{
Button_Cycle_Process(pass_btn);
}
}
/************************************************************
* @brief Search Button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Search_Button(void)
{
struct button* pass_btn;
for(pass_btn = Head_Button; pass_btn != RT_NULL; pass_btn = pass_btn->Next)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button node have %s",pass_btn->Name));
}
}
/************************************************************
* @brief Handle all button callback functions
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note Not implemented yet
***********************************************************/
void Button_Process_CallBack(void *btn)
{
rt_uint8_t btn_event = Get_Button_Event(btn);
switch(btn_event)
{
case BUTTON_DOWM:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your press trigger"));
break;
}
case BUTTON_UP:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your trigger release"));
break;
}
case BUTTON_DOUBLE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your double-click trigger"));
break;
}
case BUTTON_LONG:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your long press trigger"));
break;
}
case BUTTON_LONG_FREE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your long press trigger free"));
break;
}
case BUTTON_CONTINUOS:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add your continuous trigger processing logic"));
break;
}
case BUTTON_CONTINUOS_FREE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your continuous trigger release"));
break;
}
}
}
/**************************** The following is the internal call function ********************/
/************************************************************
* @brief Copy the specified length string
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static char *StrnCopy(char *dst, const char *src, rt_uint32_t n)
{
if (n != 0)
{
char *d = dst;
const char *s = src;
do
{
if ((*d++ = *s++) == 0)
{
while (--n != 0)
*d++ = 0;
break;
}
} while (--n != 0);
}
return (dst);
}
/************************************************************
* @brief Print button related information
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static void Print_Btn_Info(Button_t* btn)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button struct information:\n\
btn->Name:%s \n\
btn->Button_State:%d \n\
btn->Button_Trigger_Event:%d \n\
btn->Button_Trigger_Level:%d \n\
btn->Button_Last_Level:%d \n\
",
btn->Name,
btn->Button_State,
btn->Button_Trigger_Event,
btn->Button_Trigger_Level,
btn->Button_Last_Level));
Search_Button();
}
/************************************************************
* @brief Connect buttons with a single linked list
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static void Add_Button(Button_t* btn)
{
struct button *pass_btn = Head_Button;
while(pass_btn)
{
pass_btn = pass_btn->Next;
}
btn->Next = Head_Button;
Head_Button = btn;
}
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。