经典代码分享

经典代码分享

所见即所得Web可视化编程开发板源程序分享

回复

经验分享现场总线/以太网/modbus开 发起了问题 • 1 人关注 • 0 个回复 • 92 次浏览 • 2019-10-05 11:19 • 来自相关话题

(分享)经典的按键程序,用状态机写的,支持长按双按等

经验分享admin 发表了文章 • 2 个评论 • 3010 次浏览 • 2014-10-16 14:08 • 来自相关话题

转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif 查看全部
转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif





AD采集中经常要用到数字滤波,不同情况下又有不同的滤波需求,分享下10种经典的软件滤波程序

经验分享admin 发表了文章 • 1 个评论 • 1572 次浏览 • 2014-10-15 22:39 • 来自相关话题

1、限幅滤波法(又称程序判断滤波法)
2、中位值滤波法
3、算术平均滤波法
4、递推平均滤波法(又称滑动平均滤波法)
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
6、限幅平均滤波法
7、一阶滞后滤波法
8、加权递推平均滤波法
9、消抖滤波法
10、限幅消抖滤波法
一\限副滤波

A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A)
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制那种周期性的干扰
平滑度差

程序:


/* A值可根据实际情况调整
value为有效值,new_value为当前采样值
滤波程序返回有效的实际值 */

#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A ) )
return value;
else
return new_value;
}


二\中位值滤波法
A、方法:
连续采样N次(N取奇数),把N次采样值按大小排列 ,取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
程序:


/* N值可根据实际情况调整
排序采用冒泡法*/
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j-1;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
} 查看全部
1、限幅滤波法(又称程序判断滤波法)
2、中位值滤波法
3、算术平均滤波法
4、递推平均滤波法(又称滑动平均滤波法)
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
6、限幅平均滤波法
7、一阶滞后滤波法
8、加权递推平均滤波法
9、消抖滤波法
10、限幅消抖滤波法
一\限副滤波

A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A)
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制那种周期性的干扰
平滑度差

程序:


/* A值可根据实际情况调整
value为有效值,new_value为当前采样值
滤波程序返回有效的实际值 */

#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A ) )
return value;
else
return new_value;
}


二\中位值滤波法
A、方法:
连续采样N次(N取奇数),把N次采样值按大小排列 ,取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
程序:


/* N值可根据实际情况调整
排序采用冒泡法*/
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j-1;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}

所见即所得Web可视化编程开发板源程序分享

回复

经验分享现场总线/以太网/modbus开 发起了问题 • 1 人关注 • 0 个回复 • 92 次浏览 • 2019-10-05 11:19 • 来自相关话题

(分享)经典的按键程序,用状态机写的,支持长按双按等

经验分享admin 发表了文章 • 2 个评论 • 3010 次浏览 • 2014-10-16 14:08 • 来自相关话题

转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif 查看全部
转自阿莫论坛,感谢AbnerSmith提供.
支持短按、长按、双短按、短长按以及多按键同时按下的按键程序,用状态机写的,和大家分享一下。

按键的头文件在下方


/**********************************************************************************************
* File Name : bsp_key.c
* Required Perconditions :
* Called Functions : TIM_IsExpired(),TIM_GetTimestamp()
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
* KeyValue : [15..13]->KeyState,[12..9]->Reserved,[8..3]->KeyID,[2..0]->KeyEvent
* KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007,
* bsp_timer.h and bsp_key.h ought to be included
* Call Key_Init() before Key_GetValue()
*
*
* <------ Add to Group BSP/HAL/SRC ------->
* ===========================================================================================
* @updated
* 1.Deleted some Key_State
* 2.Add the Current KeyState(KEY_STATE_INIT or KEY_STATE_UNRELEASED) to rtnval
* 3.Replace defines for KeyEventime(in bsp_key.h) with Function(Key_SetEventTime)
* 4.Define KEY_x_EffectiveLevel in header_file to make it convenient to modify it
* so it can apply to other boards.
* 5.Support 6 Independent_Keys(Max upto 10,but need modify Key_Init() & Key_GetID())
* 6.MultiKeyID were Deleted
* 7.Fix bug : When you release other key during MultiPressed state,return KeyID won't
* reflect this changes.
*
*********************************************************************************************/

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "bsp_key.h"
#include "bsp_timer.h"


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/



/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 KeyTime_Jitter = 5 ; //Time for excluding Jiteter interference
static u32 KeyTime_Interval = 400 ; //Time for confirming status had swtiched
static u32 KeyTime_Long = 800 ; //Time for confirming long pressed
static u32 KeyTime_Double = 300 ; //Time between double pressed

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Key_Init()
*
* Description : Initialize GPIO Pin,Speed,Mode for Key.
*
* Argument(s) : None.
*
* Return(s) : None.
*
* Note(s) : (1) Key's GPIO(Pin,Speed,Mode) is defined in the bsp_key.h.
*********************************************************************************************************
*/

void
Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

#if (KEY_SUPPORTNUM > 0)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_0_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_0_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_0_GPIO_Mode;
GPIO_Init (KEY_0_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 1)
RCC_APB2PeriphClockCmd (KEY_1_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_1_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_1_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_1_GPIO_Mode;
GPIO_Init (KEY_1_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 2)
RCC_APB2PeriphClockCmd (KEY_2_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_2_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_2_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_2_GPIO_Mode;
GPIO_Init (KEY_2_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 3)
RCC_APB2PeriphClockCmd (KEY_3_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_3_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_3_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_3_GPIO_Mode;
GPIO_Init (KEY_3_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 4)
RCC_APB2PeriphClockCmd (KEY_4_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_4_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_4_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_4_GPIO_Mode;
GPIO_Init (KEY_4_GPIO_Port,&GPIO_InitStructure );

#endif

#if (KEY_SUPPORTNUM > 5)
RCC_APB2PeriphClockCmd (KEY_0_GPIO_RCC_Periph ,ENABLE );

GPIO_InitStructure .GPIO_Pin = KEY_5_GPIO_Pin ;
GPIO_InitStructure .GPIO_Speed = KEY_5_GPIO_Speed ;
GPIO_InitStructure .GPIO_Mode = KEY_5_GPIO_Mode ;
GPIO_Init (KEY_5_GPIO_Port,&GPIO_InitStructure );

#endif
}


/*
*********************************************************************************************************
* Key_GetID()
*
* Description : Get pressed Key(s)'(s) ID(s).
*
* Argument(s) : None.
*
* Return(s) : Pressed Key(s)'(s) ID(s).
*
* Note(s) : (1) Key's EffectiveLevel is defined in the bsp_key.h.
*********************************************************************************************************
*/

KeyID_Enum_t
Key_GetID(void)
{
KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)
if(GPIO_ReadInputDataBit (KEY_0_GPIO_Port ,KEY_0_GPIO_Pin ) == KEY_0_EffectiveLevel)
KeyIDTmp |= KEY_ID_0;
#endif

#if (KEY_SUPPORTNUM > 1)
if(GPIO_ReadInputDataBit (KEY_1_GPIO_Port ,KEY_1_GPIO_Pin ) == KEY_1_EffectiveLevel)
KeyIDTmp |= KEY_ID_1;
#endif

#if (KEY_SUPPORTNUM > 2)
if(GPIO_ReadInputDataBit (KEY_2_GPIO_Port ,KEY_2_GPIO_Pin ) == KEY_2_EffectiveLevel)
KeyIDTmp |= KEY_ID_2;
#endif

#if (KEY_SUPPORTNUM > 3)
if(GPIO_ReadInputDataBit (KEY_3_GPIO_Port ,KEY_3_GPIO_Pin ) == KEY_3_EffectiveLevel)
KeyIDTmp |= KEY_ID_3;
#endif

#if (KEY_SUPPORTNUM > 4)
if(GPIO_ReadInputDataBit (KEY_4_GPIO_Port ,KEY_4_GPIO_Pin ) == KEY_4_EffectiveLevel)
KeyIDTmp |= KEY_ID_4;
#endif

#if (KEY_SUPPORTNUM > 5)
if(GPIO_ReadInputDataBit (KEY_5_GPIO_Port ,KEY_5_GPIO_Pin ) == KEY_5_EffectiveLevel)
KeyIDTmp |= KEY_ID_5;
#endif

return KeyIDTmp;
}


/*
*********************************************************************************************************
* Key_GetValue()
*
* Description : Get pressed Key's ID,and the first event key's event and status.
*
* Argument(s) : None.
*
* Return(s) : @ Description.
*
* Note(s) : (1) wait to update to support for getting each key's event and status independently.
* (2) KeyState = keyval & 0xE000,KeyID = keyval & 0x01F8,KeyEvent = keyval & 0x0007.
* (3) the time for Jitter and others is based on set Timestamp period to 1 ms (@bsp_timer)
*********************************************************************************************************
*/

u16
Key_GetValue(void)
{
static KeyAction_Struct_t KeyAction = {KEY_ID_NONE ,KEY_STATE_INIT ,KEY_EVENT_NONE ,0,0,0};
static u16 KeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE;

static KeyID_Enum_t KeyIDTmp = KEY_ID_NONE ;

static u16 LastKeyValue = KEY_STATE_INIT | KEY_ID_NONE | KEY_EVENT_NONE ;

KeyAction .KeyID = Key_GetID() ;

switch(KeyAction .KeyState )
{
case KEY_STATE_INIT :
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_JITTER ;
KeyAction .KeyJitterTime = TIM_GetSTime ();
}
}break;

case KEY_STATE_JITTER :
{
if(TIM_IsExpired (KeyAction .KeyJitterTime + KeyTime_Jitter ))
{
if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyState = KEY_STATE_PRESSED ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
}
else
{
KeyAction .KeyID = KEY_ID_NONE ;
KeyAction .KeyState = KEY_STATE_INIT ;
}
}
}break;

case KEY_STATE_PRESSED :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INTERIM1 ;
KeyAction .KeyReleasedTime = TIM_GetSTime ();
}

if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ) )
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
}
LastKeyValue = KeyAction .KeyState | KeyIDTmp | KEY_EVENT_LONG ;

return LastKeyValue ;
}
}break;

case KEY_STATE_INTERIM1 :
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Interval ))
{
KeyAction .KeyState = KEY_STATE_JITTER ;
}

if(KeyAction .KeyID != KEY_ID_NONE )
{
KeyIDTmp = KeyAction .KeyID ;
KeyAction .KeyPressedTime = TIM_GetSTime ();
KeyAction .KeyState = KEY_STATE_INTERIM2 ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyReleasedTime + KeyTime_Double ))
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_SHORT ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_INTERIM2 :
{
if(KeyAction .KeyID == KEY_ID_NONE )
{
KeyAction .KeyState = KEY_STATE_INIT ;
LastKeyValue = KEY_STATE_INIT | KeyIDTmp | KEY_EVENT_DOUBLESHORT ;
return LastKeyValue ;
}
else
{
if(TIM_IsExpired (KeyAction .KeyPressedTime + KeyTime_Long ))
{
KeyAction .KeyState = KEY_STATE_UNRELEASED ;
LastKeyValue = KEY_STATE_UNRELEASED | KeyIDTmp | KEY_EVENT_SHORTLONG ;
return LastKeyValue ;
}
}
}break;

case KEY_STATE_UNRELEASED :
{
if(KeyAction .KeyID == KEY_ID_NONE)
{
KeyAction .KeyState = KEY_STATE_INIT ;
}
else
{
KeyIDTmp = KeyAction .KeyID ;
return KEY_STATE_UNRELEASED | KeyIDTmp | (LastKeyValue & 0x0007 ) ;
}
}break;

default :
break;
}

return KeyValue ;
}


/**********************************************************************************************
* Function Name : Key_SetEventTime
* Function Prototype : void Key_SetEventTime(u32 NewKeyTime_Jitter ,
* u32 NewKeyTime_Interval ,
* u32 NewKeyTime_Long ,
* u32 NewKeyTime_Double )
* Behavior Description : Set KeyTime_Jitter,KeyTime_Interval,KeyTime_Long,Time_Double
* Input Parameter : NewKeyTime_Jitter,NewKeyTime_Interval,
* NewKeyTime_Long,NewTime_Double
*
* Output Parameter : None
* Return Parameter : None
* Required Perconditions : None
* Called Functions : None
*
* ===========================================================================================
* @ attention
*
*
*
*
*********************************************************************************************/

/*
*********************************************************************************************************
* Key_SetEventTime(KeyTime_Jitter,...)
*
* Description : Set JitterTimer, IntervalTime, LongTime, and DoubleTime.
*
* Argument(s) : NewKeyTime_Jitter,NewKeyTime_Interval,NewKeyTime_Long,NewKeyTime_Double.
*
* Return(s) : None.
*
* Note(s) : (1) you'd better not to call this function
*********************************************************************************************************
*/

void Key_SetEventTime(u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double )
{
KeyTime_Jitter = NewKeyTime_Jitter ;
KeyTime_Interval = NewKeyTime_Interval ;
KeyTime_Long = NewKeyTime_Long ;
KeyTime_Double = NewKeyTime_Double ;
}




/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

static u32 Timestamp ;

/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Block : Timestamp
* Block Description : TIM7 configured to provide functions TIM_GetSTime() and TIM_IsExpired()
*
* ======================================================================================================
* @ attention
* Recommend Counter frequency is 1kHz ,period is 1mS.
*
*
*********************************************************************************************************
*/

void
TIM_Stamp_Init(u16 arr,u16 psc)//recommend : arr = 719 ,psc = 99 --> 1mS
{
NVIC_InitTypeDef NVIC_InitStructure ;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;

RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7 ,ENABLE );

TIM_TimeBaseStructure .TIM_Period = arr ;
TIM_TimeBaseStructure .TIM_Prescaler = psc ;
TIM_TimeBaseStructure .TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure .TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit (TIM7 ,&TIM_TimeBaseStructure );

NVIC_InitStructure .NVIC_IRQChannel = TIM7_IRQn ;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority = 1 ;
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (&NVIC_InitStructure );

TIM_ITConfig (TIM7 ,TIM_IT_Update ,ENABLE );
TIM_Cmd (TIM7 ,ENABLE );
}

u32
TIM_GetSTime(void)
{
return Timestamp ;
}

u8
TIM_IsExpired(u32 PeriodBased)
{
u32 time_now = Timestamp ;

if(time_now > PeriodBased )
{
if((time_now - PeriodBased ) < 0x80000000)
return 1;
else
return 0;
}
else
{
if((PeriodBased - time_now ) > 0x80000000)
return 1;
else
return 0;
}
}

void
TIM7_IRQHandler(void)
{
Timestamp ++ ;
TIM_ClearITPendingBit (TIM7,TIM_IT_Update );
}




/**********************************************************************************************
* File Name : bsp_key.h
* Required Perconditions :
* Called Functions :
* Author : Abner
* Created : 02/09/2014
* Updated : 28/09/2014
*
* ===========================================================================================
* @attention
*
*
*
* <------ Add to Group BSP/HAL/INC ------->
* ===========================================================================================
* @updated
*
*
*
*********************************************************************************************/

#ifndef _BSP_KEY_H
#define _BSP_KEY_H

/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/

#include "stm32f10x_conf.h"


/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/

//KEY_SUPPORTNUM : Defualt->4,Max->6
//Support upto 10,but need modify bsp_key.c
#define KEY_SUPPORTNUM (4)

#if KEY_SUPPORTNUM > 6
#error "Max support keys is six"
#endif

/*
*********************************************************************************************************
* Block : hardware define
* Block Description : define GPIO_Port,GPIO_Pin,GPIO_RCC_Periph,GPIO_Mode for each Key
*
* =======================================================================================================
* @ attention
* It's of importance for modify GPIO_Mode after (GPIO_Port,GPIO_Pin,GPIO_RCC_Periph)
* for GPIOA to GPIOG , GPIO_RCC_Periph is always RCC_APB2Periph_GPIOx(x coulde be A to G)
*
*********************************************************************************************************
*/

/*
#define KEY_UP KEY_0
#define KEY_DOWN KEY_1
#define KEY_LEFT KEY_2
#define KEY_RIGHT KEY_3
#define KEY_ENTER KEY_5
#define KEY_ESC KEY_6
*/

#if (KEY_SUPPORTNUM > 0)&&(USE_WKUP_PA0 == 0)

#define KEY_0_GPIO_Port GPIOA
#define KEY_0_GPIO_Pin GPIO_Pin_0
#define KEY_0_GPIO_RCC_Periph RCC_APB2Periph_GPIOA
#define KEY_0_GPIO_Speed GPIO_Speed_50MHz

#define KEY_0_GPIO_Mode GPIO_Mode_IPD
#define KEY_0_EffectiveLevel 1

#endif

#if (KEY_SUPPORTNUM > 1)

#define KEY_1_GPIO_Port GPIOE
#define KEY_1_GPIO_Pin GPIO_Pin_3
#define KEY_1_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_Speed GPIO_Speed_50MHz

#define KEY_1_GPIO_Mode GPIO_Mode_IPU
#define KEY_1_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 2)

#define KEY_2_GPIO_Port GPIOE
#define KEY_2_GPIO_Pin GPIO_Pin_2
#define KEY_2_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_2_GPIO_Speed GPIO_Speed_50MHz

#define KEY_2_GPIO_Mode GPIO_Mode_IPU
#define KEY_2_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 3)

#define KEY_3_GPIO_Port GPIOE
#define KEY_3_GPIO_Pin GPIO_Pin_4
#define KEY_3_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_3_GPIO_Speed GPIO_Speed_50MHz

#define KEY_3_GPIO_Mode GPIO_Mode_IPU
#define KEY_3_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 4)

#define KEY_4_GPIO_Port GPIOE
#define KEY_4_GPIO_Pin GPIO_Pin_4
#define KEY_4_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_4_GPIO_Speed GPIO_Speed_50MHz

#define KEY_4_GPIO_Mode GPIO_Mode_IPU
#define KEY_4_EffectiveLevel 0

#endif

#if (KEY_SUPPORTNUM > 5)

#define KEY_5_GPIO_Port GPIOE
#define KEY_5_GPIO_Pin GPIO_Pin_4
#define KEY_5_GPIO_RCC_Periph RCC_APB2Periph_GPIOE
#define KEY_5_GPIO_Speed GPIO_Speed_50MHz

#define KEY_5_GPIO_Mode GPIO_Mode_IPU
#define KEY_5_EffectiveLevel 0

#endif


/*
*********************************************************************************************************
* TYPE DEFINES
*********************************************************************************************************
*/

typedef enum {
KEY_ID_NONE = 0x0000,

KEY_ID_0 = 0x0008,
KEY_ID_1 = 0x0010,
KEY_ID_2 = 0x0020,
KEY_ID_3 = 0x0040,
KEY_ID_4 = 0x0080,
KEY_ID_5 = 0x0100,

KEY_ID_Multi ,

}KeyID_Enum_t;

typedef enum {
KEY_STATE_INIT = 0x0000,
KEY_STATE_JITTER = 0x2000,
KEY_STATE_PRESSED = 0x4000,
KEY_STATE_INTERIM1 = 0x6000,
KEY_STATE_INTERIM2 = 0x8000,
KEY_STATE_UNRELEASED = 0xA000,

}KeyState_Enum_t;

typedef enum {
KEY_EVENT_NONE = 0x0000,
KEY_EVENT_SHORT = 0x0001,
KEY_EVENT_LONG = 0x0002,
KEY_EVENT_DOUBLESHORT = 0x0003,
KEY_EVENT_SHORTLONG = 0x0004,

}KeyEvent_Enum_t;

typedef struct {
KeyID_Enum_t KeyID;
KeyState_Enum_t KeyState;
KeyEvent_Enum_t KeyEvent;
u32 KeyJitterTime;
u32 KeyPressedTime;
u32 KeyReleasedTime;

}KeyAction_Struct_t;


/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void Key_Init (void);
KeyID_Enum_t Key_GetID (void);
u16 Key_GetValue (void);

void Key_SetEventTime ( u32 NewKeyTime_Jitter ,
u32 NewKeyTime_Interval ,
u32 NewKeyTime_Long ,
u32 NewKeyTime_Double ) ;

#endif





AD采集中经常要用到数字滤波,不同情况下又有不同的滤波需求,分享下10种经典的软件滤波程序

经验分享admin 发表了文章 • 1 个评论 • 1572 次浏览 • 2014-10-15 22:39 • 来自相关话题

1、限幅滤波法(又称程序判断滤波法)
2、中位值滤波法
3、算术平均滤波法
4、递推平均滤波法(又称滑动平均滤波法)
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
6、限幅平均滤波法
7、一阶滞后滤波法
8、加权递推平均滤波法
9、消抖滤波法
10、限幅消抖滤波法
一\限副滤波

A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A)
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制那种周期性的干扰
平滑度差

程序:


/* A值可根据实际情况调整
value为有效值,new_value为当前采样值
滤波程序返回有效的实际值 */

#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A ) )
return value;
else
return new_value;
}


二\中位值滤波法
A、方法:
连续采样N次(N取奇数),把N次采样值按大小排列 ,取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
程序:


/* N值可根据实际情况调整
排序采用冒泡法*/
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j-1;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
} 查看全部
1、限幅滤波法(又称程序判断滤波法)
2、中位值滤波法
3、算术平均滤波法
4、递推平均滤波法(又称滑动平均滤波法)
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
6、限幅平均滤波法
7、一阶滞后滤波法
8、加权递推平均滤波法
9、消抖滤波法
10、限幅消抖滤波法
一\限副滤波

A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A)
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制那种周期性的干扰
平滑度差

程序:


/* A值可根据实际情况调整
value为有效值,new_value为当前采样值
滤波程序返回有效的实际值 */

#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A ) )
return value;
else
return new_value;
}


二\中位值滤波法
A、方法:
连续采样N次(N取奇数),把N次采样值按大小排列 ,取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
程序:


/* N值可根据实际情况调整
排序采用冒泡法*/
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j-1;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}