蓝桥杯国赛之ADC按键

一、按键原理

扩展板上按键原理图如下:

 将八个按键的高电平端接入ADC_KEY引脚,并且每一个按键前串联相应的电阻。当每个按键按下时,该引脚的电位就会发生变化,不同的按键按下,通过ad采集到的电位不一样,因此可根据不同的电位来区分不同的按键。原理本质上是电阻分压,通过按下不同的按键来改变电压值,然后ADC引脚进行采集对应的电压,然后就可以做出判断,实现按键功能

优点:节省IO口,只需要一个IO口就可以检测这么多按键。但是缺点受硬件影响比较大,不同的板子,电阻也略有不同,检测得到的电压也有不同。对电阻的阻值有要求:每个按键按下时,它所相应的电位的变化需要比较大。并且不支持多个按键同时触发,如果多个按键同时触发就会产生混乱。

不同的按键按下电压所占比重值:


二、程序

电路图所示需要将P4和P5的PA5、ADC_KEY连接,用跳线帽将扩展板上对于的引脚进行连接。

PA5连接ADC_KEY,PA5就是一个ADC采集口,通过采集到不同的电压值来判断是哪一个按键按下的。对于着ADC2的通道15。所以在使用扩展板按键时需要配置ADC2.

将配置adc2通道13即可。可参考博客:ADC

adc数据采集:

uint16_t getADC2(void)
{
	uint16_t adc = 0;
	
	HAL_ADC_Start(&hadc2);
	adc = HAL_ADC_GetValue(&hadc2);
	
	return adc;
}

ADC数字滤波处理

// adc中值值滤波算法
#define LEN 50 
uint16_t filter(void)
{
	uint8_t i=0,j=0;
	uint16_t buf[LEN],temp;
	
	// 连续采集数据
	for(i=0;i<LEN;i++)
	{
		buf[i]=getADC2();
	}
	
	// 冒泡算法
	for(i=0;i<LEN/2;i++)
	{
		for(j=0;j<LEN-i-1;j++)
		{
			if(buf[j+1] < buf[j])
			{
				temp = buf[j+1];
				buf[j+1]= buf[j];
				buf[j] = temp;
			}
		}
	}
	if(LEN%2==0) //数组长度为偶数,返回中间两个的平均值
	{
		return (buf[LEN/2-1]+buf[LEN/2])/2;
	}
	else
	{
		return buf[LEN/2];
	}
}

按键扫描

uint8_t ADC_Key_Scan(void)
{
	uint16_t val=0;
	val = filter();
	
	if(val < 0x0FFF/ 14)  // 0fff --> 4095
	{
		return 1; // adc=0
	}
	else if((val > (0x0FFF /14)*1) && (val < (0x0FFF /14)*3))
	{
		return 2; // adc = 495
	}
	else if((val > (0x0FFF /14)*3) && (val < (0x0FFF /14)*5))
	{
		return 3; // adc = 1105
	}
	else if((val > (0x0FFF /14)*5) && (val < (0x0FFF /14)*7))
	{
		return 4; // adc = 1710
	}
	else if((val > (0x0FFF /14)*7) && (val < (0x0FFF /14)*9))
	{
		return 5;// adc = 2315
	}
	else if((val > (0x0FFF /14)*9) && (val < (0x0FFF /14)*11))
	{
		return 6;// adc = 2825
	}
	else if((val > (0x0FFF /14)*11) && (val < (0x0FFF /14)*13))
	{
		return 7;// adc = 3455
	}
	else if((val > (0x0FFF /14)*13) && (val < 0x0F6F))
	{
		return 8; // adc = 3926
	}
	else
	{
		return 0; // adc = 4040
	}
	
}

按键处理

void key_proc(void)
{
	if(key_uwTick - uwTick <200)return ;
	key_uwTick = uwTick;
	
	key_val = ADC_Key_Scan();
	key_down = key_val &(key_old ^ key_val);
	key_up = ~key_val &(key_old ^ key_val);
	key_old = key_val;
	
	if(key_down == 1)
	{
		ucled =1;
	}
}

  • 11
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值