外部中断按键 面向对象封装 hal库

#ifndef _KEY_H
#define _KEY_H

#include "main.h"
#include "FreeRTOS.h"
#include "queue.h"


typedef enum 					//按键状态
{
	KEY_STATE_IDLE=0,			//初始状态
	KEY_STATE_PRESSED,			//按下状态

}Key_STATE_t;

typedef struct {
	uint32_t KEY_SystemTICK;	//系统时间
	uint32_t KEY_TICK1;			//按下时间
	uint32_t KEY_TICK2;			//抬起时间

    Key_STATE_t state;	        //状态值
	uint8_t key_short_value;	//短按值
	uint8_t key_long_value;	    //长按值
	uint8_t key_value;			//返回值
} KeyState_t;

extern KeyState_t *Key_board;
extern KeyState_t	KEY_Value;
extern QueueHandle_t g_xQueueKey;


void Key_Test(void *argument);
#endif

#include "stm32f4xx_hal.h"
#include "key.h"
#include "led.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

KeyState_t Keys[1] = {
    {
        .KEY_TICK1 = 0,
        .KEY_TICK2 = 0,
        .state = KEY_STATE_IDLE,
        .key_short_value = 1,
        .key_long_value = 2,
        .key_value = 0,
    }
};

KeyState_t *Key_board = &Keys[0];


#if 0
static uint8_t Key_Init(void)
{
    //This section is generated by Cube
    return 0;
}
#endif

uint8_t Key_Parse(KeyState_t *KeyState)
{
	uint32_t KEY_TICK=KeyState->KEY_TICK2-KeyState->KEY_TICK1;
	
	if(KEY_TICK<=100)
	{
		return 0;
	}
	else if(KEY_TICK>100&&KEY_TICK<=1000)
	{
		return KeyState->key_short_value;
	}
	else if(KEY_TICK>1000&&KEY_TICK<=2000)
	{
		return KeyState->key_long_value;
	}
	return 0;
}


KeyState_t	KEY_Value;
QueueHandle_t g_xQueueKey; /* 按键队列 */
void Key_Test(void *argument)
{
    while (1)
    {
		if(g_xQueueKey!=NULL)			//创建队列成功
		{
			if(xQueueReceive(g_xQueueKey, &KEY_Value, portMAX_DELAY) == pdTRUE)
			{
				Led_value=Key_Parse(&KEY_Value);
				xQueueSendToBack(g_xQueueLed,&Led_value,portMAX_DELAY);
			}
		}
		vTaskDelay(10);
    }
}

/* USER CODE BEGIN 4 */
void Key_Detect(KeyState_t *KeyState)
{
    static BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    KeyState->KEY_SystemTICK=HAL_GetTick();
    
    if(KEY_STATE_IDLE==Key_board->state)
    {
      KeyState->KEY_TICK1=KeyState->KEY_SystemTICK;

      GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
      
      Key_board->state=KEY_STATE_PRESSED;
    }
    else if (KEY_STATE_PRESSED==Key_board->state)
    {
      KeyState->KEY_TICK2=KeyState->KEY_SystemTICK;
      
      GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
      
      Key_board->state=KEY_STATE_IDLE;
	
      if (xQueueSendToBackFromISR(g_xQueueKey,KeyState,&xHigherPriorityTaskWoken) != pdTRUE) 
      {
		  
      }

      portYIELD_FROM_ISR(xHigherPriorityTaskWoken); 
    }

    GPIO_InitStruct.Pin = KEY_Pin;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY_GPIO_Port, &GPIO_InitStruct);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(KEY_Pin==GPIO_Pin)
  {
    Key_Detect(Key_board);
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值