> 技术文档 > STM32 使用PWM控制舵机角度(按键调节 + OLED显示

STM32 使用PWM控制舵机角度(按键调节 + OLED显示

演示视频:https://www.bilibili.com/video/BV1Sq93YRENm/?share_source=copy_web&vd_source=0e4269581b0bc60d57a80c9a27c98905

一、项目简介

        本项目基于 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 实时显示当前角度

四、主函数代码

#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显示角度 }}

五、舵机驱动代码

#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驱动代码

#include \"stm32f10x.h\"  // Device headervoid PWM_Init(void){//开启RCC时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//初始化GPIORCC_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; //ARRTIM_TimeBaseInitStruncture.TIM_Prescaler=72-1; //PSCTIM_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; //CCRTIM_OC2Init(TIM2,&TIM_OCInitStructure);//启动定时控制器TIM_Cmd(TIM2,ENABLE);}void PWM_SetCompare2(uint16_t Compare){TIM_SetCompare2(TIM2,Compare);}

七、总结

本项目通过 PWM 控制舵机,结合 OLED 显示和按键交互,实现了一个经典的嵌入式入门项目,适用于机器人、机械臂、舵机教学等场景。