【新星计划】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…...
Unity基础-Mathf相关
Unity基础-Mathf相关 一、Mathf数学工具 概述 Mathf是Unity中封装好用于数学计算的工具结构体,提供了丰富的数学计算方法,特别适用于游戏开发场景。它是Unity开发中最常用的数学工具之一,能够帮助我们处理各种数学计算和插值运算。 Mathf…...
uni-app学习笔记三十--request网络请求传参
request用于发起网络请求。 OBJECT 参数说明 参数名类型必填默认值说明平台差异说明urlString是开发者服务器接口地址dataObject/String/ArrayBuffer否请求的参数App 3.3.7 以下不支持 ArrayBuffer 类型headerObject否设置请求的 header,header 中不能设置 Refere…...
十、【ESP32开发全栈指南: TCP客户端】
一、TCP协议核心特性回顾 TCP与UDP关键差异 特性TCPUDP连接方式面向连接 (三次握手)无连接可靠性可靠传输 (重传/排序/校验)尽力交付数据顺序保证数据按序到达不保证顺序流控制滑动窗口机制无流控制传输效率协议开销大头部开销小适用场景文件传输、网页浏览实时音视频、广播通…...

二叉树-226.翻转链表-力扣(LeetCode)
一、题目解析 翻转可以理解为树的左右子树交换,从根到叶子节点,但是这里交换的是链接的指针,而不是单纯的交换值,当出现nullptr时,也是可以交换链接的,交换值的话就不行了。 二、算法原理 依旧的递归&…...

词法分析和词性标注 自然语言处理
目录 一. 概述 1 不同语言的词法分析 2 英语的形态分析 英语单词的形态还原(和正常英语的词法变化一样) 1.有规律变化单词的形态还原 编辑 2.动词、名词、形容词、副词不规则变化单词的形态还原 3.对于表示年代&…...

1.springmvc基础入门(一)
1.Spring MVC概念 Spring MVC 是 Spring Framework 提供的 Web 组件,全称是 Spring Web MVC,是⽬前主流的实现 MVC 设计模式的框架,提供前端路由映射、视图解析等功能。 Java Web 开发者必须要掌握的技术框架。 2.Spring MVC 功能 MVC&am…...

spring task定时任务快速入门
spring task它基于注解和配置,可以轻松实现任务的周期性调度、延迟执行或固定频率触发。按照我们约定的时间自动执行某段代码。例如闹钟 使用场景 每月还款提醒,未支付的订单自动过期,收到快递后自动收货,系统自动祝你生日快乐等…...
2480: 2020年06月2级T1:计算矩阵边缘元素之和
题目描述 2020年06月2级第一题题目:计算矩阵边缘元素之和 输入一个整数矩阵,计算位于矩阵边缘的元素之和。所谓矩阵边缘的元素,就是第一行和最后一行的元素以及第一列和最后一列的元素。 输入 第一行分别为矩阵的行数m和列数n࿰…...
Postgresql字符串操作函数
目录 一、基础字符串操作 二、大小写转换 三、空白处理 四、子串提取 五、搜索与定位 六、字符串修改 七、填充与格式化 八、编码转换 九、正则表达式(高级匹配) 十、其他实用函数 使用技巧: 以下是 PostgreSQL 中最全面的常用字符…...

【汇编逆向系列】三、函数调用包含单个参数之float类型-xmm0寄存器,sub,rep,stos,movss,mulss,addss指令
一、汇编代码 single_float_param:0000000000000060: F3 0F 11 44 24 08 movss dword ptr [rsp8],xmm00000000000000066: 57 push rdi0000000000000067: 48 83 EC 10 sub rsp,10h000000000000006B: 48 8B FC mov …...