公司动态

杰里AC695N音频开发入门:从环境搭建到播放第一个WAV文件

📅 2026/7/30 13:33:49
杰里AC695N音频开发入门:从环境搭建到播放第一个WAV文件
1. 项目概述从零上手杰里695N音频开发如果你刚拿到一块基于杰里AC695N芯片的开发板看着一堆资料和SDK包有点无从下手那这篇文章就是为你准备的。我最近刚用这个系列的芯片做完一个智能音箱项目从环境搭建到第一个“Hello World”级别的音频播放程序中间踩了不少坑也总结了一套能让新手快速跑起来的流程。AC695N在蓝牙音频、Soundbar、便携音箱等领域应用很广其1.0版本的SDK虽然相对基础但结构清晰是理解其开发框架和进行二次开发的绝佳起点。这篇文章我就带你一步步走通这个“快速入门”的过程不仅仅是照着手册操作更会分享那些手册里不会写的环境配置细节、编译烧录的注意事项以及如何避免一些常见的“坑”。2. 开发环境搭建与SDK初探2.1 工具链与IDE准备杰里695N系列芯片的开发官方推荐在Windows环境下进行核心工具链是ARM的arm-none-eabi-gcc。很多新手第一步就会在这里卡住因为网络上的工具链版本混杂。根据我的经验直接使用SDK包toolchain目录下自带的工具链是最稳妥的能最大程度避免因编译器版本差异导致的诡异问题。如果SDK里没有可以去ARM官方下载对应版本但务必记录好版本号。除了编译器另一个核心工具是杰里自家的烧录与调试工具JLINK或杰里烧录工具。这里有个关键点695N芯片通常通过UART0进行日志输出和烧录。你需要一个USB转TTL串口模块将它的TX、RX分别连接到板子的UART0_RX和UART0_TX上同时共地。波特率通常设置为921600或115200具体要看board.h中的配置。注意连接串口模块时务必确保板子在断电状态下操作热插拔可能会损坏芯片的UART引脚。上电顺序建议为先连接好串口线再给开发板上电。集成开发环境方面虽然可以用纯命令行编译但我强烈建议使用Source Insight或VS Code来阅读和编辑代码。SDK的代码量不小一个好的IDE能极大提升查找和阅读效率。用Source Insight的话记得把SDK根目录和cpu/br25、include等关键目录添加到工程中并创建符号数据库。2. 2 SDK目录结构解析解压1.0 SDK后你会看到一堆文件夹先别慌我们挑核心的看apps目录这是你的主战场应用程序代码就在这里。里面通常会有一个demo文件夹包含了各种功能的示例比如audio_demo、bt_demo。我们快速入门就是从复制和修改其中一个demo开始。cpu/br25目录这是芯片内核相关的底层驱动和启动文件。br25对应着AC695N的内核型号。这里的文件一般不需要改动它们是芯片能跑起来的基础。include目录全局头文件聚集地包含了芯片寄存器定义、库函数API声明、系统配置等。写代码时#include的很多文件都在这里。driver目录外设驱动层如GPIO、PWM、I2C、ADC等操作的封装函数。你想控制某个引脚或者读取按键状态就需要调用这里的接口。sdk.lib或lib目录预编译好的库文件提供了音频编解码、蓝牙协议栈等核心功能的实现。我们的应用程序会链接这些库。tools目录一些实用工具比如电池曲线生成工具、密钥生成工具等。初期可以不用深究。理解这个结构你就知道该去哪里找代码、该去哪里放自己的代码。一个常见的做法是在apps目录下复制一份audio_demo重命名为你自己的项目名然后在这个副本里进行开发。3. 第一个音频播放工程剖析与编译3.1 从Demo工程开始我们以最简单的音频播放为例。在apps/audio_demo/src目录下找到main.c。这个文件就是整个应用的入口。我们快速浏览一下它的骨架#include app_config.h #include system/includes.h // 硬件初始化 void board_init(void) { // 初始化系统时钟、电源管理等 ... // 初始化音频硬件CODEC、I2S audio_init(); // 初始化文件系统用于读取SD卡或Flash中的音频文件 fs_init(); // 其他外设初始化按键、LED等 } // 主任务 void main_task(void *p) { board_init(); while(1) { // 处理音频播放事件、按键事件等 audio_event_handler(); os_time_dly(2); // 让出CPU延时2个系统tick } } // 系统入口 int main(void) { // 创建主任务 create_task(main_task, ...); // 启动任务调度器 os_run(); return 0; }这个框架非常经典main()创建任务任务里先做硬件初始化然后进入一个无限循环处理各种事件。对于音频播放核心是audio_init()和audio_event_handler()。3.2 关键配置修改app_config.h在编译前必须根据你的实际硬件修改app_config.h文件。这个文件决定了SDK的编译方向和资源分配。新手最容易出错的地方就在这里。芯片型号选择确保CPU_BR25被正确定义。通常AC695N就是BR25系列。#define CONFIG_CPU_BR25 1功能模块使能你需要播放本地音频文件那么以下宏必须打开#define TCFG_AUDIO_ENABLE 1 // 使能音频模块 #define TCFG_DEC_WAV_ENABLE 1 // 使能WAV解码器 #define TCFG_DEC_MP3_ENABLE 1 // 使能MP3解码器如果需要 #define TCFG_FS_ENABLE 1 // 使能文件系统 #define TCFG_SD_ENABLE 1 // 使能SD卡如果音频文件在SD卡上 #define TCFG_NOR_FS_ENABLE 1 // 使能Nor Flash文件系统如果音频在Flash里硬件引脚映射这是最需要根据原理图核对的部分。例如SD卡检测引脚、音频输出模式DAC直接输出还是I2S外接功放、按键引脚等。错误的引脚配置会导致硬件完全不工作。// 例如配置一个播放/暂停按键在GPIO_PA1 #define TCFG_AD_KEY_0_PORT GPIO_PA1 #define TCFG_AD_KEY_0_VALUE 0 // 按键按下时的ADC值或电平实操心得修改app_config.h后最好执行一次make clean再make因为很多配置会通过条件编译影响全局不清除旧的编译中间文件可能导致配置未生效。3.3 编译与生成固件环境准备好后打开命令行或使用IDE集成的终端进入你的工程目录例如apps/audio_demo。执行make命令。如果一切配置正确编译工具链会自动开始工作。编译成功后你会在工程目录下找到生成的固件文件通常是*.bin或*.fw格式同时也会生成一个*.map文件用于分析代码和内存分布。首次编译可能会遇到一些路径错误或头文件找不到的问题。请检查工具链的PATH环境变量是否设置正确。app_config.h中是否包含了必要的头文件路径。SDK的顶层Makefile中ROOT变量是否指向了正确的SDK根目录。编译通过的标志是在最后看到生成固件文件并且没有error提示。warning可以暂时忽略但最好也了解一下原因。4. 固件烧录与基础调试4.1 烧录操作步骤拿到bin文件后下一步就是把它烧录到开发板的Flash中。连接硬件确保USB转TTL串口模块正确连接板子的烧录口通常是标注为UART0的排针并连接好USB线给板子供电。进入烧录模式杰里芯片通常有两种方式进入烧录模式硬件进入按住板子上的某个特定按键如VOL-或MODE不放然后给板子重新上电保持按住几秒后松开。软件进入通过串口发送特定命令。对于新手硬件进入法更可靠。具体是哪个按键需要查阅板子的原理图或说明。使用烧录工具打开杰里烧录工具选择正确的串口号。在工具中加载编译好的bin文件。开始烧录点击“烧录”或“下载”按钮。工具会先擦除Flash然后写入程序最后可能会进行校验。成功后会提示“烧录完成”或“Download Success”。重启运行烧录完成后断开USB供电再次上电或者按一下复位键程序就会开始运行。4.2 串口日志查看与初步调试程序跑起来后怎么知道它是否正常工作呢串口日志是最重要的调试手段。打开一个串口调试助手如Xshell、SecureCRT、或者免费的Putty、MobaXterm。选择对应的串口号设置波特率与代码中uart_init设置的波特率一致通常是921600或115200数据位8停止位1无校验。重新给开发板上电你应该能在串口助手中看到打印信息。正常的启动日志可能类似这样System Start... Clock: 24000000 Hz Audio Init OK. FS Init OK. SD Card Inserted.如果你看到了这些恭喜你系统基础初始化成功了。如果没有输出或者输出乱码请检查波特率是否与代码配置完全一致尝试更换几个常用波特率115200, 921600, 1000000。接线TX和RX是否接反了串口模块的TX应接板子的RXRX接板子的TX。电源板子供电是否稳定可以用万用表测量一下芯片供电电压。烧录模式是否还在烧录模式有些板子烧录后需要完全断电再上电才能正常启动。5. 实现基础音频播放功能5.1 播放流程代码分析假设我们已经编译烧录了一个基础的audio_demo并且通过串口日志确认系统启动了。现在我们来深入看一下如何触发播放一个音频文件。在SDK的音频框架中播放一个文件通常遵循以下步骤我们可以在main_task循环中某个条件比如检测到按键按下触发void start_play_file(const char *path) { struct audio_decoder *decoder; // 1. 创建解码任务 decoder audio_decoder_create(path, AUDIO_CODEC_WAV); // 假设是WAV文件 if (decoder NULL) { printf(create decoder fail!\n); return; } // 2. 设置输出设备例如主DAC通道 audio_decoder_set_output(decoder, AUDIO_DAC_OUTPUT); // 3. 设置事件回调用于获取播放状态 audio_decoder_set_event_handler(decoder, my_decoder_event_handler, NULL); // 4. 启动解码播放 audio_decoder_start(decoder); } // 解码器事件回调函数 static void my_decoder_event_handler(struct audio_decoder *decoder, int event, void *arg) { switch (event) { case AUDIO_DEC_EVENT_START: printf(Playback started.\n); break; case AUDIO_DEC_EVENT_COMPLETE: printf(Playback finished.\n); // 播放完成可以销毁解码器或者播放下一个文件 audio_decoder_destroy(decoder); break; case AUDIO_DEC_EVENT_ERROR: printf(Playback error!\n); audio_decoder_destroy(decoder); break; } }这个流程清晰地展示了SDK的封装层次我们不需要关心PCM数据如何从文件读出、如何解码、如何送入DAC只需要调用audio_decoder_这一系列的API即可。5.2 文件系统与音频文件准备要让上面的代码工作你必须确保音频文件能被系统找到。这涉及到文件系统的挂载。SD卡这是最常用的方式。将格式化为FAT32的SD卡插入开发板卡槽代码中fs_init()会自动检测并挂载。你可以把test.wav文件放在SD卡根目录然后播放路径就设为/mnt/sdcard/test.wav。SPI Flash如果板载了SPI Nor Flash你需要先将文件系统如FAT或LittleFS烧录到Flash的特定区域并将音频文件一并打包进去。这通常需要使用SDKtools目录下的打包工具过程稍复杂。注意事项音频文件的格式和参数必须匹配。AC695N的1.0 SDK通常支持标准的PCM WAV16bit 单声道/立体声 8k/16k/44.1k/48kHz采样率和MP3格式。如果你播放的WAV文件没有声音先用电脑的播放器确认文件本身是正常的再用十六进制工具查看一下文件头确认其编码格式和采样率是否在芯片支持范围内。6. 常见问题排查与实战技巧6.1 编译与烧录类问题问题1编译时报错arm-none-eabi-gcc: command not found排查这是工具链路径问题。在命令行中直接输入arm-none-eabi-gcc -v看是否能识别。解决将工具链的bin目录例如xxx\gcc-arm-none-eabi\bin添加到系统的PATH环境变量中或者修改工程Makefile中的CROSS_COMPILE变量指定完整的工具链路径。问题2烧录工具找不到设备或烧录失败排查确认USB转TTL驱动已安装设备管理器中串口识别正常。确认板子是否成功进入烧录模式通常会有特定指示灯慢闪。检查串口线连接是否牢固TX/RX是否接反。尝试降低烧录波特率。解决严格按照硬件进入烧录模式的操作先按住指定键不放再上电等待2-3秒后松开最后点击烧录工具的“连接”或“开始”。问题3程序烧录后无任何现象串口无输出排查首先确认烧录的.bin文件是否确实是本次编译新生成的。检查app_config.h中TCFG_UART0_ENABLE和TCFG_UART0_BAUDRATE是否已正确使能和配置。用万用表测量芯片的VDDIO和VCORE电压是否正常通常分别为3.3V和1.2V左右。解决最直接的方法是在main()函数的最开始在初始化任何东西之前先写一个简单的GPIO翻转代码并让这个引脚接一个LED。如果上电后LED能闪烁说明芯片已经运行问题出在串口初始化或配置上。如果LED不闪则可能是时钟、电源或复位电路有问题。6.2 音频播放类问题问题4播放音频时只有噪音或破音排查采样率不匹配这是最常见的原因。代码中音频输出设备如DAC的采样率必须与音频文件本身的采样率一致。检查audio_init()中DAC的初始化参数。数据格式不匹配确认音频文件是16位有符号整数S16_LE而DAC也配置为接收同样的格式。时钟精度系统主时钟偏差过大可能导致DAC工作异常。检查board_init()中系统时钟如sys_clock_set()的配置是否准确。解决统一采样率。例如播放一个44.1kHz的WAV文件那么在audio_init()中配置DAC采样率也应为44100。可以在串口打印出音频解码器打开文件后解析出的采样率参数与你的配置进行对比。问题5播放一段时间后卡死或重启排查堆栈溢出音频解码、文件读取都需要内存。检查任务堆栈大小是否足够。在create_task()时第三个参数是堆栈大小对于音频主任务建议不少于4K。内存泄漏每次播放完成后是否正确调用audio_decoder_destroy()释放了资源可以在循环播放中观察系统剩余内存如果SDK提供相关API。文件系统阻塞如果SD卡质量差或文件碎片多读取可能超时导致任务阻塞。可以尝试更换高速SD卡或格式化后再放入音频文件。解决增加主任务堆栈大小并在每次播放流程结束后确保所有创建的资源都被销毁。使用os_malloc和os_free记录内存分配释放情况辅助排查。6.3 调试进阶技巧活用printf在关键函数入口、出口和错误分支添加带详细信息的printf这是最朴素的调试方法。注意控制打印频率避免影响实时音频流。查看.map文件编译生成的.map文件记录了所有函数和变量的内存地址。如果程序跑飞通过反汇编工具和map文件可以定位崩溃的大致位置。逻辑分析仪抓波形对于硬件问题如I2S信号是否正确、I2C通信是否正常逻辑分析仪是神器。可以直观地看到时钟、数据线上的波形判断时序是否符合规格书要求。逐步添加功能不要一开始就想实现所有功能。先从让系统跑起来、串口能打印开始然后添加LED控制再实现按键扫描最后才接入复杂的音频播放。每步都测试通过能极大降低问题排查的复杂度。走完以上所有步骤你应该已经让杰里AC695N开发板成功地播放出了第一段声音。这个过程中遇到的编译、烧录、硬件连接、代码配置等问题是每个嵌入式开发者都会经历的。1.0 SDK虽然不如高版本功能丰富但其代码结构直观没有过多抽象层非常适合初学者理解芯片的工作原理和SDK的基本框架。掌握了这个快速入门流程你就有了立足点接下来可以去探索更复杂的蓝牙A2DP音乐播放、通话、EQ音效处理等功能那些无非是在这个框架上添加更多的任务和事件处理而已。