简述多个AD按键使用双通道实现
2016-02-16 17:16
1151 查看
AD按键多,单通道实现易窜键,这时候可以考虑使用双通道实现。
原理:
本质还是单通道的实现方法,由于单条通道的采样不会大于1023,所以将二条通道上面的按键AD值都增加1000,一通道的按键遍历完成后,才轮到二通道的按键进行遍历,这样就实现了双通道按键。
本文使用的平台是RK的3126 Android5.1的SDK,先了解单通道AD按键是如何实现的。
判断button,如果获取到的ad值处于button->adc_value-70、button->adc_value+70的区间里,则判断按下的按键为当前的button。
在上面单通道的基础来实现双通道按键。
硬件上需要多拉出一个通道,单通道的时候是SARADC_CH1,双通道为SARADC_CH0、SARADC_CH1
rockchip,adc_value = <1003>和 rockchip,adc_value = <1499>分别是pre-key和next-key配置的AD值,实际上在二通道里检测到的pre-key和next-key按下的AD值是3和499,在这里要增加1000。io-channels = <&adc 2>,<&adc 0>; io-channel-names = “adc2”, “adc0”;增加了ADC0这个通道为二通通道。第二通道的按键配置必须置于第一通道的按键配置下面,至于原因,后面会提到。
配置采样通道
获取两个通道上的AD值
获取一通道上AD值,由于DTS里面第二通道 rockchip,adc_value设置的值都大于1000且在DTS都根据rockchip,adc_value从小到大排序来配置,当button->adc_value>1000为true,说明一通道上的按键完成遍历。
获取二通道上的AD值。上面一通道遍历完成后,省下来的就全部是二通道的按键。由于二通道按键的 rockchip,adc_value在DTS被故意增加1000以用来区分按键来自不同的通道,所以判断具体是哪个按键的时候,才二通道采样到的AD值也需要增加1000(result
+1000)
原理:
本质还是单通道的实现方法,由于单条通道的采样不会大于1023,所以将二条通道上面的按键AD值都增加1000,一通道的按键遍历完成后,才轮到二通道的按键进行遍历,这样就实现了双通道按键。
本文使用的平台是RK的3126 Android5.1的SDK,先了解单通道AD按键是如何实现的。
&adc { status = "okay"; key: key { compatible = "rockchip,key"; io-channels = <&adc 1>; vol-up-key { linux,code = <115>; label = "volume up"; rockchip,adc_value = <142>; }; vol-down-key { linux,code = <114>; label = "volume down"; rockchip,adc_value = <1>; }; ……}; }; &key { io-channels = <&adc 2>; power-key { gpios = <&gpio1 GPIO_A4 GPIO_ACTIVE_LOW>; linux,code = <116>; label = "power"; gpio-key,wakeup; }; };
DTS里按键的配置,rockchip,adc_value按键设置的AD值,linux,code上报给系统的按键键值。
chan = iio_channel_get(&pdev->dev, NULL); pdata->chan = chan;
配置采样通道
static int rk_key_adc_iio_read(struct rk_keys_drvdata *data) { struct iio_channel *channel = data->chan; int val, ret; if (!channel) return INVALID_ADVALUE; ret 4000 = iio_read_channel_raw(channel, &val); if (ret < 0) { pr_err("read channel() error: %d\n", ret); return ret; } return val; } result = rk_key_adc_iio_read(ddata);
获取通道的AD值。
struct rk_keys_button { u32 type; //TYPE_GPIO, TYPE_ADC u32 code; // key code int code_long_press; const char *desc;//key label u32 state; //key up & down state int gpio; //gpio only int adc_value; //adc only int adc_state; //adc only int active_low;//gpio only int wakeup; //gpio only int long_press_count; int pressFlag; int lednum; struct timer_list timer; }; struct rk_keys_button *button = &ddata->button[i];
adc_value是按键的AD值。ddata->button[i]通过DTS的解析进行赋值得到。
#define DRIFT_ADVALUE 70 if(result < button->adc_value + DRIFT_ADVALUE && result > button->adc_value - DRIFT_ADVALUE) { }
判断button,如果获取到的ad值处于button->adc_value-70、button->adc_value+70的区间里,则判断按下的按键为当前的button。
在上面单通道的基础来实现双通道按键。
硬件上需要多拉出一个通道,单通道的时候是SARADC_CH1,双通道为SARADC_CH0、SARADC_CH1
&adc { status = "okay"; key: key { compatible = "rockchip,key"; io-channels = <&adc 1>; vol-up-key { linux,code = <115>; label = "volume up"; rockchip,adc_value = <142>; }; vol-down-key { linux,code = <114>; label = "volume down"; rockchip,adc_value = <1>; }; …… /*二通道的按键配置*/ pre-key { linux,code = <165>; label = "pre"; rockchip,adc_value = <1003>; }; next-key { linux,code = <163>; label = "next"; rockchip,adc_value = <1499>; }; …… }; }; &key { io-channels = <&adc 2>,<&adc 0>; io-channel-names = "adc2", "adc0"; power-key { gpios = <&gpio1 GPIO_A4 GPIO_ACTIVE_LOW>; linux,code = <116>; label = "power"; gpio-key,wakeup; }; };
rockchip,adc_value = <1003>和 rockchip,adc_value = <1499>分别是pre-key和next-key配置的AD值,实际上在二通道里检测到的pre-key和next-key按下的AD值是3和499,在这里要增加1000。io-channels = <&adc 2>,<&adc 0>; io-channel-names = “adc2”, “adc0”;增加了ADC0这个通道为二通通道。第二通道的按键配置必须置于第一通道的按键配置下面,至于原因,后面会提到。
chan = iio_channel_get(&pdev->dev, NULL); if (IS_ERR(chan)) { dev_info(&pdev->dev, "no io-channels defined\n"); chan = NULL; } pdata->chan = chan; chan = iio_channel_get(&pdev->dev, "adc0"); if (IS_ERR(chan)) { dev_info(&pdev->dev, "no io-channels defined\n"); chan = NULL; } pdata->chan0 = chan;
配置采样通道
static int rk_key_adc_iio_read(struct rk_keys_drvdata *data) { struct iio_channel *channel = data->chan; int val, ret; if (!channel) return INVALID_ADVALUE; ret = iio_read_channel_raw(channel, &val); if (ret < 0) { pr_err("read channel() error: %d\n", ret); return ret; } return val; } static int rk_key_adc_iio_read000(struct rk_keys_drvdata *data) { struct iio_channel *channel = data->chan0; int val, ret; if (!channel) return INVALID_ADVALUE; ret = iio_read_channel_raw(channel, &val); if (ret < 0) { pr_err("read channel() error: %d\n", ret); return ret; } return val; }
获取两个通道上的AD值
result = rk_key_adc_iio_read(ddata); for (i = 0; i < ddata->nbuttons; i++) { ...... if(button->adc_value>1000) break; ...... }
获取一通道上AD值,由于DTS里面第二通道 rockchip,adc_value设置的值都大于1000且在DTS都根据rockchip,adc_value从小到大排序来配置,当button->adc_value>1000为true,说明一通道上的按键完成遍历。
result = rk_key_adc_iio_read000(ddata); for (; i < ddata->nbuttons; i++) { …… if(result +1000< button->adc_value + DRIFT_ADVALUE && result +1000> button->adc_value - DRIFT_ADVALUE) { } …… }
获取二通道上的AD值。上面一通道遍历完成后,省下来的就全部是二通道的按键。由于二通道按键的 rockchip,adc_value在DTS被故意增加1000以用来区分按键来自不同的通道,所以判断具体是哪个按键的时候,才二通道采样到的AD值也需要增加1000(result
+1000)
相关文章推荐
- java之eclipse常用快捷键
- is-a、has-a和like-a、组合、聚合和继承 两组概念的区别
- Eclipse 的 Debug 介绍与技巧
- React Native iOS 之Could not connect to development server.
- IT企业面试题(java描述)-字符串包含(1)
- jQuery的一些学习总结
- Android SQlite详解
- android ANR 分析
- vsftpd配置文件详解
- 内核模块
- android 判断app是否运行在主线程中
- js 根据权重概率随机
- 《转》UIView的剖析!
- socket编程的select模型
- Neo4j简介
- BZOJ_P2301&Codevs_P1858 [HAOI2011]Problem b(数论+容斥原理)
- Android系统信息获取
- Mac系统下的Eclipse实现Android真机调试
- Python基础02 基本数据类型
- 编程中的一些概念,KISS、DRY、MVC、OOP、REST