【新星计划】STM32F103C8T6 - C语言 - 蓝牙JDY-31-SPP串口通信实验

文章目录

蓝牙技术的发展历史

蓝牙技术的发展历史可以追溯到20世纪90年代初,当时瑞典通信公司Ericsson(爱立信)推动了一个名为"蓝牙"(Bluetooth)的项目。该项目的目标是通过无线连接来取代使用电缆传输数据和语音的设备。因此,蓝牙技术在企业中也往往与音频技术息息相关,如今最常见的产品就是无线蓝牙耳机与手机通讯:

图为上海山景的BP10开发板与手机进行蓝牙音频通信指标测试场景

蓝牙技术发展流历史:

在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 源文件:

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主页

相关推荐
aaasssdddd963 小时前
python和c
c语言·开发语言·python
凯子坚持 c4 小时前
C语言复习概要(三)
c语言·开发语言
无限大.4 小时前
c语言200例 067
java·c语言·开发语言
打地基的小白4 小时前
软件I2C-基于江科大源码进行的原理解析和改造升级
stm32·单片机·嵌入式硬件·通信模式·i2c
无限大.4 小时前
c语言实例
c语言·数据结构·算法
Death2004 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
Echo_cy_5 小时前
STM32 DMA+AD多通道
stm32·单片机·嵌入式硬件
朴人5 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
stm32·单片机·嵌入式硬件·foc
追梦少年时5 小时前
STM32中断——外部中断
stm32·单片机·嵌入式硬件
Death2005 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#