STM32嵌入式开发蓝牙模块怎么使用
蓝牙模块
第一节:蓝牙模块如何与STM32连接并传输信息
目录
蓝牙模块
二、使用步骤
1.JDY31.c
2.JDY31.h
3.main.c
总结
前言
本文将重点介绍如何在STM32微控制器上实现与蓝牙模块的连接。STM32是一款常用的嵌入式微控制器,具有强大的处理能力和丰富的外设接口,非常适合用于开发各种智能设备。通过与蓝牙模块的连接,STM32可以实现与其他蓝牙设备之间的数据传输和通信,从而拓展了其应用场景和功能。
一、蓝牙是什么?
这里我们以JDY-31蓝牙为例,其他蓝牙基本相似。
JDY31蓝牙模块是一种蓝牙通信模块,它可以实现无线数据传输和通信功能。该模块采用了JDY系列芯片,具有低功耗、稳定性好、传输距离远等特点。JDY31蓝牙模块可以广泛应用于无线通信、智能家居、医疗器械、智能穿戴等领域。该模块可以与其他蓝牙设备进行配对,实现数据传输和远程控制。



二、使用步骤
1.JDY31.c
代码如下(示例):
#include "stm32f10x.h" // 设备头文件
#include <stdio.h>
#include <stdarg.h>
uint8_t JDY31_RxData; // 存储接收到的数据
uint8_t JDY31_RxFlag; // 接收标志位
// 初始化JDY31蓝牙模块
void JDY31_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0}; // GPIO初始化结构体
USART_InitTypeDef USART_InitStruct = {0}; // USART初始化结构体
NVIC_InitTypeDef NVIC_InitStruct = {0}; // 中断向量表初始化结构体
// 使能GPIOB和USART3的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
// 配置USART3的TX引脚(PB10)为复用推挽输出模式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置USART3的RX引脚(PB11)为浮空输入模式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置USART3的基本参数
USART_InitStruct.USART_BaudRate = 9600; // 波特率设置为9600
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位长度为8位
USART_InitStruct.USART_Parity = USART_Parity_No; // 无校验位
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位为1位
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 同时开启接收和发送功能
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控
USART_Init(USART3, &USART_InitStruct);
// 使能USART3的接收中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// 配置USART3中断优先级
NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
// 使能USART3
USART_Cmd(USART3, ENABLE);
}
// 发送一个字节的数据到JDY31蓝牙模块
void JDY31_SendByte(uint8_t Byte)
{
USART_SendData(USART3, Byte); // 将数据放入发送缓冲区
while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); // 等待发送完成
}
// 发送一个数组的数据到JDY31蓝牙模块
void JDY31_SendArray(uint8_t *Array, uint16_t Length)
{
uint16_t i;
for (i = 0; i < Length; i ++)
{
JDY31_SendByte(Array[i]); // 循环发送数组中的每一个字节
}
}
// 发送字符串到JDY31蓝牙模块
void JDY31_SendString(char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)
{
JDY31_SendByte(String[i]); // 循环发送字符串中的每一个字符
}
}
// 计算X的Y次方
uint32_t JDY31_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result = 1;
while (Y --)
{
Result *= X; // 循环乘法计算X的Y次方
}
return Result;
}
// 发送数字到JDY31蓝牙模块
void JDY31_SendNumber(uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i ++)
{
JDY31_SendByte(Number / JDY31_Pow(10, Length - i - 1) % 10 + '0'); // 提取每一位数字并发送
}
}
// 使用printf格式化输出数据到JDY31蓝牙模块
void JDY31_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg); // 格式化字符串
va_end(arg);
JDY31_SendString(String); // 发送格式化后的字符串
}
2.JDY31.h
代码如下(示例):
#ifndef __JDY31_H
#define __JDY31_H
#include <stdio.h>
// 声明外部变量JDY31_RxData,用于存储接收到的数据
extern uint8_t JDY31_RxData;
// 声明外部变量JDY31_RxFlag,用于表示接收标志位
extern uint8_t JDY31_RxFlag;
// 初始化JDY31蓝牙模块
void JDY31_Init(void);
// 发送一个字节的数据到JDY31蓝牙模块
void JDY31_SendByte(uint8_t Byte);
// 发送一个数组的数据到JDY31蓝牙模块
void JDY31_SendArray(uint8_t *Array, uint16_t Length);
// 发送字符串到JDY31蓝牙模块
void JDY31_SendString(char *String);
// 发送数字到JDY31蓝牙模块
void JDY31_SendNumber(uint32_t Number, uint8_t Length);
// 使用printf格式化输出数据到JDY31蓝牙模块
void JDY31_Printf(char *format, ...);
#endif
3.main.c
代码如下(示例):
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "JDY31.h"
/*
串口3(USART3)
TX PB10
RX PB11
*/
int main()
{
OLED_Init(); // 初始化OLED显示屏
JDY31_Init(); // 初始化JDY31蓝牙模块
while(1)
{
OLED_ShowString(0, 0, "RX:", OLED_8X16); // 在OLED上显示“RX:”
OLED_ShowChar(24, 0, JDY31_RxData, OLED_8X16); // 显示接收到的数据
if(JDY31_RxFlag == 1) // 检查是否接收到数据
{
// 处理接收到的数据
JDY31_SendString("RX_OK"); // 发送确认信息到蓝牙模块
JDY31_RxFlag = 0; // 清除接收标志位
// 示例:根据接收到的数据执行不同的操作
switch (JDY31_RxData)
{
case 'A':
OLED_ShowString(0, 2, "Received A", OLED_8X16); // 显示接收到'A'
break;
case 'B':
OLED_ShowString(0, 2, "Received B", OLED_8X16); // 显示接收到'B'
break;
default:
OLED_ShowString(0, 2, "Unknown", OLED_8X16); // 显示未知字符
break;
}
}
OLED_Update(); // 更新OLED显示
}
}
// 数据接收中断服务程序
void USART3_IRQHandler(void)
{
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) // 检查接收缓冲区非空中断标志
{
JDY31_RxData = USART_ReceiveData(USART3); // 读取接收到的数据
JDY31_RxFlag = 1; // 设置接收标志位
USART_ClearITPendingBit(USART3, USART_IT_RXNE); // 清除接收中断标志
}
}
总结
-
硬件准备:获取一个STM32F103C8T6开发板和一个蓝牙模块(如HC-05或HC-06)。将蓝牙模块连接到开发板的串口引脚(TX和RX),并将模块的电源引脚连接到3.3V电源引脚。
-
软件准备:安装STM32CubeIDE开发环境,并创建一个新的STM32Cube工程。选择正确的MCU型号(STM32F103C8T6),并选择合适的时钟配置和外设配置。
-
串口初始化:在工程代码中添加串口初始化代码。配置串口的波特率、数据位、停止位和校验位等参数。
-
蓝牙通信:使用串口的发送和接收函数来与蓝牙模块进行通信。可以使用AT指令集来配置蓝牙模块的参数,如名称、配对码等。也可以使用串口发送和接收数据来实现与其他蓝牙设备的通信。
-
主程序:在主程序中添加代码来处理蓝牙连接和数据传输。可以使用中断或轮询方式来接收蓝牙模块发送的数据,然后进行相应的处理。
需要注意的是,连接蓝牙模块之前,需要确保蓝牙模块处于可配对和可连接状态。也要注意蓝牙模块的供电电压和电流要求,以及串口引脚的电平适配和电气特性匹配。另外,还要注意蓝牙模块的串口通信协议和数据格式,以便正确解析和处理蓝牙模块发送的数据。
作者:一起开发吧