1、配置Sysick
#ifndef _SYSTICK_H__
#define _SYSTICK_H__
#include <stdint.h>
void SysitickInit(void);
void SysTick_Handler(void);
uint64_t GetSysRunTime(void);
#endif
#include <stdint.h>
#include "gd32f30x.h"
static volatile uint64_t g_sysRunTime = 0;
void SysitickInit(void)
{
if(SysTick_Config(rcu_clock_freq_get(CK_AHB)/ 1000))
{
while(1);
}
}
void SysTick_Handler(void)
{
g_sysRunTime++;
}
uint64_t GetSysRunTime(void)
{
return g_sysRunTime;
}
2、按键驱动源码
#include <stdint.h>
#include "gd32f30x.h"
#include "led_drv.h"
#include "systick.h"
typedef struct
{
rcu_periph_enum rcu;
uint32_t gpio;
uint32_t pin;
}Key_GPIO_t;
static Key_GPIO_t g_gpioList[]=
{
{RCU_GPIOA, GPIOA, GPIO_PIN_0},
{RCU_GPIOG, GPIOG, GPIO_PIN_13},
{RCU_GPIOG, GPIOG, GPIO_PIN_14}
};
#define KEY_NUM_MAX (sizeof(g_gpioList)/ sizeof(g_gpioList[0]))
void KeyDrvInit(void)
{
for(uint8_t i=0; i<KEY_NUM_MAX; i++)
{
rcu_periph_clock_enable(g_gpioList[i].rcu);
gpio_init(g_gpioList[i].gpio, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, g_gpioList[i].pin);
}
}
typedef enum
{
KEY_RELEASE = 0,
KEY_CONFIRM,
KEY_SHORTPRESS,
KEY_LONGPRESS
}KEY_STATE;
#define CONFIRM_TIME 10
#define LONGPRESS_TIME 1000
typedef struct
{
KEY_STATE keyState;
uint64_t prvSysTime;
}KEY_Info_t;
KEY_Info_t g_keyInfo[KEY_NUM_MAX];
static uint8_t KeyScan(uint8_t keyIndex)
{
volatile uint64_t curSysTime;
uint8_t keypress;
keypress = gpio_input_bit_get(g_gpioList[keyIndex].gpio, g_gpioList[keyIndex].pin);
switch(g_keyInfo[keyIndex].keyState)
{
case KEY_RELEASE:
if(!keypress)
{
g_keyInfo[keyIndex].keyState = KEY_CONFIRM;
g_keyInfo[keyIndex].prvSysTime = GetSysRunTime();
}
break;
case KEY_CONFIRM:
if(!keypress)
{
curSysTime = GetSysRunTime();
if(curSysTime - g_keyInfo[keyIndex].prvSysTime > CONFIRM_TIME)
{
g_keyInfo[keyIndex].keyState = KEY_SHORTPRESS;
}
}
else
{
g_keyInfo[keyIndex].keyState = KEY_RELEASE;
}
break;
case KEY_SHORTPRESS:
if(keypress)
{
g_keyInfo[keyIndex].keyState = KEY_RELEASE;
return (keyIndex + 0x01);
}
else
{
curSysTime = GetSysRunTime();
if(curSysTime - g_keyInfo[keyIndex].prvSysTime > LONGPRESS_TIME)
{
g_keyInfo[keyIndex].keyState = KEY_LONGPRESS;
}
}
break;
case KEY_LONGPRESS:
if(keypress)
{
g_keyInfo[keyIndex].keyState = KEY_RELEASE;
return (keyIndex + 0x81);
}
break;
default:
g_keyInfo[keyIndex].keyState = KEY_RELEASE;
break;
}
return 0;
}
uint8_t GetKeyVal(void)
{
uint8_t res = 0;
for(uint8_t i=0; i<KEY_NUM_MAX; i++)
{
res = KeyScan(i);
if(res != 0)
{
break;
}
}
return res;
}
3、main.c
#include <stdint.h>
#include "gd32f30x.h"
#include "key_drv.h"
#include "led_drv.h"
#include "systick.h"
int main(void)
{
uint8_t keyval;
LedDrvInit();
KeyDrvInit();
SysitickInit();
while (1)
{
keyval = GetKeyVal();
switch(keyval)
{
case KEY1_SHORT_PRESS:
TurnOnLed(LED1);
break;
case KEY1_LONG_PRESS:
TurnOffLed(LED1);
break;
case KEY2_SHORT_PRESS:
TurnOnLed(LED2);
break;
case KEY2_LONG_PRESS:
TurnOffLed(LED2);
break;
case KEY3_SHORT_PRESS:
TurnOnLed(LED3);
break;
case KEY3_LONG_PRESS:
TurnOffLed(LED3);
default:
break;
}
}
}
4、工程文件
链接: 基于systick中断进行按键消抖功能