STM32+HC05串口蓝牙设计简易的蓝牙音箱 您所在的位置:网站首页 蓝牙mp3如何连接手机播放 STM32+HC05串口蓝牙设计简易的蓝牙音箱

STM32+HC05串口蓝牙设计简易的蓝牙音箱

2024-06-22 03:11| 来源: 网络整理| 查看: 265

一、环境介绍

MCU:  STM32F103C8T6

蓝牙模块:  HC05 (串口蓝牙)

音频解码模块:  VS1053B 

OLED显示屏:  0.96寸SPI接口OLED

开发软件: Keil5

上位机: 使用QT设计Android端APP

二、功能介绍

Android手机打开APP,设置好参数之后,选择音乐文件发送给蓝牙音箱设备端,HC05蓝牙收到数据之后,再传递给VS1053进行播放。程序里采用环形缓冲区,接收HC05蓝牙传递的数据,设置好传递的参数之后,基本播放音乐是很流畅的。

完整项目源码下载地址:  https://download.csdn.net/download/xiaolong1126626497/18621270

三、硬件实物

VS1053可以接耳机或者接音箱设备即可听音乐。

四、设置HC05蓝牙波特率

HC05蓝牙串口默认波特率是38400,为了提高蓝牙传输速率,需要修改波特率为: 921600。

五、APP端界面

 

六、设备端:核心代码  6.1  mian.cpp

 

#include "stm32f10x.h" #include "led.h" #include "key.h" #include "oled.h" #include "usart.h" #include #include "sdcard.h" #include "ff.h" #include "vs1053b.h" #include "timer.h" #include "hc05_Bluetooth.h" //文件系统工作区注册 FATFS FatFs; //函数声明 u8 VS1053_PlayOneMusic(u8 *pname); u8 VS1053_ScanDirPlayMusic(const char *path); //存放OLED显示屏滚动显示的提示语句 u8 oled_show_buff[50]; u8 *oled_data_p; //蓝牙音乐的缓冲区 #define MUSIC_BUFF_LEN 1024*5 //音乐数据缓冲区大小 u32 rev_len=0; u32 play_len=0; u8 musicbuff[MUSIC_BUFF_LEN]; u8 flagbuff[MUSIC_BUFF_LEN]; u8 music_byte; /* 使用STM32F103C8T6最小系统板编写的代码----买的那种 */ //中文字库路径: 0:/font/gbk16.DZK //本地是1 //蓝牙是2 int main(void) { LED_Init(); KEY_Init(); USART_X_Init(USART1,72,115200); OLED_Init(); OLED_Clear(0xFF); OLED_Refresh_GRAM(); printf("SD卡初始化状态:%d\r\n",SDCardDeviceInit()); //初始化SD卡 f_mount(&FatFs,"0:", 0); //注册工作区 VS1053_Init(); //VS1053初始化 printf("正常工作.\r\n"); if(KEY_UP==0) //按键已经按下 //播放蓝牙音乐数据 { u32 hc05_rx_state=1; VS1053_Reset(); //硬复位MP3 VS1053_SoftReset(); //软复位VS10XX VS1053_SetVol(250); //设置音量 最大值 VS1053_PlayOneMusic((u8*)"0:/2.mp3"); //蓝牙语音提示 strncpy((char*)oled_show_buff," Play HCO5 Bluetooth music ",100); /*1. 初始化HC05串口蓝牙*/ printf("1 蓝牙正在初始化.........\r\n"); USART2_RX_FLAG=0; while(HC05_Bluetooth_Init()){} // /*设置当前蓝牙为从机模式*/ HC05_Bluetooth_SetCmd("AT+ROLE=0\r\n"); //设置为从机模式 if(HC05_Bluetooth_GetRoleStatus()==0)printf("当前蓝牙处于从机状态!\r\n"); else if(HC05_Bluetooth_GetRoleStatus()==1)printf("当前蓝牙处于主机状态!\r\n"); HC05_Bluetooth_SetCmd("AT+RESET\r\n"); //复位ATK-HC05模块 DelayMs(1000); //等待蓝牙模块稳定 /*2. 查询蓝牙主从状态*/ if(HC05_Bluetooth_GetRoleStatus()==0)printf("2 当前蓝牙处于从机状态!\r\n"); else if(HC05_Bluetooth_GetRoleStatus()==1)printf("2 当前蓝牙处于主机状态!\r\n"); else printf("2 当前蓝牙主从状态查询失败!\r\n"); /*3. 查看蓝牙连接状态*/ if(HC05_LED)printf("3 当前蓝牙连接成功!\r\n"); else printf("3 当前蓝牙未连接!\r\n"); /*4. 设置蓝牙的名称*/ if(HC05_Bluetooth_SetCmd("AT+NAME=wbyq666_HC-05\r\n"))printf("4 蓝牙名称设置失败!\r\n"); else printf("4 蓝牙名称设置为 wbyq666_HC-05 \r\n"); /*5. 设置蓝牙配对密码*/ if(HC05_Bluetooth_SetCmd("AT+PSWD=1234\r\n"))printf("5 蓝牙配对密码设置失败!\r\n"); //密码必须是4位 else printf("5 蓝牙配对密码设置为 1234 \r\n"); //if(HC05_Bluetooth_SetCmd("AT+UART=921600,0,0\r\n"))printf("5 蓝牙波特率设置成功!\r\n"); //密码必须是4位 //else printf("5 蓝牙波特率设置失败!\r\n\r\n"); /*6. 等待蓝牙连接*/ printf("等待蓝牙连接.....\r\n"); while(!HC05_LED){} printf("当前蓝牙连接成功! 进入到数据透传模式\r\n"); //蓝牙连接成功 USART2->CR1&=~(1lineEdit_Timer->setText(QString::number(FileSendTime)); FileSendCnt=32; //默认每包数据值32字节 ui->lineEdit_SendFileCnt->setText(QString::number(FileSendCnt)); //创建存放音乐文件的目录 QDir dir; if(dir.mkpath("/sdcard/WBYQ_MP3")) { ui->plainTextEdit->insertPlainText("/WBYQ_MP3 目录创建成功!\n"); } else { ui->plainTextEdit->insertPlainText("/WBYQ_MP3 目录创建失败!\n"); } MusicFileDir="assets:/nansannan.mp3"; //目录的路径 Def_MusicName="assets:/nansannan.mp3"; file.setFileName(Def_MusicName); //设置文件名称 ui->lineEdit_MusicName->setText(Def_MusicName); //默认文件名称 } int count=0; //更新 void MainWindow::update() { if(SendStat) { int len; if(file.atEnd()==false) //文件未结束 { len=file.read(FileBuff,FileSendCnt); len=socket->write(FileBuff,len); //发送数据 } else { file.close(); timer->stop(); //停止定时器 SendStat=0; ui->plainTextEdit->setPlainText("文件读取写入完毕!\n"); } } } MainWindow::~MainWindow() { delete ui; delete discoveryAgent; delete localDevice; delete socket; timer->stop(); delete timer; } void MainWindow::on_pushButton_CloseBluetooth_clicked() { /*关闭蓝牙设备*/ localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff); } void MainWindow::on_pushButton_BluetoothScan_clicked() { /*3.1 检查蓝牙是否开启*/ if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) { /*请求打开蓝牙设备*/ localDevice->powerOn(); } /*开始扫描周围的蓝牙设备*/ discoveryAgent->start(); ui->comboBox_BluetoothDevice->clear(); //清除条目 } void MainWindow::on_pushButton_DeviceVisible_clicked() { /*设置蓝牙可见,可以被周围的设备搜索到,在Android上,此模式最多只能运行5分钟。*/ // localDevice->setHostMode( QBluetoothLocalDevice::HostDiscoverable); static bool cnt=1; cnt=!cnt; if(cnt) { MusicFileDir="assets:/nansannan.mp3"; //目录的路径 QMessageBox::information(this,"提示","路径切换为内部路径!\n请选择文件!",QMessageBox::Ok,QMessageBox::Ok); } else { MusicFileDir="/mnt/sdcard"; //目录的路径 QMessageBox::information(this,"提示","路径切换为SD路径!\n请选择文件!",QMessageBox::Ok,QMessageBox::Ok); } } void MainWindow::on_pushButton_StopScan_clicked() { /*停止扫描周围的蓝牙设备*/ discoveryAgent->stop(); } /*当扫描到周围的设备时会调用当前的槽函数*/ void MainWindow::addBlueToothDevicesToList(const QBluetoothDeviceInfo &info) { // QString label = QString("%1 %2").arg(info.name()).arg(info.address().toString()); QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name()); ui->comboBox_BluetoothDevice->addItem(label); //添加字符串到comboBox上 } //有数据可读 void MainWindow::readBluetoothDataEvent() { QByteArray all = socket->readAll(); ui->plainTextEdit->insertPlainText(all); } //建立连接 void MainWindow::bluetoothConnectedEvent() { QMessageBox::information(this,tr("连接提示"),"蓝牙连接成功!"); ConnectStat=1; /*停止扫描周围的蓝牙设备*/ discoveryAgent->stop(); } //断开连接 void MainWindow::bluetoothDisconnectedEvent() { ConnectStat=0; QMessageBox::information(this,tr("连接提示"),"蓝牙断开连接!"); } /* 在说蓝牙设备连接之前,不得不提一个非常重要的概念,就是蓝牙的Uuid,引用一下百度的: 在蓝牙中,每个服务和服务属性都唯一地由"全球唯一标识符" (UUID)来校验。 正如它的名字所暗示的,每一个这样的标识符都要在时空上保证唯一。 UUID类可表现为短整形(16或32位)和长整形(128位)UUID。 他提供了分别利用String和16位或32位数值来创建类的构造函数,提供了一个可以比较两个UUID(如果两个都是128位)的方法,还有一个可以转换一个UUID为一个字符串的方法。 UUID实例是不可改变的(immutable),只有被UUID标示的服务可以被发现。 在Linux下你用一个命令uuidgen -t可以生成一个UUID值; 在Windows下则执行命令uuidgen 。UUID看起来就像如下的这个形式:2d266186-01fb-47c2-8d9f-10b8ec891363。当使用生成的UUID去创建一个UUID对象,你可以去掉连字符。 */ //发送音乐文件 void MainWindow::on_pushButton_SendData_clicked() { if(ConnectStat) { if(file.open(QIODevice::ReadOnly)) { SendStat=1; count=0; ui->plainTextEdit->insertPlainText("系统提示: 开始发送文件!\n"); ui->lineEdit_fileSizef->setText(QString::number(file.size())); ui->lineEdit_fileCount->setText(""); ui->progressBar_SendCount->setMaximum(file.size()); //设置进度条显示最大值 ui->progressBar_SendCount->setValue(0); //设置进度条的值 timer->start(FileSendTime); //启动定时器 } } } //连接蓝牙 void MainWindow::on_pushButton_ConnectDev_clicked() { QString text = ui->comboBox_BluetoothDevice->currentText(); int index = text.indexOf(' '); if(index == -1) return; QBluetoothAddress address(text.left(index)); QString connect_device="开始连接蓝牙设备:\n"; connect_device+=ui->comboBox_BluetoothDevice->currentText(); QMessageBox::information(this,tr("连接提示"),connect_device); //开始连接蓝牙设备 socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite); } //帮助提示 void MainWindow::on_pushButton_help_clicked() { QMessageBox::information(this,tr("帮助提示"),"本软件用于HC-05/06系列串口蓝牙连接!\n" "暂时不支持BLE4.0版本蓝牙!\n" "用于发送音乐文件数据,每次发送32字节,默认100ms发送间隔时间\n" "软件作者:DS小龙哥\n" "BUG反馈:[email protected]"); } //选择音乐文件 void MainWindow::on_pushButton_select_clicked() { QString filename=QFileDialog::getOpenFileName(this,"选择发送的音乐文件",MusicFileDir,tr("*.mp3 *.MP3 *.WAV")); //filename==选择文件的绝对路径 file.setFileName(filename); ui->lineEdit_MusicName->setText(filename); Def_MusicName=filename; //保存文件名称 } //清除 void MainWindow::on_pushButton_clear_clicked() { ui->plainTextEdit->setPlainText(""); } void MainWindow::on_pushButton_StopSend_clicked() { timer->stop(); //停止定时器 } //设置发送间隔时间 void MainWindow::on_pushButton_SendTime_clicked() { QString str=ui->lineEdit_Timer->text(); int time=str.toInt(); FileSendTime=time; //保存时间 if(timeplainTextEdit->insertPlainText(tr("设置发送间隔时间为%1ms\n").arg(time)); } //修改每包发送的数量 void MainWindow::on_pushButton_SendFileCnt_clicked() { QString str=ui->lineEdit_SendFileCnt->text(); int cnt=str.toInt(); if(cnt>4096 || cntplainTextEdit->insertPlainText(tr("发送数量设置为%1字节.\n").arg(cnt)); } } //写成功的数量 void MainWindow::bluetoothbytesWritten(qint64 byte) { count+=byte; ui->lineEdit_fileCount->setText(QString::number(count)); ui->progressBar_SendCount->setValue(count); //设置进度条的值 } 7.3  mianwindows.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include "QListWidgetItem" #include #include "QFile" #include "QFileDialog" #include "QTimer" #include "QInputDialog" #include #include namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); QFile file; QTimer *timer; bool ConnectStat; bool SendStat; QBluetoothDeviceDiscoveryAgent *discoveryAgent; //这个是指扫描周围蓝牙设备! QBluetoothLocalDevice *localDevice;//是指配置获取设备的蓝牙状态信息等! QBluetoothSocket *socket; //指进行链接蓝牙设备,读写信息! int FileSendTime; //文件发送时间 char FileBuff[4096]; //每包最大的字节数 int FileSendCnt; //每次发送的字节数 QString Def_MusicName; QString MusicFileDir; private slots: void on_pushButton_CloseBluetooth_clicked(); void on_pushButton_BluetoothScan_clicked(); void addBlueToothDevicesToList(const QBluetoothDeviceInfo&); //发现蓝牙设备的槽函数 void on_pushButton_DeviceVisible_clicked(); void on_pushButton_StopScan_clicked(); void readBluetoothDataEvent(); void bluetoothConnectedEvent(); void bluetoothDisconnectedEvent(); void on_pushButton_SendData_clicked(); void SetStyle(const QString &qssFile); //样式表设置函数 void on_pushButton_ConnectDev_clicked(); void on_pushButton_help_clicked(); void on_pushButton_select_clicked(); void on_pushButton_clear_clicked(); void on_pushButton_StopSend_clicked(); void on_pushButton_SendTime_clicked(); void on_pushButton_SendFileCnt_clicked(); void bluetoothbytesWritten(qint64 byte); public slots: void update(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H

 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有