山景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的调试界…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
Python学习(8) ----- Python的类与对象
Python 中的类(Class)与对象(Object)是面向对象编程(OOP)的核心。我们可以通过“类是模板,对象是实例”来理解它们的关系。 🧱 一句话理解: 类就像“图纸”,对…...
