【杰理蓝牙开发】AC695x 按键ADC接口分析

0. 个人简介 && 授权须知

image-20230911133730620

📋 个人简介

  • 💖 作者简介:大家好,我是喜欢记录零碎知识点的菜鸟打工人。😎
  • 📝 个人主页:欢迎访问我的博客主页🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:杰理蓝牙开发专栏 🍁 🍁
  • 💬格言:写文档啊不是写文章,重要的还是直白!🔥

转载文章,禁止声明原创;不允许直接二次转载,转载请根据原文链接联系作者

若无需改版,在文首清楚标注作者及来源/原文链接,并删除【原创声明】,即可直接转载。
但对于未注明转载来源/原文链接的文章,我将保留追述的权利。

作者:积跬步、至千里

image-20230911133724204

1. APP消息管理

【系统事件分类】

  • 模式事件

    • 按键、设备、其他
  • 公共事件

    • 按键、设备、蓝牙、其他

【系统事件处理】

产生系统事件时

  • 先到【模式事件】中查询是否有匹配的事件,若果有,则执行事件处理函数,然后结束,若没有,执行下一步
  • 再到【公共事件】中查询是否有匹配的事件,若果有,则执行事件处理函数,然后结束,若没有,则事件作废

蓝牙模式的设备事件如果不做处理,那么会把事件丢到公共事件中的公共蓝牙事件去 处理,而不是丢到公共事件的公共设备事件去处理

2. adc 按键接口

2.1 驱动部分

adc 按键的初始化流程函数接口如下所示:

【初始化后,系统开始2ms为周期采集 adc 通道的值】

main()
  -> task_create(app_task_handler, NULL, "app_core");
   -> app_init();
    -> board_init();
	 -> adc_init();
	  -> _adc_init(1); 
	   -> sys_s_hi_timer_add(NULL, adc_scan, 2); //定时器 2ms 扫描一次 
		-> adc_scan();
		 -> adc_sample();   //  adc 采样函数
			 依次采集 AD_CH_LDOREF 和 AD_CH_VBAT 这两个通道的 adc 值

【添加按键的扫描驱动,这个是在ADC扫描函数之后】

main()
  -> task_create(app_task_handler, NULL, "app_core");
   -> app_init();
    -> board_init();
	 -> board_devices_init();
	  -> key_driver_init();
		{
            -> err = adkey_init(&adkey_data);  // 初始化 ADC 
            -> // 定义了哪些按键,就初始化哪些按键
               //按键扫描,扫描所有定义的按键 
	   		-> sys_s_hi_timer_add((void *)&adkey_scan_para, key_driver_scan, adkey_scan_para.scan_time);  
        }
   

其中 adkey_scan_para 变量是定义的全局按键驱动扫描参数结构体,注意定义的 key_typeKEY_DRIVER_TYPE_AD

//按键驱动扫描参数列表
struct key_driver_para adkey_scan_para = {
    .scan_time 	  	  = 10,				//按键扫描频率, 单位: ms
    .last_key 		  = NO_KEY,  		//上一次get_value按键值, 初始化为NO_KEY;
    .filter_time  	  = 2,				//按键消抖延时;
    .long_time 		  = 75,  			//按键判定长按数量
    .hold_time 		  = (75 + 15),  	//按键判定HOLD数量
    .click_delay_time = 20,				//按键被抬起后等待连击延时数量
    .key_type		  = KEY_DRIVER_TYPE_AD, //  **********************注意定义的类型*******************
    .get_value 		  = ad_get_key_value,    // 返回定义的 ADC 通道的 按键值,也即是 adkey_data 变量中定义的哪个按键
};

key_driver_scan 函数负责扫描所有注册的按键驱动,消抖,单击、双击、长按、短按…………,伪代码逻辑如下:

最终会通过 sys_event_notify(&e) 接口向系统通知发生了什么类型的事件。

比如:发生了 按键事件,按键为 ``ADC IO口的第六个按键,类型为KEY_DRIVER_TYPE_AD`

key_driver_scan()
{	
  cur_key_value = scan_para->get_value(); // 判断当前是哪个按键
  // 经过各种判断,最后打包 struct sys_event e; 这个变量
    e.type = SYS_KEY_EVENT;  // 类型为 按键   
    e.u.key.init = 1;   
    e.u.key.type = scan_para->key_type; //区分按键类型,ADC中自定义类型为 KEY_DRIVER_TYPE_AD,在变量 adkey_scan_para 中
    e.u.key.event = key_event;          // 判断按键事件类型为,长按、短按、保持、松开、等具体的类型
    e.u.key.value = key_value;          // 比如ADC中一个IO口可能连接了9个按键,该值定义是哪个按键被按下
    e.u.key.tmr = timer_get_ms();
    scan_para->click_cnt = 0;  //单击次数清0
    scan_para->notify_value = NO_KEY;
    
    sys_event_notify(&e);  // ******************************向系统通知事件触发的接口******************
}
 

2.2 应用层部分

board_ac695x_demo_cfg.h 中,设置 ADC 的引脚为 ADC3/PA10

#define TCFG_ADKEY_PORT                     IO_PORTA_10         //AD按键端口(需要注意选择的IO口是否支持AD功能)
#define TCFG_ADKEY_AD_CHANNEL               AD_CH_PA10

2.2.1 定义事件处理函数

定义一个全局变量 adkey_data 作为该部分的数据结构,定义 AD按键对应的引脚,ADC通道等值

系统通知有事件发生时,应用层应该定义相应的事件处理函数

SYS_EVENT_HANDLER(SYS_KEY_EVENT, app_key_event_remap, 3); // SYS_KEY_EVENT 对应的事件处理函数

int app_key_event_remap(struct sys_event *e)
{
    struct key_event *key = &e->u.key;
    int msg = KEY_NULL;
    switch (key->type) {
         case KEY_DRIVER_TYPE_AD:   // ************发生这个类型的按键事件时,自定义事件处理函数****************   
         	break;
         case KEY_DRIVER_TYPE_RTCVDD_AD:    // 示例:如果发生这个事件
#if TCFG_ADKEY_ENABLE
         msg = adkey_event_to_msg(app_curr_task, key);   //从表中获取事件类型
#endif
        break; 
        
        defalut:break
    }
    e->u.key.event = msg;
    e->u.key.value = 0;//
    return TRUE;//notify数据
}
SYS_EVENT_HANDLER(SYS_KEY_EVENT,  app_key_event_remap, 3);  // 注册完毕后,系统会自动执行

2.2.2 查表获取事件类型

msg = adkey_event_to_msg(app_curr_task, key);   //从表中获取事件类型

// msg 为 某模式,例如 fm 模式下的 adkey table ,中的某个事件类型
/*
	按键1动作:  单击   长击  保持  抬起  双击  三击
	事件类型:	A1     A2	A3	  A4	A5	  A6
*/

假设当前 task 类型为 fm_task,则查表过程如下:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. fm task 中获取按键消息

adc 按键只有一组,但是可以实现在不同的任务下实现不同的功能。
在 fm 模式下,通过按键实现事件触发的接口原理分析如下:

app_fm_task();
 -> fm_event_handler((struct sys_event *)(&msg[1]);
  -> fm_key_event_opr(event);
   -> /*不同的 event 对应不同的时间处理函数*/

比如,暂停播放对应的 adc 按键为: 按键2 的单击事件
在这里插入图片描述
在这里插入图片描述

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

积跬步、至千里

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

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

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

打赏作者

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

抵扣说明:

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

余额充值