最经典的 STM32 蓝牙入门实验,逻辑非常简单:
手机蓝牙发送指令 → STM32 串口接收 → 控制 LED 亮灭
STM32F103 + HC‑05 蓝牙模块
一、硬件连接(非常重要)
1、HC‑05 蓝牙模块 ↔ STM32F103
| HC‑05 | STM32F103 | 说明 |
|---|---|---|
| VCC | 5V | 蓝牙功耗较大 |
| GND | GND | |
| TXD | PA10 (USART1_RX) | 蓝牙 → 单片机 |
| RXD | PA9 (USART1_TX) | 单片机 → 蓝牙 |
注意:
- HC‑05 是 3.3V 电平容忍,RX 可直接接 STM32
- 如果不确定,串 1k 电阻更安全
2、 LED 连接
| LED | STM32 |
|---|---|
| 正极 | PB12(串联 220Ω 电阻) |
| 负极 | GND |
二、软件设计思路
手机蓝牙APP
↓
HC-05 串口
↓
USART1 接收中断
↓
判断收到 '1' / '0'
↓
PB12 输出高 / 低
三、核心源码(标准外设库)
1、LED 初始化
c
// led.c
#include "led.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_12); // 默认熄灭
}
c
// led.h
#ifndef __LED_H
#define __LED_H
void LED_Init(void);
#define LED_ON() GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define LED_OFF() GPIO_SetBits(GPIOB, GPIO_Pin_12)
#endif
2、串口初始化(蓝牙)
c
// usart.c
#include "usart.h"
#include "stm32f10x_usart.h"
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// PA9 TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PA10 RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600; // HC-05 默认波特率
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);
// 开启接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
3、串口中断(核心逻辑)
c
// usart.c(续)
#include "led.h"
void USART1_IRQHandler(void)
{
uint8_t data;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
data = USART_ReceiveData(USART1);
if(data == '1')
{
LED_ON(); // 手机发 1 → LED亮
}
else if(data == '0')
{
LED_OFF(); // 手机发 0 → LED灭
}
}
}
4、 main.c
c
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
int main(void)
{
LED_Init();
USART1_Init();
while(1)
{
// 主循环什么都不用做
}
}
参考代码 STM32蓝牙接收让LED亮 www.youwenfan.com/contentcsv/103461.html
四、手机端操作
安卓 APP 推荐
- 蓝牙串口助手
- Serial Bluetooth Terminal
操作步骤
-
打开手机蓝牙
-
搜索并配对 HC‑05 (密码一般是
1234或0000) -
连接成功后
-
发送:
1 → LED 亮 0 → LED 灭
五、常见问题排查
| 现象 | 原因 |
|---|---|
| 没反应 | 波特率不是 9600 |
| 乱码 | 晶振不是 8MHz |
| 能配对但收不到 | TX/RX 接反 |
| LED 不亮 | 引脚不对 / 没接电阻 |
| 只能接收一次 | 没清中断标志 |