整理东西整理出了几块RDA5851S模块

本着物尽其用的原则,我查了一下相关资料,发现是在车载上用的,还可以进行AT控制

看到这里我觉得还好,因为这种可以AT控制的蓝牙模块还是比较常见的,

本着试一试的心思,接电源线,想到接功放和喇叭太费事儿,直接连接了一个耳机口,插上耳机,通电

蓝牙名称还是很好找的  CAR KIT ,点击蓝牙连接,手机放歌,耳机里传出了声音,一切正常,除了没有蓝牙连接提示音,断开连接提示音。

接着用USB转串口接到蓝牙的RX TX上,数据显示乱码,切换波特率,再来。。。

终于,波特率57600情况下,显示正常了,哎等等,怎么还有乱码?

换歌再来,还是乱码

灵机一动,放个英文歌

发现了新大陆

MI1后面就是歌名

MI2后面就是歌手

那么问题来了,汉字歌名怎么不行呢?

看看16进制到底发了什么

找个转换工具转一下

喜出望外,说明汉字歌曲是可以的,但为什么这里可以显示,串口助手就不行?

换一个支持改编码的串口助手

原来如此,模块发送出来是UTF-8编码的数据,英文数字因为编码一样可以正常显示,而汉字编码则为乱码。找到原因就好办了。

因为单片机显示汉字是GBK编码的字库,而现在是UTF-8编码,UTF-8可以转GBK吗?查查查起来。。。

UTF-8不能直接转GBK,但是UTF-8可以转成Unicode,而Unicode经过一个大表可以对应到GBK。

代码实现

/************************************************************************
* 函数名称: StrProcess_UTF8toGBK
* 函数功能: 将网络上 utf8 的字符串转换为 GBK 字符串 使得兼容 原子LCD屏驱动程序
* 函数输入: void input: c_utf8 原utf8 字符串 同时 新的 gbk字符串会将其覆盖
* length 你想要设置的 中间缓存块的大小
* 函数输出: void output:字符总数 (一个中文算两个字节)
* 作者 :
* 文件依存:
* #include “ff.h”
* #include “malloc.h”
* #include “stm32f10x.h”
************************************************************************/
int16_t StrProcess_UTF8toGBK(u8 *c_utf8, u16 length)
{char low;char high;char middle;// ff_uni2oem(,FF_CODE_PAGE);/* !< 首先 将 utf8 转换成标准 Unicode 然后查表将 Unicode 转化为GBK */u16 outputSize = 0; //记录转换后的gbk字符串长度u8 *pInput = c_utf8;u8 *c_gbk = mymalloc(0, length); /* !< 申请内存,也可以外部传入一个 数据缓存空间 */u8 *pOutput = c_gbk;u16 *uni = (u16 *)c_gbk;u16 gbk;/* !< 以下中间代码来自于 CSDN @bladeandmaster88 公开的源码 */while (*pInput){if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字){*pOutput = *pInput;pOutput += 1;*pOutput = 0; //小端法表示,在高地址填补0}else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符{high = *pInput;pInput += 1;low = *pInput;if ((low & 0xC0) != 0x80) //检查是否为合法的UTF8字符表示{return -1; //如果不是则报错}*pOutput = (high << 6) + (low & 0x3F);pOutput++;*pOutput = (high >> 2) & 0x07;}else if (((*pInput) & 0xF0) == 0xE0) //处理三字节UTF8字符{high = *pInput;pInput++;middle = *pInput;pInput++;low = *pInput;if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80)){return -1;}*pOutput = (middle << 6) + (low & 0x3F);//取出middle的低两位与low的低6位,组合成unicode字符的低8位pOutput++;*pOutput = (high << 4) + ((middle >> 2) & 0x0F); //取出high的低四位与middle的中间四位,组合成unicode字符的高8位}else //对于其他字节数的UTF8字符不进行处理{return -1;}pInput++;//处理下一个utf8字符pOutput++;}//unicode字符串后面,有两个\0*pOutput = 0;pOutput++;*pOutput = 0;/* !< 感谢 @bladeandmaster88 的开源支持 */pInput = c_utf8;while(*uni != 0){gbk = ff_convert((WCHAR) * uni, 0);//    gbk = ff_uni2oem(*uni,FF_CODE_PAGE);        /* !< Unicode 向 GBK 转换函数  */uni++;if(gbk & 0xff00){*pInput = ((gbk & 0xff00) >> 8);pInput++;*pInput = (gbk & 0x00ff);pInput++;outputSize += 2;}else{*pInput = (gbk & 0x00ff);pInput++;outputSize++;}}*pInput = '\0';         /* !< 加上结束符号 */myfree(0, c_gbk);       /* !< 释放内存 */return outputSize;
}

蓝牙数据解析

void Data_Analysis()
{char *ptr;uint8_t lenth = 0;uint8_t i = 0;ptr = strstr((char *)STR_BUF, "IB");        //已连接if(ptr != NULL){Connect_Flag = 1;}else{ptr = strstr((char *)STR_BUF, "IA");       //断开连接if(ptr != NULL){Connect_Flag = 0;}}ptr = strstr((char *)STR_BUF, "MB");      //开始播放if(ptr != NULL){Play_Flag = 1;}else{ptr = strstr((char *)STR_BUF, "MA");     //停止播放if(ptr != NULL){Play_Flag = 0;}}ptr = strstr((char *)STR_BUF, "MI1");        //歌名if(ptr != NULL){Connect_Flag = 1;Play_Flag = 1;ptr = ptr + 3;lenth = 127;i = 0;memset(STR_Name , 0 , 127);while ((*ptr != 0x0D) && (lenth --)){STR_Name[i++] = *(ptr++);}}ptr = strstr((char *)STR_BUF, "MI2");     //歌手if(ptr != NULL){ptr = ptr + 3;lenth = 127;i = 0;memset(STR_Singer , 0 , 127);while ((*ptr != 0x0D) && (lenth --)){STR_Singer[i++] = *(ptr++);}}
}

接下来就是STM32显示了

接着又画了一下PCB,毕竟总是连着线也不太好,带有充电电路,小集成功放,MOS管控制蓝牙电源,状态指示灯等(毕竟这个蓝牙没连接提示音)。

焊接调试好没问题。

自动居中显示,如果超长则滚动显示

void Dis_Play()
{uint8_t STR_Name_len;uint8_t STR_Singer_len;int8_t STR_Name_can;int8_t STR_Singer_can;uint8_t STR_Name_symbol = 0;uint8_t STR_Singer_symbol = 0;int8_t i , j ;if(Play_Flag){Lcd_P16x16Ch(88, 0, (uint8_t *)"播放", 0);Connect_Flag = 1;}else{if(Connect_Flag){Lcd_P16x16Ch(88, 0, (uint8_t *)"暂停", 0);}}if(Connect_Flag){Lcd_P16x16Ch(8, 0, (uint8_t *)"已连接", 0);LED2_ON;}else{Lcd_P16x16Ch(8, 0, (uint8_t *)"未连接", 0);LED2_OFF;}Lcd_fill(0, 4, 128, 4, 0);if(STR_Name_lenth > 16) //歌名超长滚动处理{STR_Name_can = STR_Name_lenth - STR_Name_num ;if(STR_Name_can < 0){STR_Name_num = 0;STR_Name_can = STR_Name_lenth - STR_Name_num ;}if(STR_Name_can > 16){for(i = 0 ; i < 16 ; i ++){if(STR_Name [i + STR_Name_num] <= 0x80){STR_Name_symbol ++;}Dis_STR_Name[i] = STR_Name [i + STR_Name_num] ;}}else{for(i = 0 ; i < STR_Name_can ; i ++){Dis_STR_Name[i] = STR_Name [i + STR_Name_num] ;}Dis_STR_Name[i ++] = 0x20 ;Dis_STR_Name[i ++] = 0x20 ;STR_Name_can = STR_Name_can + 2 ;j = 0 ;for(; i < 16 ; i++){Dis_STR_Name[i] = STR_Name [j++] ;}for(i = 0; i < 16 ; i++){if(Dis_STR_Name[i] <= 0x80){STR_Name_symbol ++;}}}if(STR_Name_symbol % 2){Dis_STR_Name[15] = 0;}if(Dis_STR_Name[0] <= 0x80){STR_Name_num += 1;}else{STR_Name_num += 2;}STR_Name_len = 0;}else        //歌名自动居中处理{memset(Dis_STR_Name , 0 , 16);for(i = 0 ; i < STR_Name_lenth ; i ++){Dis_STR_Name[i] = STR_Name [i] ;}STR_Name_len = (128 - STR_Name_lenth * 8) / 2;}if(STR_Singer_lenth > 16)    //歌手超长滚动处理{STR_Singer_can = STR_Singer_lenth - STR_Singer_num ;if(STR_Singer_can < 0){STR_Singer_num = 0;STR_Singer_can = STR_Singer_lenth - STR_Singer_num ;}if(STR_Singer_can > 16){for(i = 0 ; i < 16 ; i ++){if(STR_Singer [i + STR_Singer_num] <= 0x80){STR_Singer_symbol ++;}Dis_STR_Singer[i] = STR_Singer [i + STR_Singer_num] ;}}else{for(i = 0 ; i < STR_Singer_can ; i ++){Dis_STR_Singer[i] = STR_Singer [i + STR_Singer_num] ;}Dis_STR_Singer[i ++] = 0x20 ;Dis_STR_Singer[i ++] = 0x20 ;STR_Singer_can = STR_Singer_can + 2 ;j = 0 ;for(; i < 16 ; i++){Dis_STR_Singer[i] = STR_Singer [j++] ;}for(i = 0; i < 16 ; i++){if(Dis_STR_Singer[i] <= 0x80){STR_Singer_symbol ++;}}}if(STR_Singer_symbol % 2){Dis_STR_Singer[15] = 0;}if(Dis_STR_Singer[0] <= 0x80){STR_Singer_num += 1;}else{STR_Singer_num += 2;}STR_Singer_len = 0;}else  //歌手自动居中处理{memset(Dis_STR_Singer , 0 , 16);for(i = 0 ; i < STR_Singer_lenth ; i ++){Dis_STR_Singer[i] = STR_Singer [i] ;}STR_Singer_len = (128 - STR_Singer_lenth * 8) / 2;}Lcd_P16x16Ch(STR_Name_len, 4, Dis_STR_Name, 0);     //歌名显示Lcd_P16x16Ch(STR_Singer_len, 6, Dis_STR_Singer, 0);       //歌手显示}

大功告成,试了一下,几乎所有音乐软件都可以(主流的那几个都试了,包括自带的音乐播放器,还有一些游戏背景音乐也可以)可以同步显示歌名歌手,再也不用为不知道现在放的什么歌而苦恼了,也不用打开手机查看了。

以下就是全部下载资料https://download.csdn.net/download/qq_22848695/13106771

后续:因为汉字显示是Unicode通过一个大表可以对应到GBK,而这个表只有基本汉字(意思就是没有一些生僻字和部分特殊符号),即使这样,程序也达到了190K,不过实际使用中影响不大,我切了几十首歌才有一个因为特殊符号乱码的(可能我找的歌也不到位)。

基于stm32和RDA5851S蓝牙模块的歌名歌手同步显示相关推荐

  1. 单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app)

    单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app) 一.主要功能: 1.手机app播放内存卡的音乐.同时点阵屏随音乐进行跳 ...

  2. 【小睿精选·第七期】基于STM32的DIY蓝牙机械键盘

    [小睿精选] [小睿精选]第七弹来啦,本期共收录 6条 嵌入式资讯信息,希望可以帮到你.欢迎大家在文末留言,唠一唠你关注的话题,说不定下期就有你想要的惊喜! 资讯类 1.瑞萨推出RZ/V系列微处理器搭 ...

  3. 基于数字电路交通灯信号灯控制系统设计-基于单片机病房温度监测与呼叫系统设计-基于STM32的无线蓝牙心电监护仪系统设计-基于STM32的智能蓝牙温控风扇控制设计-基于STM32的智能温室控制系统设计

    1617基于数字电路交通灯信号灯控制系统设计(仿真电路,论文报告)  摘  要:交通灯控制系统在城市交通控制中发挥着重要的作用,本次课程设计就是以城市交通灯控制系统为背景的,主要通过运用学过的数字电路 ...

  4. 基于STM32的智能温室控制系统仿真电路设计(温控补光)-基于STM32的智能蓝牙温控风扇控制系统设计-基于STM32的无线蓝牙心电监护仪系统设计【毕设课设分享】

    1609 基于STM32的智能蓝牙温控风扇控制系统设计-毕设课设 1.LCD1602液晶显示当前温度,温度上下限值,风扇等级,自动手动模式: 2.设置有4个按键,按键1可以设置自动和手动2种模式切换: ...

  5. 最简单DIY基于STM32单片机的蓝牙智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 文章目录 STM32库函数开发系列文 ...

  6. STM32控制HC-05蓝牙模块进行通信

    一.HC-05蓝牙模块 1. 简介 HC-05主从一体蓝牙串口模块采用英国CSR公司BlueCore4系列的芯片,符合符合蓝牙2.0+EDR规范,可以同带同种蓝牙功能的电脑.蓝牙主机和手机等智能终端配 ...

  7. K_A32_002 基于STM32等单片机驱动红外接收模块 串口+OLED0.96显示

    K_A32_002 基于STM32等单片机驱动红外接收模块 串口+OLED0.96显示 所有资源导航 一.资源说明 二.基本参数 参数 引脚说明 三.驱动说明 时序: 对应程序: 四.部分代码说明 1 ...

  8. 基于STM32单片机智能蓝牙PWM温控风扇带定时APP控制

    实践制作DIY- GC0009-智能蓝牙PWM温控风扇 一.功能说明: 基于STM32单片机设计-智能蓝牙PWM温控风扇 功能介绍: 1.基于STM32F103C系列,OLED,DHT11温度湿度传感 ...

  9. STM32开发实例 基于STM32单片机的蓝牙手环

    一.系统设计 本次是基于STM32单片机的简易蓝牙手环,手指放在心率检测处,心率传感器就能实时的检测使用者的心率的变化,并在显示屏上进行显示:通过DS18B20检测体温,体温数值也会在显示屏上进行显示 ...

最新文章

  1. CveService.java
  2. 网站真分页js代码该怎么写?
  3. 【C#学习笔记】退出程序
  4. 调用加了SSL签名的WebService
  5. c语言编写程序x的y次方,C语言变为编程y = x-x立方/ 3! + x五次方力量/ 5! -x7th power / 7!...
  6. Android Handler原理
  7. matlab怎么重新打开新的代码,方程求解程序代码求助-程序代码修改或新的代码...
  8. 异常检测3——AutoEncoder异常检测
  9. 创建目录_聊聊Word创建目录那些事儿
  10. 计蒜客——回文平方数
  11. in与exist , not in与not exist 的区别
  12. SQL Server Join方式
  13. linux锐捷认证成功无法上网,锐捷认证成功但是却无法上网怎么办
  14. 更新至2021各省份上传服务器地址(航信、百旺、税务UK)
  15. 方维直播源码:修复BUG完整版(附代码)
  16. 怎么用计算机计算化学,计算化学
  17. 计算机网络知识之1M宽带下载速度多少?
  18. 【3】少儿Python编程学习_从哪开始学习
  19. 【MMCV 源码解读】一、Config(配置文件相关)
  20. SAS统计初学1-卡方检验

热门文章

  1. 虚拟网络overlay、underlay
  2. 微信小程序中图片占满整个屏幕实现方法
  3. 在spring batch中如何使用rowmapper
  4. 数据中心 动环监控能效管理解决方案
  5. 人工智能是学术搜索的未来吗?
  6. WEB22_Js原生Ajax和Jquery的Ajax
  7. Android最新相机(Camera)拍照、拍视频全面总结
  8. java反编译微信小程序_反编译微信小程序(最新)
  9. 鸿蒙系统适配荣耀机型,荣耀鸿蒙系统支持的手机型号机型名单 曝6月开始适配...
  10. ASP.net:关于何种情况下使用DataGrid、DataList或Repeater