舵机驱动详解(模拟/数字 STM32)

2025-07-02 11:46:32

目录

一、介绍

二、模块原理

1.舵机驱动原理

2.引脚描述

三、程序设计

main.c文件

servo.h文件

servo.c文件

四、实验效果

五、资料获取

项目分享

一、介绍

舵机(Servo)是在程序的控制下,在一定范围内连续改变输出轴角度并保持的电机系统。即舵机只支持在一定角度内转动,无法像普通直流电机按圈转;其主要控制物体的转动并保持(机器人关节、转向机构)。适用于位置角度经常变化的场合。可以作为理想的电机驱动器件。

以下MG90S舵机模块的参数:

型号

MG90S/MG90

使用电压

4.8V

反应速度

0.11s(4.8V)

转动角度

180度(左90,右90)

使用温度

0~55℃

工作扭矩

2.0kg

产品重量

13.6g

哔哩哔哩视频链接:

舵机驱动详解(模拟/数字 STM32)

(资料分享见文末)

二、模块原理

1.舵机驱动原理

舵机的控制一般需要一个20MS左右的时基脉冲,该脉冲的高电平部分一般为0.5MS-2.5MS范围内的角度控制脉冲部分总间隔为2MS。以180度角度为例,那么对应的控制关系是这样的

2.引脚描述

引脚名称

描述

VCC

供给电压5V

GND

地线

S 信号线

三、程序设计

使用STM32F103C8T6通过按键控制舵机旋转指定角度。

SERVO

PA2

KEY

PB1

OLED_SCL

PB11

OLED_SDA

PB10

main.c文件

#include "stm32f10x.h"

#include "led.h"

#include "usart.h"

#include "delay.h"

#include "oled.h"

#include "servo.h"

#include "key.h"

/*****************辰哥单片机设计******************

STM32

* 项目 : 舵机驱动实验

* 版本 : V1.0

* 日期 : 2024.9.27

* MCU : STM32F103C8T6

* 接口 : 参看servo.h

* BILIBILI : 辰哥单片机设计

* CSDN : 辰哥单片机设计

* 作者 : 辰哥

**********************BEGIN***********************/

int key = 0;

float Angle; //定义角度变量

int main(void)

{

SystemInit();//配置系统时钟为72M

delay_init(72);

LED_Init();

LED_On();

Servo_Init();

USART1_Config();//串口初始化

Key_Init();

OLED_Init();

printf("Start \n");

delay_ms(1000);

OLED_Clear();

//显示“舵机角度:”

OLED_ShowChinese(0,0,0,16,1);

OLED_ShowChinese(16,0,1,16,1);

OLED_ShowChinese(32,0,2,16,1);

OLED_ShowChinese(48,0,3,16,1);

OLED_ShowChar(64,0,':',16,1);

while (1)

{

key = Key_GetData();

if(key)

{

Angle += 30; //角度变量自增30

if (Angle > 180) //角度变量超过180后

{

Angle = 0; //角度变量归零

}

}

Servo_SetAngle(Angle); //设置舵机的角度为角度变量

OLED_ShowNum(50, 24, Angle, 3,16,1); //OLED显示角度变量

}

}

servo.h文件

#ifndef __SERVO_H

#define __SERVO_H

#include "stm32f10x.h"

#include "delay.h"

#include "sys.h"

/*****************辰哥单片机设计******************

STM32

* 文件 : 舵机驱动驱动h文件

* 版本 : V1.0

* 日期 : 2024.9.27

* MCU : STM32F103C8T6

* 接口 : 见代码

* BILIBILI : 辰哥单片机设计

* CSDN : 辰哥单片机设计

* 作者 : 辰哥

**********************BEGIN***********************/

/***************根据自己需求更改****************/

// SERVO舵机 GPIO宏定义

#define SERVO_CLK RCC_APB2Periph_GPIOA

#define SERVO_GPIO_PIN GPIO_Pin_2

#define SERVO_GPIO_PORT GPIOA

/*********************END**********************/

void Servo_Init(void);

void PWM_SetCompare3(uint16_t Compare);

void Servo_SetAngle(float Angle);

#endif

servo.c文件

#include "servo.h"

/*****************辰哥单片机设计******************

STM32

* 文件 : 舵机驱动模块c文件

* 版本 : V1.0

* 日期 : 2024.9.27

* MCU : STM32F103C8T6

* 接口 : 见代码

* BILIBILI : 辰哥单片机设计

* CSDN : 辰哥单片机设计

* 作者 : 辰哥

**********************BEGIN***********************/

void Servo_Init(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

RCC_APB2PeriphClockCmd(SERVO_CLK, ENABLE); //开启GPIOA的时钟

/*GPIO初始化*/

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = SERVO_GPIO_PIN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(SERVO_GPIO_PORT, &GPIO_InitStructure); //将PA1和PA2引脚初始化为推挽输出

TIM_InternalClockConfig(TIM2);

//配置时基单元

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频

TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式

TIM_TimeBaseInitStructure.TIM_Period = 20000-1; //自动重装ARR 分辨率

TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频PSC

TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

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_OC3Init(TIM2,&TIM_OCInitStructure);

TIM_Cmd(TIM2,ENABLE);

}

void PWM_SetCompare3(uint16_t Compare)

{

TIM_SetCompare3(TIM2, Compare); //设置CCR2的值

}

void Servo_SetAngle(float Angle)

{

PWM_SetCompare3(Angle / 180 * 2000 + 500); //设置占空比

//将角度线性变换,对应到舵机要求的占空比范围上

}

四、实验效果

五、资料获取

项目分享