这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【原创】STM32小车舵机抓取功能实现--from毅

共1条 1/1 1 跳转至

【原创】STM32小车舵机抓取功能实现--from毅

工程师
2026-05-19 13:08:08     打赏

使用 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);    } }image.png

注意:舵机单独供电更稳,避免 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);    } }

image.png

五、小车常用抓取函数你可以直接加到 servo.c 里,控制爪子开合:

// 爪子张开 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);    } }

六、常见问题
  1. 舵机抖动

    • 原因:供电不足、共地不好

    • 解决:舵机 5V 单独供电,GND 和 STM32 连在一起

  2. 舵机不动

    • 检查:PA0 是否接对、是否 5V 供电、代码是否开启定时器

  3. 角度反了

    • 把 0° 和 180° 互换即可

  4. 机械爪行程不够

    • 调整角度:张开用 30°,闭合用 150°(根据你的机械爪调整)





共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]