【新星计划】STM32F103C8T6 - C语言 - 蓝牙JDY-31-SPP串口通信实验
文章目录
- 蓝牙技术的发展历史
- SPP蓝牙串口
- BLE协议(超低功耗应用蓝牙协议)
- 常见通用蓝牙模块
- JDY-31-SPP
- HC05/06
- Keil 工程开发模版
- main.c 源文件:
- 接线方式:
- 烧录工具:FlyMcu
- 串口调试工具:XCOM
- 蓝牙调试助手APP
- 实验效果:
蓝牙技术的发展历史
蓝牙技术的发展历史可以追溯到20世纪90年代初,当时瑞典通信公司Ericsson(爱立信)推动了一个名为“蓝牙”(Bluetooth)的项目。该项目的目标是通过无线连接来取代使用电缆传输数据和语音的设备。因此,蓝牙技术在企业中也往往与音频技术息息相关,如今最常见的产品就是无线蓝牙耳机与手机通讯:
蓝牙技术发展流历史:
在1996年,Ericsson成立了一个推动该技术的蓝牙SIG(特别兴趣组)。
1998年:蓝牙技术的第一个版本1.0发布,并且开始吸引其他公司的注意。这个版本的蓝牙规范定义了基本的无线连接协议,能够在短距离范围内(通常为10米)连接设备,并提供较低的功耗和可靠的数据传输。
1999年:推出了蓝牙技术的1.1版本,修复了一些早期版本中的问题,提高了互操作性和音频质量。
2000年:蓝牙技术的2.0版本发布。这个版本引入了增强数据传输速率的“增强数据速率”(Enhanced Data
Rate,EDR)功能,使得蓝牙连接更快速。同时,2.0版本还提供了蓝牙自适应频率跳频(AFH)功能,以减少干扰。
2003年:蓝牙技术的2.1版本发布,引入了更快的配对过程和安全增强功能。
2009年:蓝牙技术的3.0版本发布,引入了高速率的无线传输技术。这个版本可以通过Wi-Fi进行更高速的数据传输,并称为蓝牙高速(Bluetooth
High Speed)。 2010年:蓝牙技术的4.0版本发布,引入了低功耗功能,被称为蓝牙低功耗(Bluetooth Low
Energy,BLE),以满足物联网设备的需求,如传感器和健康监测设备。
2016年:蓝牙技术的5.0版本发布,提供更长的通信范围、更高的传输速率和更低的功耗。这个版本对物联网和无线音频设备提供了更好的支持。
从此以后,蓝牙技术继续发展,不断推出新的版本和改进,以满足不断增长的无线连接需求,并为各种设备提供更好的互联性和互操作性。
SPP蓝牙串口
通常我们所说的蓝牙实际就是基于SPP协议(Serial Port Profile)的蓝牙串口通信。
SPP蓝牙串口能在蓝牙设备之间创建串口进行数据传输的一种设备。蓝牙串口的目的是针对如何在两个不同设备(通信的两端)上的应用之间保证一条完整的通信路径。
具体的SPP协议技术栈包含很多通信相关的内容,大致流程如下:
建立连接:在SPP通信之前,需要确保两个蓝牙设备(例如,一台手机和一台蓝牙串口透传模块)之间已经成功建立了蓝牙连接。
配对和授权:在建立蓝牙连接之后,如果需要进行配对(Pairing)和授权(Authorization),则需要执行相应的配对和授权步骤。这确保了通信双方对彼此的身份进行验证和授权。
端口配置:在连接建立和授权完成后,进行端口配置以设置通信参数,如波特率、数据位、停止位、校验等。常见的配置方式是使用AT命令(如果蓝牙设备支持)或者通过蓝牙协议栈提供的API。
数据传输:一旦端口配置完成,通信双方可以开始进行数据传输。在SPP中,数据按字节流的方式进行传输,类似于传统的串口通信。发送方将数据通过蓝牙连接发送到接收方,并且接收方通过蓝牙连接接收和处理这些数据。
错误检测和纠正:在SPP通信中,数据传输过程中的错误可以使用CRC(循环冗余检测)等机制进行检测和纠正。这种机制可以帮助确保数据传输的准确性和可靠性。
需要注意的是,SPP协议只提供了基本的串口通信功能,并且在不同的蓝牙设备和应用中可能会有一些差异和扩展。因此,具体的通信过程还可能因设备和应用而异。对于深入理解和实现SPP协议,建议查阅相关的SPP规范和文档。
BLE协议(超低功耗应用蓝牙协议)
BLE(Bluetooth Low Energy)是一种低功耗蓝牙通信技术,被广泛应用于物联网和可穿戴设备等领域。BLE协议栈包含多个协议层,其中最重要的是GAP(Generic Access Profile)、GATT(Generic Attribute Profile)和ATT(Attribute Protocol)。
BLE通信过程大致如下:
建立连接:BLE通信的第一步是设备之间的连接。连接过程发生在GAP层,其中一个设备作为广播器(广播Adv)发送广告数据包,另一个设备作为扫描器(扫描Scan)接收广告数据包。通过广告和扫描,设备可以发现彼此并尝试建立连接。
建立连接参数协商:连接建立后,进行连接参数协商。双方协商通信的参数,如连接间隔、广播间隔和数据长度等。这些参数决定了通信速率和功耗。
发现服务和特征:连接成功后,扫描器设备可以通过GATT和ATT协议发现广播器设备上的服务和特征(Characteristics)。服务和特征提供了设备之间交换数据的接口。
特征值读写:一旦服务和特征被发现,扫描器可以读取或写入特征值进行数据交换。一个设备可以向另一个设备检索数据或发送数据。
订阅和通知:在某些情况下,设备可以通过订阅特征来接收数据的通知。当特征值有更新时,设备会收到通知或指示,以便进行相应的处理。
常见通用蓝牙模块
JDY-31-SPP
本文选用的蓝牙模块就是JDY-31,JDY31支持SPP协议,支持 AT 指令集。
HC05/06
更常用的HC05/06模块同样包含AT命令模式,价格要稍贵一些。HC05和06用法没有太大区别,HC05带复位按钮。
Keil 工程开发模版
使用Keil进行基于STM32的开发通常需要先创建一个基本工程模版,包含常用的库函数和头文件,之后再学习其他模块时直接更换模版中的main.c源文件内容即可。
读者可以下载本文创建好的工程附件直接烧录运行:

main.c 源文件:
//引用库函数头文件
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_crc.h"
#include "system_stm32f10x.h"
#include "stdio.h"//函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void delay_ms(u16 time);void UART_PutChar(USART_TypeDef* USARTx, uint8_t Data);
void UART_PutStr(USART_TypeDef* USARTx, uint8_t *str);
int Putchat(int c);//主函数
int main()
{SystemInit();RCC_Configuration();GPIO_Configuration();USART_Configuration();while(1){UART_PutStr(USART1, "Access successfully\r\n"); //打印信息delay_ms(1000);}
}//函数定义
void RCC_Configuration(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB,ENABLE);
}
void GPIO_Configuration(void) //串口引脚配置
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //定义PA9为TXD(发送引脚)通常使用推挽输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能(Alternate Function)推挽输出模式GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //定义PA10为RXD(接收引脚)GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //复用功能(Input Pull-Up)输入上拉模式GPIO_Init(GPIOA, &GPIO_InitStructure);
}void USART_Configuration(void) //串口通信初始化配置
{USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600; //波特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1,&USART_InitStructure);USART_Cmd(USART1,ENABLE);
}void delay_ms(u16 time)
{u16 i=0;while(time--){i = 12000;while(i--);}
}int Putchar(int c)
{if (c == '\n'){putchar('\r');}USART_SendData(USART1,c);while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {};return c;
}void UART_PutChar(USART_TypeDef*USARTx, uint8_t Data)
{USART_SendData(USARTx, Data);while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET) {};
}void UART_PutStr(USART_TypeDef*USARTx, uint8_t *str) //打印字符串函数定义
{while(0 != *str){UART_PutChar(USARTx, *str);str++;}
}
接线方式:
MCU的PA9(TXD)连接蓝牙模块的RXD,PA10(RXD)连接蓝牙模块的TXD,默认密码:1234;
此外蓝牙模块还需要连接5V供电,5V电源可来源于直流稳压电源或市面上可购买到的电源模块;
MCU通过电源模块进行供电,并通过USB连接计算机进行烧录,BOOT1与BOOT0都连接到GND,在FlyMcu中点击开始编程后按下MCU的复位键后程序就烧录进去了。

烧录工具:FlyMcu
选择如下烧录方式将hex文件下载到MCU:

串口调试工具:XCOM
连接好MCU与蓝牙模块、计算机后,烧录程序,可在XCOM中查看到串口打印信息,说明连接正确。

蓝牙调试助手APP
安卓应用市场搜索SPP蓝牙串口APP,点击搜索可用设备,连接后选择编解码格式为 utf-8(默认为hex模式)防止显示乱码。
实验效果:
可以看到将移动设备端(手机)和MCU通过蓝牙连接后,可以正常接收打印出来的 “Access Successfully” 信息。

缺点:实验中发现通过JDY31蓝牙传输发送的信息误码率还是比较高的,经常会出现隔行乱码的情况。

参考:
STM32F103C8T6单片机HC-06蓝牙手机通讯实验NO.2
【半导体】一文读懂什么是BLE(超低功耗应用蓝牙协议)
【蓝牙模块】三款常用的基础蓝牙模块,HC05,JDY-31,CC2541介绍与测试说明
智能车从入门到入土(DAY1)————JDY31蓝牙模块的简单介绍
引用部分来源于VScode商店 - ChatMoss - GPT-3.5,使用教程:ChatMoss主页
相关文章:
【新星计划】STM32F103C8T6 - C语言 - 蓝牙JDY-31-SPP串口通信实验
文章目录 蓝牙技术的发展历史SPP蓝牙串口BLE协议(超低功耗应用蓝牙协议) 常见通用蓝牙模块JDY-31-SPPHC05/06 Keil 工程开发模版main.c 源文件:接线方式:烧录工具:FlyMcu串口调试工具:XCOM蓝牙调试助手APP …...
算法39:Excel 表列序号
一、需求 给你一个字符串 columnTitle ,表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如: A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2&…...
Android:ImageView xml方式配置selector 图片切换
1、在res/drawable目录下创建一个新的XML文件,比如selector_image.xml <?xml version"1.0" encoding"utf-8"?> <selector xmlns:android"http://schemas.android.com/apk/res/android"> <!-- 背景选择器 state_pre…...
Spring Boot 缓存 Cache 入门
Spring Boot 缓存 Cache 入门 1.概述 在系统访问量越来越大之后,往往最先出现瓶颈的往往是数据库。而为了减少数据库的压力,我们可以选择让产品砍掉消耗数据库性能的需求。 当然也可以引入缓存,在引入缓存之后,我们的读操作的代码ÿ…...
如何关闭谷歌浏览器自动更新
适用范围: 写自动化脚本时,需要安装浏览器驱动,安装浏览器驱动时需要下载对应的浏览器驱动版本,如果浏览器版本一直在自动更新的话,自动化脚本会报错浏览器版本和浏览器驱动不匹配,所以建议关闭谷歌浏览器自动更新&am…...
mybatis日志工厂
前言: 如果一个数据库操作,出现异常,我们需要排错,日志就是最好的助手 官方给我们提供了logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 默认工厂: 在配置文件里添加…...
020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试
020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试 上节学习了FatFs文件系统的相关知识,这节内容继续学习在STM32上如何移植FatFs文件系统,并且实现文件的创建、读、写与删除等功能。各位看官觉得还行的话点点赞,…...
flask用DBUtils实现数据库连接池
flask用DBUtils实现数据库连接池 在 Flask 中,DBUtils 是一种实现数据库连接池的方案。DBUtils 提供了持久性(persistent)和透明的(transient)两种连接池类型。 首先你需要安装 DBUtils 和你需要的数据库驱动。例如&…...
SQL注入之布尔盲注
SQL注入之布尔盲注 一、布尔盲注介绍二、布尔盲注的特性三、布尔盲注流程3.1、确定注入点3.2、判断数据库的版本3.3、判断数据库的长度3.4、猜解当前数据库名称(本步骤需要重复)3.5、猜解数据表的数量3.6、猜解第一个数据表名称的长度3.7、猜解第一个数据…...
微服务入门---SpringCloud(一)
微服务入门---SpringCloud(一) 1.认识微服务1.0.学习目标1.1.单体架构1.2.分布式架构1.3.微服务1.4.SpringCloud1.5.总结 2.服务拆分和远程调用2.1.服务拆分原则2.2.服务拆分示例2.2.1.导入Sql语句2.2.2.导入demo工程 2.3.实现远程调用案例2.3.1.案例需求…...
Rust vs Go:常用语法对比(九)
题图来自 Golang vs Rust - The Race to Better and Ultimate Programming Language 161. Multiply all the elements of a list Multiply all the elements of the list elements by a constant c 将list中的每个元素都乘以一个数 package mainimport ( "fmt")func …...
Typescript 第五章 类和接口(多态,混入,装饰器,模拟final,设计模式)
第五章 类和接口 类是组织和规划代码的方式,是封装的基本单位。 typescript类大量借用了C#的相关理论,支持可见性修饰符,属性初始化语句,多态,装饰器和接口。 不过,由于Typescript将类编译成常规的JavaScri…...
IFNULL()COALESCE()
在 MySQL 中,IFNULL() 函数是可用的,但是请注意它不能直接用于聚合函数的结果。要在聚合函数结果可能为 NULL 的情况下返回特定值,应该使用 COALESCE() 函数而不是 IFNULL() 函数。 以下是代码示例: COALESCE(SUM(pc.CONTRACT_T…...
WPF实战学习笔记23-首页添加功能
首页添加功能 实现ITodoService、IMemoService接口,并在构造函数中初始化。新建ObservableCollection<ToDoDto>、 ObservableCollection<MemoDto>类型的属性,并将其绑定到UI中修改Addtodo、Addmemo函数,将添加功能添加 添加添加…...
OpenCV-Python常用函数汇总
OpenCV Python OpenCV简述显示窗口waitKey():等待按键输入namedWindow():创建窗口destroyWindow() :注销指定窗口destroyAllWindows() 注销全部窗口resizeWindow() 调整窗口尺寸 图像操作imread():读取图像imwrite():保…...
Vue-router多级路由
目录 直接通过案例的形式来演示多级路由的用法 文件结构 Banner.vue <template><div class"col-xs-offset-2 col-xs-8"><div class"page-header"><h2>Vue Router Demo</h2></div></div> </template><…...
前端学习--vue2--2--vue指令基础
写在前面: 前置内容 - vue配置 文章目录 插值表达式v-html条件渲染v-show和v-ifv-ifv-if的扩展标签复用组件 v-show v-on /事件v-bind /:属性v-modelv-for 循环元素v-slotv-prev-cloak vue指令只的是带有v-前缀的特殊标签属性 插值表达式 插值表达式{…...
【Python机器学习】实验03 logstic回归
文章目录 简单分类模型 - 逻辑回归1.1 准备数据1.2 定义假设函数Sigmoid 函数 1.3 定义代价函数1.4 定义梯度下降算法gradient descent(梯度下降) 1.5 绘制决策边界1.6 计算准确率1.7 试试用Sklearn来解决2.1 准备数据(试试第二个例子)2.2 假设函数与前h相同2.3 代价函数与前相…...
面试-杨辉三角python递归实现,二进制转换
杨辉三角 def yang_hui(x,y):xint(x)yint(y)assert x>y,列数不应该大于行数# x 表示行,y表示列if y1 or yx:return 1else:return yang_hui(x-1,y-1)yang_hui(x-1,y)xinput(输入第几行) yinput(输入第几列) resultyang_hui(int(x),int(y)) print(result) #inclu…...
SPEC CPU 2017 x86_64 Ubuntu 22.04 LTS LLVM 16.0.6 编译 intrate intspeed
源码编译llvm 下载源码 yeqiangyeqiang-MS-7B23:~/Downloads/src$ git clone --depth1 -b 7cbf1a2 https://github.com/llvm/llvm-project 正克隆到 llvm-project... warning: 不能发现要克隆的远程分支 7cbf1a2。 fatal: 远程分支 7cbf1a2 在上游 origin 未发现 yeqiangyeqi…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
