使用 SG90 舵机,最适合小车机械爪,采用 定时器 PWM 输出 控制,兼容 STM32F103,小车最常用芯片。
一、核心原理
SG90 舵机:只需要输入PWM 波形就能控制角度
周期:20ms(50Hz)
高电平:0.5ms ~ 2.5ms
对应角度:0° ~ 180°
小车抓取逻辑:
0°:爪子张开90°:爪子半开
180°:爪子闭合抓取
二、硬件连线
#include "stm32f10x.h"
#include "servo.h"
#include "delay.h" // 你自己的延时函数
int main(void)
{
SERVO_Init(); // 舵机初始化
while(1)
{
// 抓取流程
SERVO_SetAngle(0); // 爪子张开
Delay_ms(1000);
SERVO_SetAngle(180); // 爪子闭合抓取
Delay_ms(1000);
}
}
注意:舵机单独供电更稳,避免 STM32 供电不足抖动。
三、完整代码(标准库 / 直接复制)1. 舵机初始化文件(servo.c)#include "servo.h" #include "stm32f10x.h" // 舵机初始化:TIM2_CH1 PA0 50Hz PWM void SERVO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 开时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 四、角度与 PWM 对应表
// PA0 复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器配置:20ms周期(50Hz) // 计数频率=72M/(71+1)=1MHz,每1us加1 // 自动重装载=19999 → 1us*20000=20ms TIM_TimeBaseStructure.TIM_Period = 19999; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // PWM模式1 通道1配置 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); TIM_Cmd(TIM2, ENABLE); } // 设置舵机角度 0~180度 void SERVO_SetAngle(u8 angle) { u16 pwm_val; if(angle > 180) angle = 180; if(angle < 0) angle = 0; // 0.5ms(0°) → 2.5ms(180°) pwm_val = 500 + (angle * 11.11); TIM_SetCompare1(TIM2, pwm_val); }
2. 头文件(servo.h)#ifndef __SERVO_H #define __SERVO_H #include "stm32f10x.h" void SERVO_Init(void); void SERVO_SetAngle(u8 angle); #endif
3. main 函数调用示例
#include "stm32f10x.h" #include "servo.h" #include "delay.h" // 你自己的延时函数 int main(void) { SERVO_Init(); // 舵机初始化 while(1) { // 抓取流程 SERVO_SetAngle(0); // 爪子张开 Delay_ms(1000); SERVO_SetAngle(180); // 爪子闭合抓取 Delay_ms(1000); } }

// 爪子张开 void SERVO_Open(void) { SERVO_SetAngle(0); } // 爪子闭合抓取 void SERVO_Close(void) { SERVO_SetAngle(180); } // 缓慢抓取(防抖动、防夹飞物品) void SERVO_GrabSlowly(void) { u8 i; for(i=0; i<=180; i+=5) { SERVO_SetAngle(i); Delay_ms(30); } }
六、常见问题
舵机抖动
原因:供电不足、共地不好
解决:舵机 5V 单独供电,GND 和 STM32 连在一起
舵机不动
检查:PA0 是否接对、是否 5V 供电、代码是否开启定时器
角度反了
把 0° 和 180° 互换即可
机械爪行程不够
调整角度:张开用 30°,闭合用 150°(根据你的机械爪调整)
我要赚赏金
