hc85蓝牙模块结合stm32单片机控制sg90舵机详细操作和完整代码
时间: 2025-07-16 12:17:14 浏览: 4
<think>好的,我现在需要详细回答用户关于如何使用HC-85蓝牙模块结合STM32单片机控制SG90舵机的详细操作和完整代码。首先,我得理清整个系统的组成部分以及它们之间的连接方式。用户可能对硬件连接和代码编写不太熟悉,所以需要分步骤解释。
首先,硬件部分。HC-85蓝牙模块通常通过串口与STM32通信,所以需要确定STM32的USART引脚。SG90舵机使用PWM信号控制,所以需要选择一个定时器的PWM通道。STM32常见的型号比如F103C8T6,可能需要使用TIM2或TIM3等定时器。然后要确认舵机的信号线连接到哪个GPIO,比如PA0或者PA1,对应的定时器通道是否正确。
接下来是蓝牙模块的配置。HC-85可能需要设置波特率,比如9600或者115200,需要确保STM32的串口波特率与之匹配。另外,蓝牙模块的工作模式,主从模式可能需要用户根据实际情况设置,但用户可能只需要基本的通信功能,所以这部分可能不需要深入,但需要提到AT指令配置的可能。
然后是PWM生成的配置。SG90舵机的控制信号是周期20ms的PWM波,高电平宽度在0.5ms到2.5ms之间对应0到180度。所以需要配置定时器以产生50Hz的PWM信号,占空比可调。例如,如果定时器时钟为72MHz,预分频和自动重装值需要计算正确,以得到20ms的周期。
代码部分需要包括初始化串口接收蓝牙数据,解析接收到的指令(比如角度值),然后调整PWM的占空比。可能需要使用中断来处理串口接收,或者使用DMA。但为了简化,可能采用轮询方式或者中断接收单个字符,组成字符串后解析。
需要注意的问题:电压匹配,舵机需要5V电源,而STM32的GPIO是3.3V,信号线可能需要电平转换,但实际中SG90可能可以直接用3.3V信号。另外,蓝牙模块的供电要稳定,可能需要外部电源,避免电流不足。
代码结构可能包括:初始化系统时钟,配置USART和定时器PWM,然后在主循环中处理接收到的数据,或者通过中断处理接收到的字符,转换为角度,再设置对应的PWM占空比。
可能的错误点:定时器配置不正确导致PWM频率不对,串口接收数据不完整,角度解析错误。需要确保代码中每一步都正确,特别是定时器的配置和占空比的计算。
现在需要将这些步骤系统化,分步骤解释硬件连接、代码结构,并提供示例代码。代码部分要包含必要的注释,帮助用户理解。同时提醒用户注意电源和接线问题,避免硬件损坏。</think>下面分步骤详细说明HC-85蓝牙模块结合STM32控制SG90舵机的操作流程:
---
### **一、硬件准备**
1. **硬件清单**
- STM32F103C8T6核心板
- HC-05/HC-06蓝牙模块(支持AT指令)
- SG90舵机(工作电压4.8-6V)
- 5V电源(单独给舵机供电)
- USB-TTL模块(用于蓝牙模块调试)
- 杜邦线若干
2. **接线图**
```
STM32 HC-85 SG90
PA9(TX) ----> RX
PA10(RX) <---- TX
VCC ----> VCC(3.3V)
GND ----> GND
舵机黄线 ---> PA6(PWM信号)
舵机红线 ---> 5V电源+
舵机棕线 ---> GND
```
---
### **二、蓝牙模块配置**
1. 使用AT指令设置参数(通过USB-TTL连接PC):
```bash
AT+NAME=MyServo # 设置蓝牙名称
AT+BAUD=4 # 设置波特率9600(对应数值参考模块手册)
AT+ROLE=0 # 设置为从机模式
```
---
### **三、STM32代码实现**
#### 1. PWM配置(TIM3_CH1)
```c
// PWM初始化函数
void PWM_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
TIM_OCInitTypeDef TIM_OCStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// 配置PA6为复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 定时器基础配置:50Hz(周期20ms)
TIM_BaseStruct.TIM_Period = 19999; // ARR值
TIM_BaseStruct.TIM_Prescaler = 71; // 72MHz/(71+1)=1MHz
TIM_BaseStruct.TIM_ClockDivision = 0;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_BaseStruct);
// PWM模式配置
TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_Pulse = 1500; // 初始占空比1.5ms(90度)
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCStruct);
TIM_Cmd(TIM3, ENABLE);
}
```
#### 2. 串口配置(USART1)
```c
void USART1_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA9(TX)为复用推挽,PA10(RX)为浮空输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 串口参数配置
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
}
```
#### 3. 主程序逻辑
```c
char rxBuffer[10];
uint8_t rxIndex = 0;
int main(void) {
SystemInit();
PWM_Init();
USART1_Init();
while(1) {
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) {
char ch = USART_ReceiveData(USART1);
if(ch == '\n') { // 接收到完整指令
int angle = atoi(rxBuffer);
angle = (angle < 0) ? 0 : (angle > 180) ? 180 : angle;
uint16_t pulse = 500 + angle * (2000 / 180); // 计算占空比
TIM_SetCompare1(TIM3, pulse); // 更新PWM
memset(rxBuffer, 0, sizeof(rxBuffer));
rxIndex = 0;
} else {
rxBuffer[rxIndex++] = ch;
}
}
}
}
```
---
### **四、手机端操作**
1. 使用蓝牙串口APP(如Serial Bluetooth Terminal)
2. 连接名为"MyServo"的蓝牙设备
3. 发送数字指令:
- `0` ➔ 舵机转到0度
- `90` ➔ 舵机转到90度
- `180` ➔ 舵机转到180度
---
### **五、注意事项**
1. 必须为舵机单独供电,避免STM32电流过载
2. PWM占空比范围对应500-2500μs(0.5ms-2.5ms)
3. 蓝牙模块与STM32共地
4. 遇到舵机抖动时,检查电源稳定性
完整工程代码可在Keil MDK中编译,建议使用STM32CubeMX生成初始化代码以简化配置。实际应用中需添加数据校验和错误处理机制。
阅读全文
相关推荐



















