2026/4/6 7:27:25
网站建设
项目流程
企业网站开发视频,网站建设唯美谷网站,网络推广专员任职要求,自己怎样做广告链接偶然发现有一个产品#xff0c;可以通过蓝牙连接手机#xff0c;在播放音乐的同时#xff0c;显示歌词。于是查找了一下资料#xff0c;发现有很多用ESP32实现的例子#xff0c;但无一例外都基于Arduino#xff0c;调用大神提供的库实现歌词获取和显示。为了节约硬盘空间…偶然发现有一个产品可以通过蓝牙连接手机在播放音乐的同时显示歌词。于是查找了一下资料发现有很多用ESP32实现的例子但无一例外都基于Arduino调用大神提供的库实现歌词获取和显示。为了节约硬盘空间前不久Arduino已经被我从硬盘上删掉了无法利用现成的了所以只能用IDF实现一下。一、蓝牙歌词显示原理如果没接触过传统蓝牙可能要实现在一个屏幕显示歌词需要在手机播放歌曲的同时将歌词字幕通过蓝牙以字符串的形式发送给单片机然后再由单片机对字符串解析查找字库字模在LCD上显示。这里面涉及手机上的歌词字幕获取以及发送字符串的手机蓝牙编程感觉难度不小。但实际上蓝牙标准化组织早已考虑到大众对显示歌词的需求在传统蓝牙中提供了相关协议A2DP和AVRCP。利用这两个协议可以实现音频和控制传输实现蓝牙歌词显示。A2DPAdvanced Audio Distribution Profile蓝牙音频传输模型协定和AVRCPAudio/Video Remote Control Profile音频/视频远程控制协议是传统蓝牙的两种高层应用协议在市面上的应用产品中支持A2DP的蓝牙产品通常也支持AVRCP。A2DP负责高质量音频数据的传输而AVRCP则负责对这些音频数据进行远程控制。例如在使用蓝牙耳机听音乐时A2DP负责将音乐数据从手机传输到耳机而AVRCP则允许用户通过耳机上的按钮来控制音乐的播放、暂停和切换等操作。另外AVRCP也可以传输歌词、歌名、作者等信息而且手机上大部分音乐播放软件都已实现AVRCP。所以只需在单片机端实现AVRCP协议就可以和手机对话获取歌词。二、为什么选择ESP32其一ESP32不是乐鑫最高性能的模块和ESP32 S3相比真的很难用但ESP32支持传统蓝牙而ESP32 S3只支持BLE。其二ESP32有A2DP的例程可以拿来直接利用。三、实现方案为了达到目标需要完成以下工作驱动一个屏幕可以是LED、LCD这个决定最终的显示效果需要一个GBK汉字字模库用来获取显示汉字需要一个UTF转GBK的函数因为AVRCP是UTF-8格式的需要转换成GBK格式才能通过GBK汉字字模库获取字模读懂A2DP例程加入适当的功能。四、屏幕驱动篇幅有限这部分略大家根据自已手头的屏幕情况驱动就好。但需要注意的是ESP32引脚资源有限并且34-39引脚只能做为输入00、02、05、12、15不推荐使用如果还要支持I2S外放音乐就剩不了太多引脚可能刚好够一个8位并口屏驱动。五、GBK汉字字模库1、汉字库可以从网上找一个gb2312.bin的标准汉字库也可以用一些字库工具生成一个比如高通字库。2、自定义烧录分区表为了将gb2312.bin烧录到ESP32中需要为gb2312.bin分配一个分区在烧录的时候和固件一起烧录到ESP32中idf.py menuconfigPartition Table选择Custom partition table CSV设置Custom partition table CSV名称partitions_singleapp_large.csv内容hzk是用于放汉字库的分区0x50,0x32是自定义的类型和子类型用于和其他分区区别便于查找300k为分区大小汉字库200多k大小足够了。3、烧录命令和烧录地址每次idf.py build编译后都会给出烧录命令和烧录地址比如nvs,data,nvs,0x9000,24K,phy_init,data,phy,0xf000,4K,factory,app,factory,0x10000,3000K,hzk,80,50,0x2fe000,300K,其中0x2fe000是烧录hzk的烧录地址。编译后给出的烧录命令C:\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.1.2\components\esptool_py\esptool\esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x1000 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\a2dp-demo.bin需要修改下把gb2312.bin也一起烧录。为了方便可以将下面内容放到一个bat文件中。C:\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.1.2\components\esptool_py\esptool\esptool.py -p COM10 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x1000 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\a2dp-demo.bin 0x2fe000 gb2312_80.binCOM10酌情修改gb2312_80.bin放到工程根目录。4、读取汉字库并在LCD上显示通过前面操作可以在每次烧录时将汉字库烧录到0x2fe000的起始位置。要读取它需要利用2个函数esp_partition_find_firstFind first partition based on one or more parameters。通过类型、子类型、标识获取分区句柄。esp_partition_readRead data from the partition。从分区上读取指定字节数据。实现函数获取分区句柄void getHzkPartition(void){ hzkPartition esp_partition_find_first(0x50,0x32,hzk);}获取字模数据void getMatrix(const unsigned short nmCode){ uint32_t offset; unsigned char GBH,GBL; unsigned short nmnmCode; GBHnm8; GBLnm; if(GBH0xb0) { offset((GBH-0xa7)*94GBL-0xa1)*32; }else { offset((GBH-0xa1)*94GBL-0xa1)*32; } esp_partition_read(hzkPartition,offset,MatrixBuff,32);}通过GB2312汉字编码获取在字库中的偏移量然后通过esp_partition_read读取字模数据。将字模在LCD上显示函数void GUI_Write16CnCharMatrix(unsigned char x, unsigned char y, char *cn, unsigned short wordColor, unsigned short backColor){ uint8_t i0, j,mx,my,wordByte; uint16_t zm; uint16_t color; uint8_t wordNum; mxx; myy; while (*cn ! \0) { if(mx170){ mxx; my16; } if(*cn128){ wordNum *cn - 32; setXY(mx,my,mx7, my15); for (wordByte0; wordByte16; wordByte) { color Font_Data[wordNum].dat[wordByte]; for (j0; j8; j) { if ((color0x80) 0x80) { setPixel(wordColor); } else { setPixel(backColor); } color 1; } } cn; mx 8; } else { setXY(mx, my, mx15, my15); zm*cn; zm8; zm|*(cn1); getMatrix(zm); for(i0; i32; i) { //MSK的位数 colorMatrixBuff[i]; for(j0;j8;j) { if((color0x80)0x80) { setPixel(wordColor); } else { setPixel(backColor); } color1; }//for(j0;j8;j)结束 } cn 2; mx 16; } }}可以显示ASCII和汉字。六、UTF转GBK的函数UTF汉字不能直接转换为GBK需要先将UTF转换为unicode再将unicode通过查表法转换为GBK。这部分不用自己实现网上有现成的https://gitee.com/zhangkt1995/my-code/tree/master/utf8_gb2312_switch使用起来很方便七、实现蓝牙歌词功能ESP IDF下有一个传统蓝牙接收设备sink例程esp-idf-v5.1.2\examples\bluetooth\bluedroid\classic_bt\a2dp_sink可以选择这个做为模板新建一个工程然后将前面四、五、六步的程序加到这个工程中再打开其中bt_app_av.c在430行左右修改memset(gb2312Data, ,sizeof(gb2312Data)); size_t gb2312DataLen utf8_to_gb2312((uint8_t *)rc-meta_rsp.attr_text, strlen((char*)rc-meta_rsp.attr_text), (uint8_t *)gb2312Data, sizeof(gb2312Data)); if((rc-meta_rsp.attr_id0x01)(gb2312DataLen0)){ gb2312Data[gb2312DataLen] ; gb2312Data[128]\0; printf(%s,gb2312Data); GUI_Write16CnCharMatrix(10,90,gb2312Data,VGA_WHITE,VGA_RED); }当收到ESP_AVRC_CT_METADATA_RSP_EVT消息后将收到的AVRCP协议数据显示出来。为什么要在这里添加如果想深入了解还是需要参考AVRCP协议相关内容。rc-meta_rsp.attr_id0x01标识接收的是歌曲TITLE信息同时歌词也复用该字段。通过utf8_to_gb2312将收到的歌词由UTF-8转换为gb2312编码。通过GUI_Write16CnCharMatrix将歌词显示在LCD上。八、运行效果手机打开蓝牙连接ESP_SPEAKER。打开搜狗音乐找一首歌播放。这时LCD上歌词会实时显示以上就是今天的分享如果有需要查看原图、代码的小伙伴请点击底部“阅读原文”进行下载。END作者sujingliang来源21ic论坛