一、项目简介
本项目基于 STM32F103 实现通过 PWM 控制舵机角度,每次按键按下,舵机角度增加 30°,并在 OLED 屏幕上显示当前角度数值。适合作为 STM32 PWM 控制舵机的入门实践。
二、硬件准备
硬件模块 | 用途 |
---|---|
STM32F103C8T6 | 主控芯片 |
SG90/MG995 舵机 | 控制角度旋转 |
0.96寸 OLED(I2C) | 实时显示角度 |
按键模块 | 控制角度变化 |
外部电源(推荐) | 给舵机供电 |
三、核心原理
-
使用 TIM3 输出 PWM 控制舵机
-
舵机一般使用 50Hz(周期20ms)PWM
- 0.5ms ≈ 0°,1.5ms ≈ 90°,2.5ms ≈ 180°
-
通过控制 PWM 的占空比,控制舵机的角度
-
使用按键触发角度增加,每次 +30°
-
OLED 实时显示当前角度
四、主函数代码
cpp
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "Key.h"
uint8_t KeyNum;
float Angle;
int main(){
OLED_Init(); // OLED初始化
Servo_Init(); // PWM舵机初始化
Key_Init(); // 按键初始化
OLED_ShowString(1,1,"Angle:");
while(1){
KeyNum = Key_GetNum(); // 获取按键值
if(KeyNum == 1){ // 按键1被按下
Angle += 30; // 增加30°
if(Angle > 180){
Angle = 0; // 超过180°重置
}
}
Servo_SetAngle(Angle); // 设置舵机角度
OLED_ShowNum(1,7,Angle,3); // OLED显示角度
}
}
五、舵机驱动代码
cpp
#include "stm32f10x.h" // Device header
#include "PWM.h"
void Servo_Init(void)
{
PWM_Init();
}
void Servo_SetAngle(float Angle)
{
PWM_SetCompare2(Angle/180*2000 + 500);
}
六、PWM驱动代码
cpp
#include "stm32f10x.h" // Device header
void PWM_Init(void){
//开启RCC时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//初始化GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);//定时器上电后默认开启的内部时钟
//初始化时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruncture;
TIM_TimeBaseInitStruncture.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStruncture.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruncture.TIM_Period=20000-1; //ARR
TIM_TimeBaseInitStruncture.TIM_Prescaler=72-1; //PSC
TIM_TimeBaseInitStruncture.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruncture);
//OC输出比较初始化
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse=0; //CCR
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
//启动定时控制器
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare2(uint16_t Compare){
TIM_SetCompare2(TIM2,Compare);
}
七、总结
本项目通过 PWM 控制舵机,结合 OLED 显示和按键交互,实现了一个经典的嵌入式入门项目,适用于机器人、机械臂、舵机教学等场景。