精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32 + HC05串口藍(lán)牙設(shè)計(jì)簡(jiǎn)易的藍(lán)牙音箱

DS小龍哥-嵌入式技術(shù) ? 來(lái)源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2022-02-28 13:59 ? 次閱讀

?

一、環(huán)境介紹

MCU:STM32F103C8T6

藍(lán)牙模塊: HC05 (串口藍(lán)牙)

音頻解碼模塊: VS1053B

OLED顯示屏: 0.96寸SPI接口OLED

開發(fā)軟件:Keil5

上位機(jī):使用QT設(shè)計(jì)Android端APP

二、功能介紹

Android手機(jī)打開APP,設(shè)置好參數(shù)之后,選擇音樂(lè)文件發(fā)送給藍(lán)牙音箱設(shè)備端,HC05藍(lán)牙收到數(shù)據(jù)之后,再傳遞給VS1053進(jìn)行播放。程序里采用環(huán)形緩沖區(qū),接收HC05藍(lán)牙傳遞的數(shù)據(jù),設(shè)置好傳遞的參數(shù)之后,基本播放音樂(lè)是很流暢的。

三、硬件實(shí)物

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

VS1053可以接耳機(jī)或者接音箱設(shè)備即可聽音樂(lè)。

四、設(shè)置HC05藍(lán)牙波特率

HC05藍(lán)牙串口默認(rèn)波特率是38400,為了提高藍(lán)牙傳輸速率,需要修改波特率為: 921600。

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

五、APP端界面

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

六、設(shè)備端:核心代碼

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" 

//文件系統(tǒng)工作區(qū)注冊(cè)
FATFS FatFs;

//函數(shù)聲明
u8 VS1053_PlayOneMusic(u8 *pname);
u8 VS1053_ScanDirPlayMusic(const char *path);

//存放OLED顯示屏滾動(dòng)顯示的提示語(yǔ)句
u8 oled_show_buff[50];
u8 *oled_data_p; 

//藍(lán)牙音樂(lè)的緩沖區(qū)
#define MUSIC_BUFF_LEN 1024*5	//音樂(lè)數(shù)據(jù)緩沖區(qū)大小
u32 rev_len=0;
u32 play_len=0;
u8 musicbuff[MUSIC_BUFF_LEN];
u8 flagbuff[MUSIC_BUFF_LEN];
u8 music_byte;
	

/*
                       使用STM32F103C8T6最小系統(tǒng)板編寫的代碼----買的那種
*/

//中文字庫(kù)路徑: 0:/font/gbk16.DZK
//本地是1
//藍(lán)牙是2
int main(void)
{
	LED_Init();
	KEY_Init();
	USART_X_Init(USART1,72,115200);
	OLED_Init();
	OLED_Clear(0xFF);
	OLED_Refresh_GRAM();
	printf("SD卡初始化狀態(tài):%d\r\n",SDCardDeviceInit()); //初始化SD卡
	f_mount(&FatFs,"0:", 0);      //注冊(cè)工作區(qū)
	VS1053_Init();       					//VS1053初始化
	printf("正常工作.\r\n");
    
	if(KEY_UP==0) //按鍵已經(jīng)按下 		//播放藍(lán)牙音樂(lè)數(shù)據(jù)
	{
		u32 hc05_rx_state=1;
		VS1053_Reset();      								//硬復(fù)位MP3
		VS1053_SoftReset(); 								//軟復(fù)位VS10XX
		VS1053_SetVol(250);								  //設(shè)置音量  最大值
		VS1053_PlayOneMusic((u8*)"0:/2.mp3"); //藍(lán)牙語(yǔ)音提示
		
		strncpy((char*)oled_show_buff,"   Play HCO5 Bluetooth music         ",100);
		
		/*1. 初始化HC05串口藍(lán)牙*/
		printf("1 藍(lán)牙正在初始化.........\r\n");
		USART2_RX_FLAG=0;
		while(HC05_Bluetooth_Init()){}
		
//		/*設(shè)置當(dāng)前藍(lán)牙為從機(jī)模式*/
		HC05_Bluetooth_SetCmd("AT+ROLE=0\r\n"); //設(shè)置為從機(jī)模式
		if(HC05_Bluetooth_GetRoleStatus()==0)printf("當(dāng)前藍(lán)牙處于從機(jī)狀態(tài)!\r\n");
		else if(HC05_Bluetooth_GetRoleStatus()==1)printf("當(dāng)前藍(lán)牙處于主機(jī)狀態(tài)!\r\n");
		HC05_Bluetooth_SetCmd("AT+RESET\r\n");	//復(fù)位ATK-HC05模塊
		DelayMs(1000);			//等待藍(lán)牙模塊穩(wěn)定
			
		/*2. 查詢藍(lán)牙主從狀態(tài)*/
		if(HC05_Bluetooth_GetRoleStatus()==0)printf("2 當(dāng)前藍(lán)牙處于從機(jī)狀態(tài)!\r\n");
		else if(HC05_Bluetooth_GetRoleStatus()==1)printf("2 當(dāng)前藍(lán)牙處于主機(jī)狀態(tài)!\r\n");
		else printf("2 當(dāng)前藍(lán)牙主從狀態(tài)查詢失敗!\r\n");
	
		/*3. 查看藍(lán)牙連接狀態(tài)*/
		if(HC05_LED)printf("3 當(dāng)前藍(lán)牙連接成功!\r\n");
		else printf("3 當(dāng)前藍(lán)牙未連接!\r\n");
		
		/*4. 設(shè)置藍(lán)牙的名稱*/
		if(HC05_Bluetooth_SetCmd("AT+NAME=wbyq666_HC-05\r\n"))printf("4 藍(lán)牙名稱設(shè)置失敗!\r\n");
		else printf("4 藍(lán)牙名稱設(shè)置為 wbyq666_HC-05 \r\n");
		
		/*5. 設(shè)置藍(lán)牙配對(duì)密碼*/
		if(HC05_Bluetooth_SetCmd("AT+PSWD=1234\r\n"))printf("5 藍(lán)牙配對(duì)密碼設(shè)置失敗!\r\n"); //密碼必須是4位
		else printf("5 藍(lán)牙配對(duì)密碼設(shè)置為 1234 \r\n");
		
		
		//if(HC05_Bluetooth_SetCmd("AT+UART=921600,0,0\r\n"))printf("5 藍(lán)牙波特率設(shè)置成功!\r\n"); //密碼必須是4位
		//else printf("5 藍(lán)牙波特率設(shè)置失敗!\r\n\r\n");
		
		/*6. 等待藍(lán)牙連接*/
		printf("等待藍(lán)牙連接.....\r\n");
		while(!HC05_LED){}
		printf("當(dāng)前藍(lán)牙連接成功! 進(jìn)入到數(shù)據(jù)透?jìng)髂J絓r\n");
		
		//藍(lán)牙連接成功
		USART2->CR1&=~(1<<5);//關(guān)閉串口2接收中斷
		TIM2->CR1&=~(1<<0);  //關(guān)閉定時(shí)器2
		USART1->CR1&=~(1<<5);//關(guān)閉串口1接收中斷
		
	  VS1053_XDCS=0; 
	//VS1053_XDCS=1;
		while(1)
		{	
			if(USART2->SR&(1<<5)) 
			{
				music_byte=USART2->DR;
				if(flagbuff[rev_len]==0)			//可以接收
				{
					musicbuff[rev_len]=music_byte;
					flagbuff[rev_len]=1;			//設(shè)置接收標(biāo)志
					rev_len++;
				}
				if(rev_len>=MUSIC_BUFF_LEN)		//緩沖區(qū)滿
				{
					rev_len=0;				
				}
			}
			if(flagbuff[play_len]==1)			//可以播放
			{
				if(VS1053_DREQ!=0)  
				{
					VS1053_SPI_ReadWriteByte(musicbuff[play_len]);//播放一個(gè)字節(jié)音頻
					flagbuff[play_len]=0;			//置接已播放標(biāo)志
					play_len++;
				}
			}
			if(play_len>=MUSIC_BUFF_LEN)	
			{
				play_len=0;				
			}
		}	
	}
	else  //沒(méi)有按下,播放本地SD卡音樂(lè)數(shù)據(jù)
	{
        printf("播放本地音樂(lè).\r\n");
        TIM1_Init(7200,3000);					//定時(shí)器用于滾動(dòng)顯示OLED顯示屏的提示語(yǔ)句(); 
        printf("準(zhǔn)備播放本地音樂(lè)提示音:\r\n");        
        VS1053_PlayOneMusic((u8*)"0:/1.mp3");//藍(lán)牙語(yǔ)音提示
        strncpy((char*)oled_show_buff,"   Play local music         ",100);
        printf("準(zhǔn)備循環(huán)播放本地音樂(lè).\r\n");  
        while(1)
        {
             VS1053_ScanDirPlayMusic("0:/mp3");  //循環(huán)掃描目錄播放音樂(lè)文件
        }
	}
}


/*
函數(shù)名稱: TIM1_UP_IRQHandler
函數(shù)功能: 定時(shí)器1的更新中斷服務(wù)函數(shù)
*/		
void TIM1_UP_IRQHandler(void)
{
    static u8 *p=oled_show_buff;
    static u32 data1[]={1,3,5,1,2,1,2,1,4,1,2,1,1,4,1,1};
    static u8 x=0;
    u8 i=0;
    u32 cnt=0;
    TIM1->SR=0;
    for(i=0;i<16;i++)
    {
        data1[i]=rand()%6;
    }

    if(*p=='\0')p=oled_show_buff;
    cnt=OLED_DisplayString(x,48,16,p);
    if(x==0 && cnt<16)OLED_DisplayString(128-(16-cnt)*8,48,16,oled_show_buff);
    if(x!=0)x-=8;
    else 
    {
        if(*p>80)p+=2;
        else p++;
    }

    OLED_DisplayData_MP3_Check(16,44,data1);
    OLED_DrawBMP(0,0,16,7,(u8 *)SignalTower);
    OLED_DrawBMP(88,0,16,9,(u8 *)Messages);
    OLED_DrawBMP(109,0,24,7,(u8 *)Battery);
    OLED_Refresh_GRAM();
    OLED_Clear_GRAM();
}

/*
函數(shù)功能: 播放一曲指定的歌曲				     	   									    	 
返 回 值: 0,正常播放完成
*/
u8 VS1053_PlayOneMusic(u8 *pname)
{	 
 	FIL fmp3;
  u16 br;
	u8 res,rval;	  
	u8 databuf[4096];	   		   
	u16 i=0;

	VS1053_Reset();      								//硬復(fù)位MP3
	VS1053_SoftReset(); 								//軟復(fù)位VS10XX
	VS1053_SetVol(250);								  //設(shè)置音量  最大值
	res=f_open(&fmp3,(const TCHAR*)pname,FA_READ);//打開文件	 
	if(res!=0)return 1;  //文件打開失敗 
	printf("%s文件打開成功!\r\n",pname);				   
	while(1)
	{
		res=f_read(&fmp3,databuf,4096,(UINT*)&br);//讀出4096個(gè)字節(jié)  
		i=0;
		while(i<4096) //每次播放4096個(gè)字節(jié)
		{  	
				if(VS1053_SendMusicData(databuf+i)==0)//給VS10XX發(fā)送音頻數(shù)據(jù)
				{
					i+=32;
				}
		}
		if(br!=4096||res!=0)
		{
			rval=0;
			break;//讀完了.		  
		} 							 
	}
    printf("%s音樂(lè)文件播放完畢.\r\n",pname);
	f_close(&fmp3);	  
	return rval;	  	 		  	    
}


/*
函數(shù)功能: 掃描音樂(lè)播放目錄下的音樂(lè)數(shù)據(jù)
0表示成功 1表示失敗
*/
u8 VS1053_ScanDirPlayMusic(const char *path)
{
    DIR dir;
    FRESULT res; 
    FILINFO fno; //存放讀取的文件信息
    char *abs_path=NULL;  
    
    /*1. 打開目錄*/    
    res=f_opendir(&dir,path);
    if(res!=FR_OK)return res;
    
    /*2. 循環(huán)讀取目錄*/
     while(1)
     {
        res=f_readdir(&dir,&fno);
        if(fno.fname[0] == 0 || res!=0)break;
        printf("文件名稱: %s,文件大小: %ld 字節(jié)\r\n",fno.fname,fno.fsize);

        /*過(guò)濾目錄*/
       // if(strstr(fno.fname,".MP3"))
        {
            //申請(qǐng)存放文件名稱的長(zhǎng)度
            abs_path=malloc(strlen(path)+strlen(fno.fname)+1);
            if(abs_path==NULL)break;
             
            strcpy(abs_path,path);
            strcat(abs_path,"/");
            strcat(abs_path,fno.fname);
          
            printf("abs_path=%s\n",abs_path);
            VS1053_PlayOneMusic((u8*)abs_path);     //播放音樂(lè)
            free(abs_path);
        }
    }
    
    /*3. 關(guān)閉目錄*/
    f_closedir(&dir);
    return 0;
}

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

6.2 hc05.c

#include "delay.h" 			 
#include "usart.h" 			  			 
#include "hc05_Bluetooth.h" 
#include "led.h" 
#include "string.h"	
#include "timer.h"

/*
函數(shù)功能:初始化ATK-HC05模塊
返 回 值:0,成功;1,失敗.
HC05_KEY--PB8---推挽輸出模式
HC05_LED--PB9---上下拉輸入模式
*/
u8 HC05_Bluetooth_Init(void)
{
	/*1. 基本初始化*/
	RCC->APB2ENR|=1<<3;     //使能PORTB時(shí)鐘 
	GPIOB->CRH&=0xFFFFFF00;
	GPIOB->CRH|=0x00000083;	
 	USART_X_Init(USART2,36,921600);//初始化串口3為:921600,波特率
	TIM2_Init(72,20000);
	
	/*2. 檢測(cè)HC05是否正常*/
	if(HCO5_SendCmd("AT\r\n","OK"))
	{
		printf("初始化失敗!\n");
        return 1;
	}		
	return 0;	 //檢測(cè)成功
}


/*
函數(shù)功能: 向HC05發(fā)送指令,并且查找返回值
返 回 值: 0表示成功  1表示失敗
*/
u8 HCO5_SendCmd(char *cmd,char *str)
{
	u32 i,j;
	for(i=0;i<5;i++)
	{
		USART2_RX_FLAG=0;
		USART2_RX_CNT=0;
		memset(USART2_RX_BUFF,0,sizeof(USART2_RX_BUFF));
		HC05_KEY=1;							//KEY置高,進(jìn)入AT模式
		delay_ms(10);
		USART_X_SendString(USART2,cmd);
		HC05_KEY=0;								//KEY拉低,退出AT模式
		for(j=0;j<500;j++)
		{
				delay_ms(30);
				if(USART2_RX_FLAG) //收到數(shù)據(jù)
				{
						USART2_RX_BUFF[USART2_RX_CNT]='\0';
						if(strstr((char*)USART2_RX_BUFF,str))
						{
								return 0; //查找正確
						}else break;
				}
		}
	}
	return 1;
}


/*
函數(shù)  功能:獲取ATK-HC05模塊的角色(主/從)狀態(tài)
函數(shù)返回值:0,從機(jī);
					  1,主機(jī);
            2,獲取失敗.	
*/						  
u8 HC05_Bluetooth_GetRoleStatus(void)
{	 		    
	u8 cnt=15;
	u8 len,t;
	while(cnt--)
	{
		HC05_KEY=1;					//KEY置高,進(jìn)入AT模式
		DelayMs(10);
		USART_X_SendString(USART2,"AT+ROLE?\r\n");	//查詢角色
		for(t=0;t<20;t++) 			 		//最長(zhǎng)等待200ms,來(lái)接收HC05模塊的回應(yīng)
		{
			DelayMs(10);
			if(USART2_RX_FLAG)break; 	//接收到一次數(shù)據(jù)了
		}
		HC05_KEY=0;									//KEY拉低,退出AT模式
		len=USART2_RX_CNT;						//得到接收數(shù)據(jù)的長(zhǎng)度
		USART2_RX_CNT=0;             //清空接收數(shù)量
		USART2_RX_FLAG=0;            //清空接收狀態(tài)
		if(len==13&&USART2_RX_BUFF[0]=='+')//接收到正確的應(yīng)答了
		{
			len=USART2_RX_BUFF[6]-'0';//得到主從模式值
			return len;
		}
	}
	return 2;//查詢失敗
}


/*
函數(shù)功能:ATK-HC05設(shè)置命令
說(shuō)    明:此函數(shù)用于設(shè)置ATK-HC05,適用于僅返回OK應(yīng)答的AT指令
函數(shù)參數(shù):atstr:AT指令串。 比如:"AT+RESET"/"AT+UART=9600,0,0"/"AT+ROLE=0"等字符串
返 回 值:0,設(shè)置成功;其他,設(shè)置失敗.	
*/						  
u8 HC05_Bluetooth_SetCmd(char* atstr)
{	 		    
	u8 cnt=0X0F;
	u8 len,t;
	while(cnt--)
	{
		HC05_KEY=1;							//KEY置高,進(jìn)入AT模式
		DelayMs(10);
		USART_X_SendString(USART2,atstr);	//發(fā)送AT字符串
		HC05_KEY=0;							//KEY拉低,退出AT模式
		for(t=0;t<20;t++) 			//最長(zhǎng)等待100ms,來(lái)接收HC05模塊的回應(yīng)
		{
			if(USART2_RX_FLAG)break;
			DelayMs(5);
		}		
		len=USART2_RX_CNT;	//得到數(shù)據(jù)長(zhǎng)度
		USART2_RX_FLAG=0;	//清空接收狀態(tài)
		USART2_RX_CNT=0;		//清空接收數(shù)量
		if(len==4&&USART2_RX_BUFF[0]=='O')//接收到正確的應(yīng)答了
		{			
			return 0; //設(shè)置成功
		}				
	}
	return 1; //設(shè)置失敗
}

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

6.3 vs1053.c

#include "vs1053b.h"	

/*
函數(shù)功能:移植接口--SPI時(shí)序讀寫一個(gè)字節(jié)
函數(shù)參數(shù):data:要寫入的數(shù)據(jù)
返 回 值:讀到的數(shù)據(jù)
*/
u8 VS1053_SPI_ReadWriteByte(u8 tx_data)
{			  	 
	u8 rx_data=0;				 
  u8 i;
  for(i=0;i<8;i++)
	{
		VS1053_SCLK=0;  
		if(tx_data&0x80){VS1053_OUTPUT=1;}
		else {VS1053_OUTPUT=0;}
		tx_data<<=1;	
		VS1053_SCLK=1;
		rx_data<<=1;
		if(VS1053_INPUT)rx_data|=0x01;
	}
	return rx_data; 
}


/*
函數(shù)功能:初始化VS1053的IO口	 
*/
void VS1053_Init(void)
{
	 RCC->APB2ENR|=1<<0;
	 AFIO->MAPR&=~(0x7<<24);  //釋放PA13/14/15
	 AFIO->MAPR|=0x4<<24;
	
	 RCC->APB2ENR|=1<<2;
	 RCC->APB2ENR|=1<<3;
	 
	 GPIOA->CRH&=0x00000FFF;
	 GPIOA->CRH|=0x33338000;
	  
	 GPIOB->CRL&=0xFFF00FFF;
	 GPIOB->CRL|=0x00083000;
	
	 VS1053_SCLK=1;
	 VS1053_XCS=1;
}	


/*
函數(shù)功能:軟復(fù)位VS10XX
*/
void VS1053_SoftReset(void)
{	 
	u8 retry=0;  				   
	while(VS1053_DREQ==0); 							//等待軟件復(fù)位結(jié)束	   
	VS1053_SPI_ReadWriteByte(0Xff);			//啟動(dòng)傳輸
	retry=0;
	while(VS1053_ReadReg(SPI_MODE)!=0x0800)	// 軟件復(fù)位,新模式  
	{
		VS1053_WriteCmd(SPI_MODE,0x0804);		// 軟件復(fù)位,新模式	    
		DelayMs(2);//等待至少1.35ms 
		if(retry++>100)break; 	  
	}	
	while(VS1053_DREQ==0);//等待軟件復(fù)位結(jié)束	 
	retry=0;
	while(VS1053_ReadReg(SPI_CLOCKF)!=0X9800)//設(shè)置VS10XX的時(shí)鐘,3倍頻 ,1.5xADD 
	{
		VS1053_WriteCmd(SPI_CLOCKF,0X9800);	//設(shè)置VS10XX的時(shí)鐘,3倍頻 ,1.5xADD
		if(retry++>100)break; 	    
	}	 
	DelayMs(20);
} 


/*
函數(shù) 功 能:硬復(fù)位MP3
函數(shù)返回值:1:復(fù)位失敗;0:復(fù)位成功	
*/
u8 VS1053_Reset(void)
{
	u8 retry=0;
	VS1053_RESET=0;
	DelayMs(20);
	VS1053_XDCS=1;//取消數(shù)據(jù)傳輸
	VS1053_XCS=1; //取消數(shù)據(jù)傳輸
	VS1053_RESET=1;	   
	while(VS1053_DREQ==0&&retry<200)//等待DREQ為高
	{
		retry++;
		DelayUs(50);
	};
	DelayMs(20);	
	if(retry>=200)return 1;
	else return 0;	    		 
}


/*
函數(shù)功能:向VS10XX寫命令
函數(shù)參數(shù):
				address:命令地址
				data   :命令數(shù)據(jù)
*/
void VS1053_WriteCmd(u8 address,u16 data)
{  
	while(VS1053_DREQ==0);	//等待空閑		   	   
	VS1053_XDCS=1; 	 
	VS1053_XCS=0; 	 
	VS1053_SPI_ReadWriteByte(VS_WRITE_COMMAND);//發(fā)送VS10XX的寫命令
	VS1053_SPI_ReadWriteByte(address); 	//地址
	VS1053_SPI_ReadWriteByte(data>>8); 	//發(fā)送高八位
	VS1053_SPI_ReadWriteByte(data);	 		//第八位
	VS1053_XCS=1;            
} 


/*
函數(shù)參數(shù):向VS1053寫數(shù)據(jù)
函數(shù)參數(shù):data:要寫入的數(shù)據(jù)
*/
void VS1053_WriteData(u8 data)
{
	VS1053_XDCS=0;   
	VS1053_SPI_ReadWriteByte(data);
	VS1053_XDCS=1;      
}


/*
函數(shù)功能:讀VS1053的寄存器 
函數(shù)參數(shù):address:寄存器地址
返回值:讀到的值
*/
u16 VS1053_ReadReg(u8 address)
{ 
	u16 temp=0;   	
  while(VS1053_DREQ==0);//非等待空閑狀態(tài)   	
	VS1053_XDCS=1;       
	VS1053_XCS=0;        
	VS1053_SPI_ReadWriteByte(VS_READ_COMMAND);//發(fā)送VS10XX的讀命令
	VS1053_SPI_ReadWriteByte(address);       	//地址
	temp=VS1053_SPI_ReadWriteByte(0xff); 		  //讀取高字節(jié)
	temp=temp<<8;
	temp+=VS1053_SPI_ReadWriteByte(0xff); 		//讀取低字節(jié)
	VS1053_XCS=1;      
   return temp; 
}  


/*
函數(shù)功能:讀取VS1053的RAM
函數(shù)參數(shù):addr:RAM地址
返 回 值:讀到的值
*/
u16 VS1053_ReadRAM(u16 addr) 
{ 
	u16 res;			   	  
 	VS1053_WriteCmd(SPI_WRAMADDR, addr); 
	res=VS1053_ReadReg(SPI_WRAM);  
 	return res;
} 


/*
函數(shù)功能:寫VS1053的RAM
函數(shù)參數(shù):
				addr:RAM地址
				val:要寫入的值 
*/
void VS1053_WriteRAM(u16 addr,u16 val) 
{  		   	  
 	VS1053_WriteCmd(SPI_WRAMADDR,addr);	//寫RAM地址 
	while(VS1053_DREQ==0); 							//等待空閑	   
	VS1053_WriteCmd(SPI_WRAM,val); 			//寫RAM值 
} 


/*
函數(shù)參數(shù):發(fā)送一次音頻數(shù)據(jù),固定為32字節(jié)
返 回 值:0,發(fā)送成功
				  1,本次數(shù)據(jù)未成功發(fā)送   
*/ 
u8 VS1053_SendMusicData(u8* buf)
{
	u8 n;
	if(VS1053_DREQ!=0)  //送數(shù)據(jù)給VS10XX
	{			   	 
		VS1053_XDCS=0;  
    for(n=0;n<32;n++)
		{
			VS1053_SPI_ReadWriteByte(buf[n]);	 			
		}
		VS1053_XDCS=1;     				   
	}else return 1;
	return 0;//成功發(fā)送了
}


/*
函數(shù)參數(shù):發(fā)送一次音頻數(shù)據(jù),固定為32字節(jié)
返 回 值:0,發(fā)送成功
				  1,本次數(shù)據(jù)未成功發(fā)送   
*/ 
void VS1053_SendMusicByte(u8 data)
{
	u8 n;
	while(VS1053_DREQ==0){}	   	 
	VS1053_XDCS=0;  
	VS1053_SPI_ReadWriteByte(data);	 			
	VS1053_XDCS=1;     				   
}


/*
函數(shù)功能:設(shè)定VS1053播放的音量
函數(shù)參數(shù):volx:音量大小(0~254)
*/
void VS1053_SetVol(u8 volx)
{
    u16 volt=0; 			      //暫存音量值
    volt=254-volx;			    //取反一下,得到最大值,表示最大的表示 
	  volt<<=8;
    volt+=254-volx;					//得到音量設(shè)置后大小
    VS1053_WriteCmd(SPI_VOL,volt);//設(shè)音量 
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

七、Android手機(jī)APP核心源碼

7.1 代碼頁(yè)面

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

7.2 mainwindow.cpp代碼

#include "mainwindow.h"
#include "ui_mainwindow.h"


/*
 * 設(shè)置QT界面的樣式
*/
void MainWindow::SetStyle(const QString &qssFile) {
    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) {
        QString qss = QLatin1String(file.readAll());
        qApp->setStyleSheet(qss);
        QString PaletteColor = qss.mid(20,7);
        qApp->setPalette(QPalette(QColor(PaletteColor)));
        file.close();
    }
    else
    {
        qApp->setStyleSheet("");
    }
}

static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
//這個(gè)字符串里面的內(nèi)容就是串口模式的Uuid

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->SetStyle(":/qss/blue.css");     //設(shè)置樣式表
    this->setWindowTitle("HC05藍(lán)牙音箱"); //設(shè)置標(biāo)題
    this->setWindowIcon(QIcon(":/wbyq.ico")); //設(shè)置圖標(biāo)

    /*1. 實(shí)例化藍(lán)牙相關(guān)的對(duì)象*/
    discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
    localDevice = new QBluetoothLocalDevice();
    socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
    //RfcommProtocol表示該服務(wù)使用RFCOMM套接字協(xié)議。RfcommProtocol屬于模擬RS232模式,就叫串口模式

    /*2. 關(guān)聯(lián)藍(lán)牙設(shè)備相關(guān)的信號(hào)*/
    /*2.1 關(guān)聯(lián)發(fā)現(xiàn)設(shè)備的槽函數(shù),當(dāng)掃描發(fā)現(xiàn)周圍的藍(lán)牙設(shè)備時(shí),會(huì)發(fā)出deviceDiscovered信號(hào)*/
    connect(discoveryAgent,
            SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
            this,
            SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo))
            );

    //藍(lán)牙有數(shù)據(jù)可讀
    connect(socket,
            SIGNAL(readyRead()),
            this,
            SLOT(readBluetoothDataEvent())
            );

    //藍(lán)牙連接建立成功
    connect(socket,
            SIGNAL(connected()),
            this,
            SLOT(bluetoothConnectedEvent())
            );

    //藍(lán)牙斷開連接
    connect(socket,
            SIGNAL(disconnected()),
            this,
            SLOT(bluetoothDisconnectedEvent())
            );

    //藍(lán)牙寫成功的數(shù)據(jù)
    connect(socket,
            SIGNAL(bytesWritten(qint64)),
            this,
            SLOT(bluetoothbytesWritten(qint64))
            );


    /*3.2 設(shè)置標(biāo)簽顯示本地藍(lán)牙的名稱*/
    QString name_info("本機(jī)藍(lán)牙:");
    name_info+=localDevice->name();
    ui->label_BluetoothName->setText(name_info);

     ui->plainTextEdit->setEnabled(false); //不可編輯

     /*定時(shí)器用于定時(shí)發(fā)送文件*/
     timer = new QTimer(this); //創(chuàng)建定時(shí)器
     connect(timer, SIGNAL(timeout()), this, SLOT(update())); //關(guān)聯(lián)槽函數(shù)

     ConnectStat=0;     //連接狀態(tài)
     SendStat=0;        //文件打開狀態(tài)
     FileSendTime=100;  //默認(rèn)每次發(fā)送的時(shí)間 單位ms
     ui->lineEdit_Timer->setText(QString::number(FileSendTime));
     FileSendCnt=32;    //默認(rèn)每包數(shù)據(jù)值32字節(jié)
     ui->lineEdit_SendFileCnt->setText(QString::number(FileSendCnt));


     //創(chuàng)建存放音樂(lè)文件的目錄
     QDir dir;
     if(dir.mkpath("/sdcard/WBYQ_MP3"))
     {
          ui->plainTextEdit->insertPlainText("/WBYQ_MP3 目錄創(chuàng)建成功!\n");
     }
     else
     {
          ui->plainTextEdit->insertPlainText("/WBYQ_MP3 目錄創(chuàng)建失敗!\n");
     }

      MusicFileDir="assets:/nansannan.mp3";  //目錄的路徑
      Def_MusicName="assets:/nansannan.mp3";
      file.setFileName(Def_MusicName); //設(shè)置文件名稱
      ui->lineEdit_MusicName->setText(Def_MusicName); //默認(rèn)文件名稱
}


int count=0;
//更新
void MainWindow::update()
{
    if(SendStat)
    {
        int len;
        if(file.atEnd()==false)  //文件未結(jié)束
        {
            len=file.read(FileBuff,FileSendCnt);
            len=socket->write(FileBuff,len); //發(fā)送數(shù)據(jù)
        }
        else
        {
           file.close();
           timer->stop(); //停止定時(shí)器
           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()
{
    /*關(guān)閉藍(lán)牙設(shè)備*/
    localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
}


void MainWindow::on_pushButton_BluetoothScan_clicked()
{
    /*3.1 檢查藍(lán)牙是否開啟*/
    if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)
    {
        /*請(qǐng)求打開藍(lán)牙設(shè)備*/
        localDevice->powerOn();
    }

     /*開始掃描周圍的藍(lán)牙設(shè)備*/
    discoveryAgent->start();
    ui->comboBox_BluetoothDevice->clear(); //清除條目
}

void MainWindow::on_pushButton_DeviceVisible_clicked()
{
    /*設(shè)置藍(lán)牙可見,可以被周圍的設(shè)備搜索到,在Android上,此模式最多只能運(yùn)行5分鐘。*/
    //  localDevice->setHostMode( QBluetoothLocalDevice::HostDiscoverable);
    static bool cnt=1;
    cnt=!cnt;
    if(cnt)
    {
        MusicFileDir="assets:/nansannan.mp3";  //目錄的路徑
        QMessageBox::information(this,"提示","路徑切換為內(nèi)部路徑!\n請(qǐng)選擇文件!",QMessageBox::Ok,QMessageBox::Ok);
    }
    else
    {
        MusicFileDir="/mnt/sdcard";  //目錄的路徑
        QMessageBox::information(this,"提示","路徑切換為SD路徑!\n請(qǐng)選擇文件!",QMessageBox::Ok,QMessageBox::Ok);
    }
}


void MainWindow::on_pushButton_StopScan_clicked()
{
    /*停止掃描周圍的藍(lán)牙設(shè)備*/
    discoveryAgent->stop();
}


/*當(dāng)掃描到周圍的設(shè)備時(shí)會(huì)調(diào)用當(dāng)前的槽函數(shù)*/
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上
}


//有數(shù)據(jù)可讀
void MainWindow::readBluetoothDataEvent()
{
    QByteArray all = socket->readAll();
    ui->plainTextEdit->insertPlainText(all);
}


//建立連接
void MainWindow::bluetoothConnectedEvent()
{
    QMessageBox::information(this,tr("連接提示"),"藍(lán)牙連接成功!");
    ConnectStat=1;
    /*停止掃描周圍的藍(lán)牙設(shè)備*/
    discoveryAgent->stop();
}


//斷開連接
void MainWindow::bluetoothDisconnectedEvent()
{
    ConnectStat=0;
    QMessageBox::information(this,tr("連接提示"),"藍(lán)牙斷開連接!");
}


/*
在說(shuō)藍(lán)牙設(shè)備連接之前,不得不提一個(gè)非常重要的概念,就是藍(lán)牙的Uuid,引用一下百度的:
在藍(lán)牙中,每個(gè)服務(wù)和服務(wù)屬性都唯一地由"全球唯一標(biāo)識(shí)符" (UUID)來(lái)校驗(yàn)。
正如它的名字所暗示的,每一個(gè)這樣的標(biāo)識(shí)符都要在時(shí)空上保證唯一。
UUID類可表現(xiàn)為短整形(16或32位)和長(zhǎng)整形(128位)UUID。
他提供了分別利用String和16位或32位數(shù)值來(lái)創(chuàng)建類的構(gòu)造函數(shù),提供了一個(gè)可以比較兩個(gè)UUID(如果兩個(gè)都是128位)的方法,還有一個(gè)可以轉(zhuǎn)換一個(gè)UUID為一個(gè)字符串的方法。
UUID實(shí)例是不可改變的(immutable),只有被UUID標(biāo)示的服務(wù)可以被發(fā)現(xiàn)。
在Linux下你用一個(gè)命令uuidgen -t可以生成一個(gè)UUID值;
在Windows下則執(zhí)行命令uuidgen 。UUID看起來(lái)就像如下的這個(gè)形式:2d266186-01fb-47c2-8d9f-10b8ec891363。當(dāng)使用生成的UUID去創(chuàng)建一個(gè)UUID對(duì)象,你可以去掉連字符。
*/

//發(fā)送音樂(lè)文件
void MainWindow::on_pushButton_SendData_clicked()
{
    if(ConnectStat)
    {
        if(file.open(QIODevice::ReadOnly))
        {
            SendStat=1;
            count=0;
            ui->plainTextEdit->insertPlainText("系統(tǒng)提示: 開始發(fā)送文件!\n");
            ui->lineEdit_fileSizef->setText(QString::number(file.size()));
            ui->lineEdit_fileCount->setText("");
            ui->progressBar_SendCount->setMaximum(file.size()); //設(shè)置進(jìn)度條顯示最大值
            ui->progressBar_SendCount->setValue(0); //設(shè)置進(jìn)度條的值
            timer->start(FileSendTime); //啟動(dòng)定時(shí)器
        }
    }
}


//連接藍(lán)牙
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="開始連接藍(lán)牙設(shè)備:\n";
    connect_device+=ui->comboBox_BluetoothDevice->currentText();
    QMessageBox::information(this,tr("連接提示"),connect_device);

    //開始連接藍(lán)牙設(shè)備
    socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);
}

//幫助提示
void MainWindow::on_pushButton_help_clicked()
{
    QMessageBox::information(this,tr("幫助提示"),"本軟件用于HC-05/06系列串口藍(lán)牙連接!\n"
                                             "暫時(shí)不支持BLE4.0版本藍(lán)牙!\n"
                                             "用于發(fā)送音樂(lè)文件數(shù)據(jù),每次發(fā)送32字節(jié),默認(rèn)100ms發(fā)送間隔時(shí)間\n"
                                             "軟件作者:DS小龍哥\n"
                                             "BUG反饋:1126626497@qq.com");
}


//選擇音樂(lè)文件
void MainWindow::on_pushButton_select_clicked()
{
    QString filename=QFileDialog::getOpenFileName(this,"選擇發(fā)送的音樂(lè)文件",MusicFileDir,tr("*.mp3 *.MP3 *.WAV"));
    //filename==選擇文件的絕對(duì)路徑
    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(); //停止定時(shí)器
}


//設(shè)置發(fā)送間隔時(shí)間
void MainWindow::on_pushButton_SendTime_clicked()
{
    QString str=ui->lineEdit_Timer->text();
    int time=str.toInt();
    FileSendTime=time; //保存時(shí)間
    if(time<=0)
    {
        QMessageBox::warning(this,"警告提示","設(shè)置錯(cuò)誤: 發(fā)送的間隔時(shí)間最小1ms\n",QMessageBox::Ok,QMessageBox::Ok);
    }
    else
    ui->plainTextEdit->insertPlainText(tr("設(shè)置發(fā)送間隔時(shí)間為%1ms\n").arg(time));
}


//修改每包發(fā)送的數(shù)量
void MainWindow::on_pushButton_SendFileCnt_clicked()
{
    QString str=ui->lineEdit_SendFileCnt->text();
    int cnt=str.toInt();
    if(cnt>4096 || cnt<=0)
    {
         QMessageBox::warning(this,"警告提示","設(shè)置錯(cuò)誤: 每包發(fā)送的數(shù)量范圍: 1~4096\n",QMessageBox::Ok,QMessageBox::Ok);
    }
    else
    {
        FileSendCnt=cnt;
        ui->plainTextEdit->insertPlainText(tr("發(fā)送數(shù)量設(shè)置為%1字節(jié).\n").arg(cnt));
    }
}


//寫成功的數(shù)量
void MainWindow::bluetoothbytesWritten(qint64 byte)
{
   count+=byte;
   ui->lineEdit_fileCount->setText(QString::number(count));
   ui->progressBar_SendCount->setValue(count); //設(shè)置進(jìn)度條的值
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

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;  //這個(gè)是指掃描周圍藍(lán)牙設(shè)備!
    QBluetoothLocalDevice *localDevice;//是指配置獲取設(shè)備的藍(lán)牙狀態(tài)信息等!
    QBluetoothSocket *socket; //指進(jìn)行鏈接藍(lán)牙設(shè)備,讀寫信息!
    int FileSendTime; //文件發(fā)送時(shí)間
    char FileBuff[4096]; //每包最大的字節(jié)數(shù)
    int FileSendCnt;     //每次發(fā)送的字節(jié)數(shù)
    QString Def_MusicName;
    QString MusicFileDir;
private slots:
    void on_pushButton_CloseBluetooth_clicked();

    void on_pushButton_BluetoothScan_clicked();

    void addBlueToothDevicesToList(const QBluetoothDeviceInfo&);  //發(fā)現(xiàn)藍(lán)牙設(shè)備的槽函數(shù)

    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); //樣式表設(shè)置函數(shù)
    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
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

完整項(xiàng)目源碼下載地址: https://download.csdn.net/download/xiaolong1126626497/18621270

審核編輯:符乾江

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2266

    文章

    10873

    瀏覽量

    354871
  • 藍(lán)牙音箱
    +關(guān)注

    關(guān)注

    6

    文章

    259

    瀏覽量

    22744
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    stm32藍(lán)牙模塊連接方法

    選擇藍(lán)牙模塊 首先,需要選擇一個(gè)適合的藍(lán)牙模塊。市面上常見的藍(lán)牙模塊有HC-05HC-06等,它們支持
    的頭像 發(fā)表于 11-19 15:49 ?169次閱讀

    藍(lán)牙耳機(jī)與藍(lán)牙音箱的區(qū)別

    在現(xiàn)代生活中,無(wú)線音頻設(shè)備已經(jīng)成為我們?nèi)粘蕵?lè)和溝通的重要組成部分。藍(lán)牙技術(shù)的發(fā)展使得我們可以擺脫線纜的束縛,享受更加自由的音頻體驗(yàn)。在眾多無(wú)線音頻設(shè)備中,藍(lán)牙耳機(jī)和藍(lán)牙音箱是兩種非常流行的選擇
    的頭像 發(fā)表于 10-28 15:47 ?277次閱讀

    藍(lán)牙音箱與PD協(xié)議快充

    隨著科技的發(fā)展,藍(lán)牙音箱已經(jīng)成為我們生活中不可或缺的娛樂(lè)設(shè)備之一。與此同時(shí),快充技術(shù)也日益普及,越來(lái)越多的設(shè)備支持Type-C接口PD協(xié)議快充。那么,藍(lán)牙音箱如何實(shí)現(xiàn)Type-C接口PD協(xié)議快充呢?本文將為您詳細(xì)解析。
    的頭像 發(fā)表于 09-07 11:00 ?369次閱讀

    時(shí)鐘藍(lán)牙音箱怎么打開藍(lán)牙

    時(shí)鐘藍(lán)牙音箱是一種結(jié)合了時(shí)鐘和藍(lán)牙音響功能的設(shè)備,它不僅可以顯示時(shí)間,還能通過(guò)藍(lán)牙技術(shù)無(wú)線連接到智能手機(jī)、平板電腦或其他藍(lán)牙設(shè)備,播放音樂(lè)或其他音頻內(nèi)容。要打開時(shí)鐘
    的頭像 發(fā)表于 09-07 09:19 ?996次閱讀

    無(wú)線時(shí)鐘藍(lán)牙音箱怎么關(guān)閉鬧鐘功能

    無(wú)線時(shí)鐘藍(lán)牙音箱關(guān)閉鬧鐘功能的方法可能因不同品牌和型號(hào)而有所差異,但通常可以按照以下一般步驟進(jìn)行: 一、通過(guò)設(shè)備按鍵操作 找到菜單按鈕 :首先,找到音箱上的“菜單”按鈕(可能是一個(gè)圓形或特定圖標(biāo)
    的頭像 發(fā)表于 09-06 18:06 ?4404次閱讀

    炬芯藍(lán)牙音箱芯片ATS2853規(guī)格書

    電子發(fā)燒友網(wǎng)站提供《炬芯藍(lán)牙音箱芯片ATS2853規(guī)格書.pdf》資料免費(fèi)下載
    發(fā)表于 08-22 16:48 ?11次下載

    超級(jí)電容器應(yīng)用在藍(lán)牙音箱PCBA上的方案說(shuō)明

    藍(lán)牙音箱已成為日常生活中不可或缺的音頻設(shè)備。為了確保藍(lán)牙音箱在音質(zhì)、續(xù)航及穩(wěn)定性方面達(dá)到最優(yōu),選擇合適的電子元器件顯得尤為重要。本文將詳細(xì)介紹風(fēng)華高科超級(jí)電容器FH5R5C155T在藍(lán)牙音箱PCBA
    的頭像 發(fā)表于 07-15 15:25 ?342次閱讀

    ESP32-S3自帶了藍(lán)牙,是否可以做藍(lán)牙音箱呢?

    因?yàn)槲沂切率郑叶紱](méi)有好好玩基礎(chǔ)開發(fā)板,上來(lái)就買了ESP32-S3,當(dāng)時(shí)不太懂,看說(shuō)明有雙模藍(lán)牙的,但真正拿到后開始學(xué)習(xí)才發(fā)現(xiàn),藍(lán)牙音箱是要用基礎(chǔ)藍(lán)牙才可以做。 但是作為新產(chǎn)品,不是向下支持嗎?ESP32-S3就做不了
    發(fā)表于 07-01 07:45

    袁婭維《歌手》沖榜成功# 音頻功放芯片# 藍(lán)牙音箱

    藍(lán)牙音箱
    深圳湯誠(chéng)科技有限公司
    發(fā)布于 :2024年06月18日 11:28:54

    使用ESP32 A2DP藍(lán)牙音頻制作了藍(lán)牙音箱,手機(jī)來(lái)電話時(shí)通話也走ESP32,如何接電話時(shí)自動(dòng)切換到iphone?

    使用ESP32 A2DP藍(lán)牙音頻制作了藍(lán)牙音箱,但是手機(jī)來(lái)電話時(shí),通話也走ESP32, 如何接電話時(shí)自動(dòng)切換到iphone?
    發(fā)表于 06-14 06:58

    NRK330x藍(lán)牙音箱語(yǔ)音識(shí)別芯片方案設(shè)計(jì)

    隨著智能家居的普及和消費(fèi)者對(duì)音樂(lè)體驗(yàn)需求的提高,藍(lán)牙音箱市場(chǎng)將繼續(xù)保持強(qiáng)勁的增長(zhǎng)勢(shì)頭。而NRK330X系列語(yǔ)音識(shí)別芯片憑借其卓越的性能和廣泛的應(yīng)用領(lǐng)域,有望在市場(chǎng)中占據(jù)更大的份額。 藍(lán)牙音箱語(yǔ)音識(shí)別
    的頭像 發(fā)表于 05-14 11:33 ?553次閱讀

    HC05藍(lán)牙模塊主從通訊,藍(lán)牙透?jìng)?b class='flag-5'>串口發(fā)出后數(shù)據(jù)字節(jié)有延時(shí)是怎么回事?

    HC05藍(lán)牙做主從通訊,主機(jī)發(fā)出從機(jī)接收。主從模塊通過(guò)兩個(gè)CH430和PC相連。用邏輯分析儀抓取數(shù)據(jù),發(fā)現(xiàn)從機(jī)接收后串口發(fā)出的數(shù)據(jù)有字節(jié)延時(shí)。
    發(fā)表于 04-02 07:52

    藍(lán)牙音箱進(jìn)行CCC認(rèn)證跟其他產(chǎn)品的區(qū)別在哪?

    在中國(guó),藍(lán)牙音箱也是屬于必須進(jìn)行產(chǎn)品強(qiáng)制性認(rèn)證CCC認(rèn)證的產(chǎn)品。而作為在這幾年逐漸變成音箱類產(chǎn)品主流的藍(lán)牙音箱,該產(chǎn)品進(jìn)行CCC認(rèn)證申請(qǐng)與其他產(chǎn)品有什么區(qū)別呢?藍(lán)牙音箱產(chǎn)品與其他產(chǎn)品在
    的頭像 發(fā)表于 01-16 16:07 ?418次閱讀
    <b class='flag-5'>藍(lán)牙音箱</b>進(jìn)行CCC認(rèn)證跟其他產(chǎn)品的區(qū)別在哪?

    藍(lán)牙midi和藍(lán)牙音頻或者藍(lán)牙audio有什么區(qū)別呢

    、什么是藍(lán)牙midi,這個(gè)一般問(wèn)這個(gè)問(wèn)題的人,基本都懂,藍(lán)牙midi實(shí)際就是在標(biāo)準(zhǔn)midi協(xié)議的基礎(chǔ)上擴(kuò)充為無(wú)線連接而已,原先的midi是靠usb傳輸,現(xiàn)在換成藍(lán)牙 3、什么是藍(lán)牙a
    的頭像 發(fā)表于 01-09 15:22 ?1126次閱讀
    <b class='flag-5'>藍(lán)牙</b>midi和<b class='flag-5'>藍(lán)牙音</b>頻或者<b class='flag-5'>藍(lán)牙</b>audio有什么區(qū)別呢