当前位置: 首页 > news >正文

杰理可视化SDK开发-添加按键触摸音教程

前言

现在为止也开发了许多杰理TWS蓝牙耳机、音响项目SDK的案子,在调试案子时不断的向前辈们学习到了很多关于蓝牙音响、蓝牙TWS耳机专业的知识。想在这里做一个学习汇总,方便各位同行和对杰理芯片SDK感兴趣的小伙伴们学习;

本章详细讲解杰理AC700N芯片按键触摸提示音实现方法

在调试一个TWS蓝牙耳机案子时,按键通常是我们必须要添加的功能,通过按键我们可以实现音量的增大/减少,歌曲的播放/暂停,曲目的切换,开机/关机等特定功能;所有我们必须在按键按下是添加提示音,有提示音的存在方便我们更好的感知按键的状态;在杰理SDK中有非常多可以实现按键提示音的方法。这里出一个常用稳定实现按键提示音的方法;

配置步骤

步骤1:在可视化配置工具JLstudio中配置添加按键触摸提示音,在选择导出。如下图所示。特别要注意我如下画框的地方!


步骤2:核对代码中对按键触摸音的定义是否与配置修改添加的触摸音文件名对应,如不对应使其对应,无论是修改代码中的文件名或者还是修改真实提示音音频文件的文件名需使得双方一一对应,没有对应后果就是配置没作用;如下图所示;


步骤3:观察代码中触摸按键音的播放流程:如下图所示

按键提示音核心配置文件:" key_tone.c "文件,博主观察了如下文件中的函数作用:
1、检查触摸提示音文件是否存在函数:static bool is_key_tone_enable()
2、按键提示音消息触摸函数:static int key_tone_msg_handler(int *msg)
3、消息注册:将 key_tone_msg_handler 注册为 APP_MSG_KEY_TONE 消息的处理者
4、IO按键按下事件处理函数:void key_down_event_handler(u8 key_value)
5、触摸按键按下发送提示音消息函数:touch_key_send_key_tone_msg(void)

代码讲解:

/* ============================================ * 内存段定义:将按键提示音相关代码和数据 * 放到独立的Flash段中,便于管理和优化 * ============================================ */ #ifdef SUPPORT_MS_EXTENSIONS #pragma bss_seg(".key_tone.data.bss") // BSS段(未初始化全局变量) #pragma data_seg(".key_tone.data") // 数据段 #pragma const_seg(".key_tone.text.const") // 只读常量段 #pragma code_seg(".key_tone.text") // 代码段 #endif #include "fs/resfile.h" // 文件系统接口,用于读取Flash中的提示音文件 #include "app_main.h" // 应用主头文件 #include "app_tone.h" // 提示音播放接口 #include "key_driver.h" // 按键驱动头文件 /* ============================================ * 全局标志:记录是否已检测到提示音文件 * 0 = 未检测,1 = 文件存在,0xFF = 文件不存在 * ============================================ */ static u8 g_have_key_tone_file = 0; /* ============================================ * 函数:检查提示音文件是否存在 * 逻辑:首次调用时,拼接Flash资源路径和提示音文件名, * 尝试打开文件。打开成功则标记为1,失败标记为0xFF * 返回:true = 文件存在,false = 文件不存在 * ============================================ */ static bool is_key_tone_enable() { if (g_have_key_tone_file == 0) { // 首次检测 char file_path[48]; strcpy(file_path, FLASH_RES_PATH); // 复制Flash资源根路径 strcpy(file_path + strlen(FLASH_RES_PATH), get_tone_files()->key_tone); // 拼接提示音文件名 void *file = resfile_open(file_path); // 尝试打开文件 if (file) { g_have_key_tone_file = 1; // 文件存在 resfile_close(file); } else { g_have_key_tone_file = 0xff; // 文件不存在 } } return g_have_key_tone_file == 1 ? true : false; } /* ============================================ * 函数:按键提示音消息处理器 * 这是一个APP消息回调函数,当收到 APP_MSG_KEY_TONE 消息时触发 * 逻辑:先检查提示音文件是否存在,若存在则调用播放函数 * ============================================ */ static int key_tone_msg_handler(int *msg) { if (!is_key_tone_enable()) { // 提示音文件不存在,直接返回 return 0; } if (msg[0] == APP_MSG_KEY_TONE) { // 收到按键提示音消息 #if LYF_KEY_TONE play_key_tone_file(get_tone_files()->key_tone); // 播放提示音文件 #endif } return 0; } /* ============================================ * 消息注册:将 key_tone_msg_handler 注册为 APP_MSG_KEY_TONE 消息的处理者 * owner = 0xff 表示系统级消息 * from = MSG_FROM_APP 表示消息来自APP层 * ============================================ */ APP_MSG_HANDLER(key_tone_msg_entry) = { .owner = 0xff, .from = MSG_FROM_APP, .handler = key_tone_msg_handler, }; /* ============================================ * 函数:IO按键按下事件处理(当宏 TCFG_IOKEY_ENABLE 开启时编译) * 逻辑:检测到按键按下后,发送 APP_MSG_KEY_TONE 消息 * 消息会被 key_tone_msg_handler 接收并触发提示音播放 * ============================================ */ #if TCFG_IOKEY_ENABLE void key_down_event_handler(u8 key_value) { if (g_have_key_tone_file == 1) { // 仅当提示音文件存在时才发送 app_send_message(APP_MSG_KEY_TONE, 0); // 发送提示音消息 } } #endif /* ============================================ * 函数:触摸按键发送提示音消息(当宏 TCFG_LP_TOUCH_KEY_ENABLE 开启时编译) * 逻辑:与 key_down_event_handler 相同,用于低功耗触摸按键场景 * ============================================ */ #if TCFG_LP_TOUCH_KEY_ENABLE void touch_key_send_key_tone_msg(void) { if (g_have_key_tone_file == 1) { app_send_message(APP_MSG_KEY_TONE, 0); } } #endif

步骤4:在最接近底层的触摸按键中断处理函数中p33_ctmu_key_event_irq_handler()发送触摸按键提示音,如图所示;

个人总结

按键按下的时候发送APP_MSG_KE_TONE消息,消息处理器检查文件是否存在,存在则调用 play_key_tone_file(get_tone_files()->key_tone)播放tone_zh/key_tone.* 或 tone_en/key_tone.*对应的提示音文件

第一步:系统初始化阶段
读取 Flash 中的提示音文件路径配置(chinese_tone_files / english_tone_files)
根据当前语言(中文/英文)选择对应的配置表
调用 is_key_tone_enable() 检测文件是否存在
拼接路径:FLASH_RES_PATH + "tone_zh/key_tone.*"
resfile_open() 尝试打开
成功 → g_have_key_tone_file = 1
失败 → g_have_key_tone_file = 0xFF

第二步:按键触发阶段(两条路径)
路径A:IO物理按键(TCFG_IOKEY_ENABLE)
key_down_event_handler(key_value)
app_send_message(APP_MSG_KEY_TONE, 0)
路径B:触摸按键(TCFG_LP_TOUCH_KEY_ENABLE) p33_ctmu_key_event_irq_handler()
收到 CTMU_P2M_CHx_FALLING_EVENT(按键按下)0
touch_key_send_key_tone_msg()
app_send_message(APP_MSG_KEY_TONE, 0)

第三步:消息分发阶段
APP消息队列收到 APP_MSG_KEY_TONE 消息
key_tone_msg_handler() 被调用
检查 is_key_tone_enable() → 文件是否存在
不存在 → 直接返回,不播放
存在 → 继续
play_key_tone_file(get_tone_files()->key_tone)
读取路径:tone_zh/key_tone.* 或 tone_en/key_tone.*
调用底层音频驱动播放提示音文件


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

http://www.zskr.cn/news/1435414.html

相关文章:

  • ChanlunX缠论插件:5分钟快速上手的通达信自动画线工具终极指南 [特殊字符]
  • 如何快速掌握RPFM:全面战争模组制作的完整教程
  • 基于Arduino的红外传感器双向人数统计与自动灯光控制系统
  • 3步解锁微信记忆宝库:让聊天记录成为你的数字资产
  • 2026年5月南京在售楼盘官方售楼电话大全 - 资讯纵览
  • 6种字重免费开源:PingFangSC字体如何解决跨平台中文排版难题
  • 3步快速下载网易云音乐FLAC无损音乐:建立个人无损音乐库的终极指南
  • 广西省北流市寄件省钱攻略:4 个全国低价寄快递微信工具,小件快递大件物流特产一键上门 - 时讯资讯
  • PMP五大过程组详解:启动、规划、执行、监控、收尾 - 众智商学院职业教育
  • 终极百度网盘加速方案:BaiduPCS-Web与KinhDown完整配置指南
  • 基于Arduino与蓝牙的视觉化计时器:从硬件选型到APP开发全解析
  • AtlasOS深度优化指南:让你的Windows系统快如闪电的终极方案
  • 3大核心技术:ESP32显示驱动完全实战指南
  • 零漂移单电源R-R运算放大:AD8629
  • 2026 年 5 月 陈年茅台品鉴馆 西安酒水回收 现款交易商户人气排行榜 - 资讯纵览
  • 小说下载器:一键保存全网小说,打造个人离线图书馆
  • Triplane Transformer:单图像3D重建的速度与质量革命
  • 如何永久保存微信聊天记录:免费本地数据备份与情感分析完整指南
  • 基于Arduino Uno与UnoJoy库自制USB游戏手柄全攻略
  • FinalBurn Neo终极指南:构建高性能街机模拟器的技术实践
  • Windows隐私保护新方案:Boss-Key一键隐藏工具完全指南
  • 基于Arduino的自动喂鱼器DIY:从硬件搭建到编程控制
  • 三步解决pyecharts离线部署难题:告别网络依赖的完整方案
  • 反渗透高纯水设备哪家强?2026年05月加工厂推荐名单,超纯水设备/全自动高纯水设备,高纯水设备生产厂家哪家好 - 品牌推荐师
  • Zotero Style完整指南:让文献管理效率翻倍的终极插件
  • 破解工业高能耗降温痛点:科瑞昌省电空调3E方法论如何降本增效? - 资讯纵览
  • 基于Arduino的智能音量均衡器:解决家庭影院动态范围过大问题
  • 宁波市海曙区黄金回收服务指南 - 黄金回收
  • 如何快速掌握艾尔登法环帧率解锁:面向新手的完整指南
  • 12306高仿购票系统:大学生分布式架构实战终极指南