山景BP1048增加AT指令,实现单片机串口控制播放音乐(一)
1、设计目的
山景提供的SDK是蓝牙音箱demo,用户使用ADC按键或者IR遥控器,进行人机交互。然而现实很多场景,需要和单片机通信,不管是ADC按键或者IR接口都不适合和单片机通信。这里设计个AT指令用来和BP1048通信。AT指令如下图所示为控制指令。
设计AT指令集
| 指令 | 功能 |
| AT+CA | 指定音量 |
| AT+CB | 播放和暂停 |
| AT+CC | 下一曲 |
| AT+CD | 上一曲 |
| AT+CE | 音量+ |
| AT+CF | 音量- |
| AT+CG | 蓝牙是否开启后台 |
| AT+CJ | 单曲播放 循环顺序播放 |
| AT+CK | 蓝牙自动后台 |
| AT+CN | 提示音 |
| AT+CP | 此指令是设置上电自动进入模式 |
| AT+CQ | EQ 设置 |
| AT+CR | 设置自动回传功能 |
| AT+CT | 设置波特率 |
| AT+CM | 切换模式 |
| AT+CU | 静音 |
| AT+CZ | 芯片复位 |
| AT+AA | 播放模式 |
| AT+AC | 指定播放模式 |
| AT+BA | 接挂电话控制指令 |
返回消息包括
| M1+0000000E | 当前设备播放的文件为0x0E |
| M2+0000000F | 当前设备的文件总数是0x0F,注意是合法的音频文件 |
| MT+0000001E | 当前文件的总时间为0x1E 秒 |
| MK+00000004 | 当前文件已经播放到了0x04秒 |
| MF+XXXXXXX | 当前播放的文件的名称是xxxxxx。这里文件名是完整的 |
上述指令基本能覆盖大部分需求。
2、移植AT指令引擎
a、在SDK中添加AT组件

b、在RTOS系统中添加一个AT处理任务服务

at_task程序如下所示
#include <string.h>
#include "type.h"
#include "app_config.h"
#include "rtos_api.h"
#include "app_message.h"
#include "debug.h"
#include "at_task.h"
#include "uarts.h"
#include "uarts_interface.h"
#include "AT_command.h"
#include "irqn.h"
#include "task.h"
#include "timers.h"
#include "FreeRTOS.h"
#include "timer.h"
#include "timeout.h"
#include "mode_task.h"
#include "bt_play_mode.h"#define AT_APP_TASK_STACK_SIZE 1024 // 512//1024#define AT_APP_TASK_PRIO 3TIMER TimerOut; //
xTaskHandle taskAtHandle;static uint8_t timeLockFlag = 0;ATAppContext AtAppCt;#define UART_RX_LEN 256
#define UART_TX_LEN 300/**\brief*/
typedef struct
{uint8_t buff[UART_RX_LEN];uint16_t lenth;uint8_t flag;uint8_t busy;uint8_t u8RxCnt;
} UART_STRUCT;static UART_STRUCT AtRxBuf;uint8_t AtTxBuff[UART_TX_LEN] = {0};static void AtAppInit(void);static void AtTaskEntrance(void *param)
{MessageContext msg;while (1){MessageRecv(AtAppCt.msgHandle, &msg, AT_APP_MSG_TIMEOUT);if(msg.msgId != MSG_NONE){switch(msg.msgId){case MSG_AT_UDISK_SONG_ALL_MSG:{AT_PPRINTF("\n");sprintf( AtTxBuff, "M1+%08X\r\n",AtAppCt.gMediaPlayer->CurFileIndex ); //当前索引AT_PPRINTF(AtTxBuff);vTaskDelay(1);sprintf( AtTxBuff, "M2+%08X\r\n",AtAppCt.gMediaPlayer->TotalFileSumInDisk ); //当前设备文件总数AT_PPRINTF(AtTxBuff);vTaskDelay(1);sprintf( AtTxBuff, "MK+%08X\r\n",AtAppCt.gMediaPlayer->CurPlayTime ); //当前播放时间AT_PPRINTF(AtTxBuff);sprintf( AtTxBuff, "MF+%s\r\n",AtAppCt.gMediaPlayer->file_longname ); //当前播放时间AT_PPRINTF(AtTxBuff);}break;case MSG_AT_UDISK_SONG_SIGNAL_MSG:{AT_PPRINTF("\n");sprintf( AtTxBuff, "M1+%08X\r\n",AtAppCt.gMediaPlayer->CurFileIndex ); //当前索引AT_PPRINTF(AtTxBuff);vTaskDelay(1);sprintf( AtTxBuff, "M2+%08X\r\n",AtAppCt.gMediaPlayer->TotalFileSumInDisk ); //当前设备文件总数AT_PPRINTF(AtTxBuff);vTaskDelay(1);sprintf( AtTxBuff, "MK+%08X\r\n",AtAppCt.gMediaPlayer->CurPlayTime ); //当前播放时间AT_PPRINTF(AtTxBuff);sprintf( AtTxBuff, "MF+%s\r\n",AtAppCt.gMediaPlayer->file_longname ); //当前播放时间AT_PPRINTF(AtTxBuff);}break;case MSG_AT_MODE_CON_BTAUDIO_IDEL_MSG: //蓝牙空闲模式{AT_PPRINTF("\n");sprintf( AtTxBuff, "TS+01\r\n"); //蓝牙模式AT_PPRINTF(AtTxBuff);sprintf( AtTxBuff, "QM+01\r\n"); //蓝牙模式AT_PPRINTF(AtTxBuff);}break;case MSG_AT_MODE_CON_BTAUDIO_PLAYING_MSG: //蓝牙模式{AT_PPRINTF("\n");sprintf( AtTxBuff, "TS+02\r\n"); //蓝牙播放音乐AT_PPRINTF(AtTxBuff);SysModeEnter(ModeBtAudioPlay);}break;case MSG_AT_MODE_CON_BTAUDIO_SUSPEND_MSG: //挂起蓝牙{AT_PPRINTF("\n");sprintf( AtTxBuff, "TS+01\r\n"); //蓝牙模式AT_PPRINTF(AtTxBuff);}break;case MSG_AT_MODE_CON_UDISK_MSG: //U盘模式{AT_PPRINTF("\n");sprintf( AtTxBuff, "MU+01\r\n"); //U盘插入AT_PPRINTF(AtTxBuff);sprintf( AtTxBuff, "QM+02\r\n"); //U盘模式AT_PPRINTF(AtTxBuff);AtStackServiceMsgSend(MSG_AT_UDISK_SONG_SIGNAL_MSG);//发送切换歌曲指令}break;case MSG_AT_MODE_CON_UDISK_OUT_MSG: //拔出U盘{AT_PPRINTF("\n");sprintf( AtTxBuff, "MU+02\r\n"); //U盘拔出AT_PPRINTF(AtTxBuff);sprintf( AtTxBuff, "QM+01\r\n"); //蓝牙模式AT_PPRINTF(AtTxBuff);SysModeEnter(ModeBtAudioPlay);}break;case MSG_AT_MODE_CON_AUX_MSG: //AUX模式{AT_PPRINTF("\n");sprintf( AtTxBuff, "QM+05\r\n"); //U盘模式AT_PPRINTF(AtTxBuff);SysModeEnter(ModeLineAudioPlay);}break;case MSG_AT_MODE_CON_IDEL_MSG: //空闲模式{AT_PPRINTF("\n");sprintf( AtTxBuff, "QM+00\r\n"); //U盘模式AT_PPRINTF(AtTxBuff);}break;}}if (timeLockFlag == 0 && IsTimeOut(&TimerOut)){timeLockFlag = 1;AtRxBuf.buff[AtRxBuf.u8RxCnt] = 0;AT_CMD_Process(AtRxBuf.buff, AtRxBuf.u8RxCnt);AtRxBuf.u8RxCnt = 0;}}
}static void AtUartReceive(void)
{AT_CMD_Process(AtRxBuf.buff, AtRxBuf.u8RxCnt);
}/***************************************************************************************** APIs**/
int32_t AtAppTaskStart(void)
{AtAppInit();APP_DBG("AtTask Create\n");TimeOutSet(&TimerOut, 20);xTaskCreate(AtTaskEntrance, "AtApp", AT_APP_TASK_STACK_SIZE, NULL, AT_APP_TASK_PRIO, &taskAtHandle);
}static void AtAppInit(void)
{memset(&AtAppCt, 0, sizeof(ATAppContext));AtAppCt.msgHandle = MessageRegister(AT_NUM_MESSAGE_QUEUE);
}void AtStackServiceMsgSend(uint16_t msgId)
{MessageContext msgSend;msgSend.msgId = msgId;MessageSend(AtAppCt.msgHandle, &msgSend);}
在主任务中启动at_task任务

3、运行调试

可以看出AT指令任务已经运行。
相关文章:
山景BP1048增加AT指令,实现单片机串口控制播放音乐(一)
1、设计目的 山景提供的SDK是蓝牙音箱demo,用户使用ADC按键或者IR遥控器,进行人机交互。然而现实很多场景,需要和单片机通信,不管是ADC按键或者IR接口都不适合和单片机通信。这里设计个AT指令用来和BP1048通信。AT指令如下图所示…...
SMMU软件指南SMMU编程之全局错误和最小配置
安全之安全(security)博客目录导读 目录 一、全局错误 二、最小配置 一、全局错误 与编程接口相关的全局错误会报告到适当的 SMMU_(*_)GERROR 寄存器,而不是通过基于内存的事件队列。这些错误通常是严重的,例如导致 SMMU 停止向前推进。例如…...
CPU条件下Pytorch、jupyter环境配置
一、创建虚拟环境 查看虚拟环境 conda env list 创建python虚拟环境 conda create -n minist python3.11 激活虚拟环境 conda activate minist 查看虚拟环境下有哪些包 pip list 二、安装pytorch 切换清华源 conda config --add channels https://mirrors.tuna.tsing…...
【自用】通信内网部署rzgxxt项目_01,后端pipeDemo部署(使用nssm.exe仿照nohup)
做完这些工作之后,不要忘记打开 Windows Server 的防火墙端口,8181、8081、8080、22、443、1521 做完这些工作之后,不要忘记打开 Windows Server 的防火墙端口,8181、8081、8080、22、443、1521 做完这些工作之后,不要…...
Ubuntu 安装实时内核指南
在运行需要高精度和低延迟响应的机器人驱动程序时,安装一个具备实时内核(Real-Time Kernel)的 Ubuntu 系统是至关重要的。若缺乏实时系统的支持,高频率的控制指令可能会导致机器人运动轨迹不流畅,甚至产生抖动现象。以…...
MySQL 主从复制与高可用
在现代分布式系统中,数据库的高可用性和可靠性至关重要。MySQL 提供了主从复制(Master-Slave Replication)机制来实现数据的冗余和容错,保证在主数据库发生故障时能够继续提供服务。而在此基础上,通过进一步的高可用架…...
RCE总结
文章目录 常见漏洞执行函数:1.系统命令执行函数2.代码执行函数 命令拼接符读取文件命令绕过:空格过滤绕过关键字绕过长度过滤绕过无参数命令执行绕过无字母数字绕过利用%0A截断利用回溯绕过利用create_function()代码注入无回显RCE1.反弹shell2.dnslog外…...
基于UNITY3D的照片墙演示项目技术分享
unity实现超大图片墙演示,由于拥有海量图片,使用了CPU 多线程,unity dots技术,图片组成文字部分,使用了点阵图技术,提取文字像素。 (关于点阵介绍) 点阵字体是把每一个字符都分成1616或2424个点…...
随手记:小程序兼容后台的wangEditor富文本配置链接
场景: 在后台配置wangEditor富文本,可以文字配置链接,图片配置链接,产生的json格式为: 例子: <h1><a href"https://uniapp.dcloud.net.cn/" target"_blank"><span sty…...
maven项目运行时NoSuchMethodError问题排查记录(依赖冲突解决)
控制台异常如下: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.apache.commons.io.input.BoundedInputStream.builder()Lorg/apache/commons/io/input/BoundedInputStream$Builder;问题明显,根据NoSuchMethodError…...
ECharts关系图-关系图11,附视频讲解与代码下载
引言: 关系图(或称网络图、关系网络图)在数据可视化中扮演着至关重要的角色。它们通过节点(代表实体,如人、物体、概念等)和边(代表实体之间的关系或连接)的形式,直观地…...
【C语言】动态内存管理:详解malloc和free函数
前言 在C语言编程中,动态内存分配是一个非常重要的概念。与静态内存分配不同,动态内存分配允许程序在运行时根据需要分配和释放内存,从而更加灵活地管理内存资源。特别是在一些数据结构的引用中经常需要使用,下面我们就详细讲解一…...
EGO Swarm翻译
目录 摘要 Ⅰ 介绍 Ⅱ 相关工作 A . 单四旋翼局部规划 B . 拓扑规划 C. 分布式无人机集群 Ⅲ 基于梯度的局部规划隐式拓扑轨迹生成 A.无需ESDF梯度的局部路径规划 B.隐式拓扑轨迹生成 Ⅳ 无人机集群导航 A 机间避碰 B. 定位漂移补偿 C. 从深度图像中去除agent Ⅴ …...
Linux根目录
在Linux系统中,文件系统遵循一种标准化的目录结构,即文件系统层次结构标准(Filesystem Hierarchy Standard,FHS)。 根目录(/) /bin:包含二进制可执行文件,通常是用户和系…...
SAP-SD-参照退货订单补货时带不出行项目
业务场景: 当物料出现质量问题时,客户需要换货,不需要退款,就需要先做退货订单,然后参照退货订单进行补货,创建补货订单,但是创建补货订单时只是把抬头数据带入补货订单,没有带入行项…...
12-C语言单向链表
一、链表的概述 1.链表与数组对比 遍历数组中的数据,查询数据比较方便,但往数组中插入、删除数据需要移动大量数据;相反。链表遍历、查询数据不方便,但是插入、删除数据比较方便,不需要移动大量数据,直接…...
2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题
2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题(选择题) 题目总数:5 总分数:50 选择题 第 1 题 单选题 Scratch运行以下程宇后,小兔子会( )。 A. 变小 B. 变大 C. 变色 D. …...
FFmpeg 4.3 音视频-多路H265监控录放C++开发二十一.2,RTP协议-RTP协议概述,协议详情
前提: 为什么要学习 RTP(Real-time Transport Protocol)重点 简介:RTP是一个实时传输媒体数据的协议,通常与RTSP一起使用。它负责在网络上传输音视频数据。特点:RTP通过UDP或TCP传输媒体数据,提供时间戳和序…...
Linux系统编程——系统内核中的信号
目录 一、前言 二、系统内核中的信号 三、sigset_t 四、信号集操作 1、sigpending(); 2、sigemptyset(); 3、sigfillset(sigset_t *set); 4、int sigaddset ()和sigdelset() 编辑 5、sigismember() 6、sigprocmask() 五、信号集操作代码演示 六、深入理解进程的信…...
delve调试环境搭建—golang
原文地址:delve调试环境搭建—golang – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 由于平时不用 IDE 开发环境,习惯在 linux终端vim 环境下开发,所以找了golang的调试工具,delve类似gdb的调试界…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
