STM32嵌入式开发蓝牙模块怎么使用

蓝牙模块

第一节:蓝牙模块如何与STM32连接并传输信息


目录

蓝牙模块

二、使用步骤

1.JDY31.c

2.JDY31.h

3.main.c

总结


前言

        本文将重点介绍如何在STM32微控制器上实现与蓝牙模块的连接。STM32是一款常用的嵌入式微控制器,具有强大的处理能力和丰富的外设接口,非常适合用于开发各种智能设备。通过与蓝牙模块的连接,STM32可以实现与其他蓝牙设备之间的数据传输和通信,从而拓展了其应用场景和功能。


一、蓝牙是什么?

        这里我们以JDY-31蓝牙为例,其他蓝牙基本相似。

        JDY31蓝牙模块是一种蓝牙通信模块,它可以实现无线数据传输和通信功能。该模块采用了JDY系列芯片,具有低功耗、稳定性好、传输距离远等特点。JDY31蓝牙模块可以广泛应用于无线通信、智能家居、医疗器械、智能穿戴等领域。该模块可以与其他蓝牙设备进行配对,实现数据传输和远程控制。

JDY-31蓝牙

引脚标识

PCB原理图

二、使用步骤

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);  // 清除接收中断标志
    }
}

总结

  1. 硬件准备:获取一个STM32F103C8T6开发板和一个蓝牙模块(如HC-05或HC-06)。将蓝牙模块连接到开发板的串口引脚(TX和RX),并将模块的电源引脚连接到3.3V电源引脚。

  2. 软件准备:安装STM32CubeIDE开发环境,并创建一个新的STM32Cube工程。选择正确的MCU型号(STM32F103C8T6),并选择合适的时钟配置和外设配置。

  3. 串口初始化:在工程代码中添加串口初始化代码。配置串口的波特率、数据位、停止位和校验位等参数。

  4. 蓝牙通信:使用串口的发送和接收函数来与蓝牙模块进行通信。可以使用AT指令集来配置蓝牙模块的参数,如名称、配对码等。也可以使用串口发送和接收数据来实现与其他蓝牙设备的通信。

  5. 主程序:在主程序中添加代码来处理蓝牙连接和数据传输。可以使用中断或轮询方式来接收蓝牙模块发送的数据,然后进行相应的处理。

需要注意的是,连接蓝牙模块之前,需要确保蓝牙模块处于可配对和可连接状态。也要注意蓝牙模块的供电电压和电流要求,以及串口引脚的电平适配和电气特性匹配。另外,还要注意蓝牙模块的串口通信协议和数据格式,以便正确解析和处理蓝牙模块发送的数据。

作者:一起开发吧

物联沃分享整理
物联沃-IOTWORD物联网 » STM32嵌入式开发蓝牙模块怎么使用

发表回复