ADC分压按键代码,有大佬教教小白马
同一个adc io口,通过adc值不同检测 s1,s2,s3,ADC分压按键 s1(开关),s2(增加温度),s3(减温度),长按s2连续增加,长按s3连续减少,s2和s3一起长按切换华氏度,或者摄氏度,目前只是做了按一次,但是长按会有问题 ,大佬们有比较优秀的代码让我学习学习吗基础大佬提供的扫描方法,优化的。请大佬指教一下,好像哪里还有问题,菜鸟自己看不出
本帖最后由 wuzhixuan 于 2024-5-15 11:04 编辑void KeyScan(void){
static unsigned char ADC_sap_cont, key_last, key_release;
unsigned char key_th;
adcData = GET_ADC_DATA(4);// 通道4 AD值
theVoltage = (unlong) adcData * 5 * 100 / 4096; //电压放大100倍
if (100 < theVoltage) {
if (theVoltage >= 450) { key_th = 1; } // S2 开关 按键
else if ((theVoltage <= 340) && (theVoltage >= 290)) { key_th = 2; } // S3 - 按键
else if ((theVoltage <= 250) && (theVoltage >= 220)) { key_th = 3; } // S4 + 按键
else if ((theVoltage <= 390) && (theVoltage >= 350)) { key_th = 4; } // S3+S4 同时按下按键
else { key_th = 0; }
if (key_last == key_th) { ADC_sap_cont++; } //键值稳定后开始累计
else { key_last = key_th, ADC_sap_cont = 0; } //不稳定键值将被替换抛弃
if (ADC_sap_cont >= 200) //如果键值稳定且累计成功
{
key_release = 1;
Key_value = key_last;
}
} else {
if (key_release == 1) {
key_release = 0;
if (key_flag == 0) //并且当前无未处理键值
{
ADC_sap_cont = 0; //则输出键值
key_flag = 1;
} else { ADC_sap_cont = 200; } //如果有未处理键值,则等待
}
ADC_sap_cont = 0;
}
}
void keyAction() {
if (key_flag) {// 检查是否有未处理的键值
switch (Key_value) {
case 1:
toggle_power();// 切换电源开关
break;
case 2:
decrease_temperature();// 减少温度
break;
case 3:
increase_temperature();// 增加温度
break;
case 4:
switch_temperature_unit();// 切换温度单位
break;
default:
// 无操作
break;
}
key_flag = 0; // 处理完毕后重置key_flag
}
Key_value = 0; // 执行完任务后将Key_value清零
}
wuzhixuan 发表于 2024-5-8 17:00
代码是这样的,感觉有问题,而且实际测量的电压值和计算的电压值相差很大,大佬可以帮忙优化一下吗 我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。
void ADC0_ISR (void) interrupt 5
{
static unsigned char ADC_sap_cont,key_last,key_release;
unsigned char key_th;
ADC_CONTR &= ~0x20; //清ADC中断标记
key_adc = (unsigned int)ADC_RES<<8 | ADC_RESL; //取AD值
if(key_adc<2100)
{
if (key_adc<200) {key_th = 1;} //键值分段,实际测试得到区间
else if ((key_adc<700) && (key_adc>=200)) {key_th = 2;}
else if ((key_adc<1100) && (key_adc>=700)) {key_th = 3;}
else if ((key_adc<2100) && (key_adc>=1100)) {key_th = 4;}
else {key_th = 0;}
if (key_last == key_th) {ADC_sap_cont++;} //键值稳定后开始累计
else{key_last = key_th,ADC_sap_cont=0;} //不稳定键值将被替换抛弃
if(ADC_sap_cont>=200) //如果键值稳定且累计成功
{
key_release = 1;
key_valu = key_last;
}
}
else //如果无按键,则及时清零
{
if(key_release == 1)
{
key_release = 0;
if(key_flag == 0) //并且当前无未处理键值
{
ADC_sap_cont = 0; //则输出键值
key_flag = 1;
}
else {ADC_sap_cont = 200;} //如果有未处理键值,则等待
}
ADC_sap_cont = 0;
}
ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | 0x00; //再次启动 AD 转换
}
晓飛飛 发表于 2024-5-8 18:37
我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。
谢谢大佬
晓飛飛 发表于 2024-5-8 18:37
我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。
大佬,你这个代码就很简洁很精妙 晓飛飛 发表于 2024-5-8 18:37
我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。
if (key_flag == 0) //并且当前无未处理键值这快代码不是很明白,可以帮忙讲解一下吗,还有就是 key_valu = key_last; 为啥是等于上一次的值,不等于key_th
wuzhixuan 发表于 2024-5-9 00:16
if (key_flag == 0) //并且当前无未处理键值这快代码不是很明白,可以帮忙讲解一下吗,还有就是 key_va ...
是一种消抖措施 晓飛飛 发表于 2024-5-9 01:21
是一种消抖措施
大佬,这个好像不支持长按和两个按键同时按,长按s3,长按s4,已经s3,s4同时按
wuzhixuan 发表于 2024-5-9 01:40
大佬,这个好像不支持长按和两个按键同时按,长按s3,长按s4,已经s3,s4同时按
...
长按、双击这些都可以在这个代码基础上进行扩展,需要额外增加代码实现的。