Firefly开源社区

打印 上一主题 下一主题

FireBlue例程 按键 多次触发

25

积分

0

威望

0

贡献

游客

积分
25

FireBlue例程 按键 多次触发

发表于 2015-3-27 10:38:09      浏览:5048 | 回复:1        打印      只看该作者   [复制链接] 楼主
本帖最后由 dezhi 于 2015-3-27 15:33 编辑

精心策划非法手段地意外搞了个 FireBLE 板子,板子做工、外观,颜色等无得说,怎么一美字了得,完全符合我这个外观控。
照着wiki用git下载了例程代码,编译,下载,运行,都挺顺利,唯一发现的是五向按键  JOYSTICK 拨动的时候  偶尔会多次触发按键,刚开始以为是按键本身硬件故障,但每个方向都那么铿锵有力,而且新板子,应该不会有这种问题,遂用公司示波器偷偷的量了下,JOY_ADC/P3_0 在按键按下时正常,能正常分压,JOY_INT/P1_2 1 的中断引脚也有较为完美的波形,以此推断 硬件上没有问题。
那就分析软件去吧。

刚拿到板子,说实在啲,对QN902x 这个ic 还真不熟悉,唯一熟悉的就是Cortex-M0 构架。
直接看代码,似懂非懂的感觉。
速度地把wiki 上的 的上手教程等资料看了一遍不够再看一遍,看了几遍就没记得了,
再回来看代码,还是似懂非懂,呵呵

不多说,看原理图分析,
1.JOY_ADC/P3_0 ,JOY_INT/P1_2 1   2线,五键,只能ADC 按键 ?
2.P1_2 int 字眼,那么明显,中断触发采集后判断到底是那个键被按下?
3.R46 上拉VCC,下降沿???

跟着代码流程走,寻找和按键有关的代码,

1.gpio_init(gpio_interrupt_callback); 跟进去,设置回调,开时钟,开GPIO总中断。

2.button_init(); 跟进去 ,得出BUTTON1_PIN == GPIO_P12,配置唤醒,引脚中断使能。但发现有几行代码被注释掉,是设置上拉,输入,中断方式?为什么注释掉?把注释去掉,编译下载运行,还是一样,会多次触发,而且每次都是中键, == 中指 ==???


3.接下来 好像没有相关的GPIO设置的代码后紧接着进入调度。


4.按键被按下,触发中断,进入中断函数,gpio_interrupt_callback被调用,判断是那个引脚的中断,如果是BUTTON1_PIN则ke_evt_set(1UL << EVENT_BUTTON1_PRESS_ID),设置事件,全局搜索,EVENT_BUTTON1_PRESS_ID,找到对应回调函数,app_event_button1_press_handler,


5.进入 发现 ke_timer_set(APP_KEY_SCAN_TIMER,TASK_APP,2); // delay 20ms to debounce ,全局搜索APP_KEY_SCAN_TIMER 得到对应回调函数app_key_scan_timer_handler


6.进入,分析等到函数功能,初始化ADC 采集 P3_0 电压,ADC 回调函数 adc_test_cb 中,发现 ke_evt_set(1UL << EVENT_ADC_KEY_SAMPLE_CMP_ID); 全局搜索 EVENT_ADC_KEY_SAMPLE_CMP_ID,得对应回调函数app_event_adc_key_sample_cmp_handler。


7.跟进 app_event_adc_key_sample_cmp_handler,函数功能为:计算电压,根据电压值 得出对应键值,后ke_timer_set(APP_KEY_PROCESS_TIMER,TASK_APP,10);,还是老方法,全局搜索APP_KEY_PROCESS_TIMER,得到对应函数 app_key_process_timer_handler,跟进。


8.最后发现是对按键的响应功能代码。


分析按键按下后的流程,
中断产生-》设置事件EVENT_BUTTON1_PRESS_ID--》ke_timer_set(APP_KEY_SCAN_TIMER,TASK_APP,2); // delay 20ms to debounce-》采集 P3_0 电压-》计算电压,根据电压值 得出对应键值-》响应按键

流程没有问题,但发现 延时20ms 后直接采集电压。
  1. int app_key_scan_timer_handler(ke_msg_id_t const msgid, void const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id)
  2. {
  3.     adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
  4.          
  5.     // Read voltage. use interrupt
  6.     adc_read_configuration read_cfg;
  7.     read_cfg.trig_src = ADC_TRIG_SOFT;
  8.     read_cfg.mode = BURST_MOD;
  9.     read_cfg.start_ch = AIN0;
  10.     read_cfg.end_ch = AIN0;
  11.     adc_read(&read_cfg,adc_key_value, KEY_SAMPLE_NUMBER, adc_test_cb);
  12.     while(adc_done == 0);   
  13.     return(KE_MSG_CONSUMED);
  14. }
复制代码

并没有进行防抖处理,中断有可能被误触发??

遂改代码为

  1. int app_key_scan_timer_handler(ke_msg_id_t const msgid, void const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id)
  2. {
  3.      
  4.      if(gpio_read_pin(BUTTON1_PIN) == GPIO_LOW)
  5.      {
  6.             adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
  7.          
  8.              // Read voltage. use interrupt
  9.              adc_read_configuration read_cfg;
  10.              read_cfg.trig_src = ADC_TRIG_SOFT;
  11.              read_cfg.mode = BURST_MOD;
  12.              read_cfg.start_ch = AIN0;
  13.              read_cfg.end_ch = AIN0;
  14.              adc_read(&read_cfg,adc_key_value, KEY_SAMPLE_NUMBER, adc_test_cb);
  15.              while(adc_done == 0);   
  16.      }
  17.      return(KE_MSG_CONSUMED);
  18. }
复制代码



在20ms 后判断 P1_2 是否给低电平。根据此值判断是否是按键按下,避免误触发。
编译下载运行,测试,试了几十次,暂无发现 一次按下,放开后再次触发问题。

至此,问题得到解决。
看了一下QBlue QN 自带的例程,也是没有对延时后再次判断,不知道在QN的测试板子会不会也有误触发情况。

总结;刚拿到板子,对ic,系统等都不为熟悉,通过这次分析,也了解了QN902x 的软件架构,不知道算是入门了没?最后还得感谢Firefly 团队的板子,也感谢我的非法手段,哈哈。

回复

使用道具 举报

400

积分

0

威望

0

贡献

注册会员

Rank: 8Rank: 8

积分
400
QQ
发表于 2015-3-27 16:29:52        只看该作者  沙发
感谢网友帮忙解决按键问题,五向按键可以精准识别了!:victory:
没个性,不签名!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表