栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32 ADC按键

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32 ADC按键

主控stm32f103vet6,使用adc1的通道0即A0口,实验目的,一个GPIO检测11个按键的多种状态,按下状态,按下释放状态,长按状态,长按释放状态,一直按状态,5种状态检测。

原理图如上图,采用电阻分压,adc采集到的不同的电压值判断是哪一个按键按下。

 效果如图下图:

0代表第一个按键,1代表按下 2代表按下释放,3代表长按,4代表按着不松开,5代表长按释放
//第一次按下立马释放

[21:45:07.441]收←◆adc_key: 0,1        //检测到按下

[21:45:07.582]收←◆adc_key: 0,2        //检测到释放

//第二次按下1.5s释放

[21:45:08.645]收←◆adc_key: 0,1        //检测到按下

[21:45:09.446]收←◆adc_key: 0,3        //检测到长按

[21:45:09.757]收←◆adc_key: 0,5        //检测到长按后释放

//第三次按下4s释放

[21:45:11.939]收←◆adc_key: 0,1        //检测到按下

[21:45:12.739]收←◆adc_key: 0,3        //检测到长按

[21:45:13.241]收←◆adc_key: 0,4        //检测到一直按

[21:45:13.742]收←◆adc_key: 0,4        //检测到一直按

[21:45:14.244]收←◆adc_key: 0,4        //检测到一直按

[21:45:14.356]收←◆adc_key: 0,5        //检测到长按后释放

adc_key.h

#ifndef __ADC_KEY_H__
#define __ADC_KEY_H__
#include "stm32f10x.h"

#define ADC_KEY_EN //adc按键使能
#ifdef ADC_KEY_EN

extern uint16_t ADCKEYSCANTIME;		//按键扫描时间
typedef enum _AdcKeyType
{
	ADC_KEY_UNKOWN_TYPE = 0,
	ADC_KEY_PRESSED,				//按下
	ADC_KEY_RELEASED,				//按下释放
	ADC_KEY_LONG_PRESSED,			//长按
	ADC_KEY_LONG_PRESS_HOLD,		//一直按
	ADC_KEY_LONG_RELEASED,			//长按释放
}AdcKeyType;

typedef struct _AdcKeyMsg
{
    uint16_t index;
    uint16_t type;
}AdcKeyMsg;

uint8_t GetAdcKeyIndex(void);

AdcKeyMsg AdcKeyScan(void);

void AdcKeyInit(void);
#endif

#endif

adc_key.c

#include "adc_key.h"
#include "adc.h"
#include "timer.h"


#ifdef ADC_KEY_EN

#define 	ADC_KEY_SCAN_TIME			10		//按键扫描时间(ms)
#define 	ADC_KEY_JITTER_TIME			30		//按键消抖时间(ms)
#define 	ADC_KEY_CP_TIME				800 	//长按到长按,长按到一直按时间(ms)
#define 	ADC_KEY_CPH_TIME			500		//一直按触发间隔(ms)
#define	    ADC_KEY_COUNT				11		//标准adc按键个数
#define		ADC_KEY_FULL_VAL			4096	//12位adc精度

uint16_t ADCKEYSCANTIME = ADC_KEY_SCAN_TIME;

typedef enum _ADC_KEY_STATE
{
	ADC_KEY_STATE_IDLE,
	ADC_KEY_STATE_JITTER,
	ADC_KEY_STATE_PRESS_DOWN,
	ADC_KEY_STATE_CP

} ADC_KEY_STATE;

TIMER			AdcKeyWaitTimer;
TIMER			AdcKeyScanTimer;
ADC_KEY_STATE	AdcKeyState;
static 	uint8_t 	PreKeyIndex = ADC_KEY_COUNT;

void AdcKeyInit(void)
{
	Adc_Init();						//初始化adc1通道0
	TIM1_Int_Init(10-1, 7200-1);	//初始化定时器 1ms 
}

uint8_t GetAdcKeyIndex(void)
{
	uint16_t Val;
	uint8_t	KeyIndex = ADC_KEY_COUNT;

	Val = Get_Adc(ADC_Channel_0);

	KeyIndex = (Val + (ADC_KEY_FULL_VAL / ADC_KEY_COUNT) / 2) * ADC_KEY_COUNT / ADC_KEY_FULL_VAL;

	return KeyIndex;
}



AdcKeyMsg AdcKeyScan(void)
{
	uint8_t				KeyIndex=ADC_KEY_COUNT;
	AdcKeyMsg Msg = {ADC_KEY_COUNT, ADC_KEY_UNKOWN_TYPE};

	KeyIndex = GetAdcKeyIndex();
	
	switch(AdcKeyState)
	{
		case ADC_KEY_STATE_IDLE:
			if(KeyIndex == ADC_KEY_COUNT)
			{
				return Msg;
			}
			PreKeyIndex = KeyIndex;
			TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_JITTER_TIME);
			//APP_DBG("GOTO JITTER!n");
			AdcKeyState = ADC_KEY_STATE_JITTER;

		case ADC_KEY_STATE_JITTER:
			if(PreKeyIndex != KeyIndex)
			{
				//APP_DBG("GOTO IDLE Because jitter!n");
				PreKeyIndex = ADC_KEY_COUNT;
				AdcKeyState = ADC_KEY_STATE_IDLE;
			}
			else if(IsTimeOut(&AdcKeyWaitTimer))
			{
				//APP_DBG("GOTO PRESS_DOWN!n");
				TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CP_TIME);
				AdcKeyState = ADC_KEY_STATE_PRESS_DOWN;
				Msg.index = PreKeyIndex;
				Msg.type = ADC_KEY_PRESSED;
			}
			break;

		case ADC_KEY_STATE_PRESS_DOWN:
			if(PreKeyIndex != KeyIndex)
			{
				//APP_DBG("key release %dn", PreKeyIndex);
				AdcKeyState = ADC_KEY_STATE_IDLE;
				Msg.index = PreKeyIndex;
				Msg.type = ADC_KEY_RELEASED;
				PreKeyIndex = ADC_KEY_COUNT;
			}
			else if(IsTimeOut(&AdcKeyWaitTimer))
			{
				//return key cp value
				//APP_DBG("ADC KEY CPS!n");
				TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CPH_TIME);
				AdcKeyState = ADC_KEY_STATE_CP;
				Msg.index = PreKeyIndex;
				Msg.type = ADC_KEY_LONG_PRESSED;
			}
			break;

		case ADC_KEY_STATE_CP:
			if(PreKeyIndex != KeyIndex)
			{
				//return key cp value
				//APP_DBG("ADC KEY CPR!n");
				AdcKeyState = ADC_KEY_STATE_IDLE;
				Msg.index = PreKeyIndex;
				Msg.type  = ADC_KEY_LONG_RELEASED;
				PreKeyIndex = ADC_KEY_COUNT;
			}
			else if(IsTimeOut(&AdcKeyWaitTimer))
			{
				//return key cph value
				//APP_DBG("ADC KEY CPH!n");
				TimeOutSet(&AdcKeyWaitTimer, ADC_KEY_CPH_TIME);
				Msg.index = PreKeyIndex;
				Msg.type  = ADC_KEY_LONG_PRESS_HOLD;
			}
			break;

		default:
			AdcKeyState = ADC_KEY_STATE_IDLE;
			PreKeyIndex = ADC_KEY_COUNT;
			break;
	}

	return Msg;
}

#endif

github:hahahahahaxiaoming/stm32adckey: stm32f103adc按键采集 (github.com)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/857051.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号