STM32学习17--定时器之舵机

舵机是一种根据输入PWM信号占空比来控制输出角度的装置。

一、舵机基本参数

舵机(Servo Motor)是一种根据输入PWM(脉冲宽度调制)信号占空比来控制输出轴角度的精密执行装置。它内部包含直流电机、减速齿轮组、位置反馈电位器和控制电路,通过闭环控制实现精确的角度定位。

1、以舵机SG90为例:

SG90是一款微型舵机,广泛应用于机器人、航模、智能小车等场景。其核心电气参数如下:

  • 工作电压:4.8V ~ 6.0V(典型5V,3.3V无驱动力)
  • 工作电流:100mA ~ 250mA(空载~堵转)
  • 扭矩:1.2kg·cm ~ 1.8kg·cm(电压不同)
  • 响应速度:0.1s/60°(4.8V)

PWM控制信号规范:

  • PWM周期固定:20ms(频率=50Hz,不能改变);
  • 高电平脉宽范围:0.5ms ~ 2.5ms(对应输出角度0° ~ 180°);
  • 典型对应关系
    • 0.5ms → 0°(最左位置)
    • 1.5ms → 90°(中间位置)
    • 2.5ms → 180°(最右位置)

2、参数计算(基于STM32F103C8T6,系统时钟72MHz)

目标:生成周期20ms、分辨率满足0.5ms~2.5ms可调的PWM信号。

步骤分解:

  1. 确定计数频率:系统时钟72MHz,预分频器PSC设为7200-1,则计数器时钟频率 = 72MHz / 7200 = 10kHz(即每个计数周期0.1ms)。
  2. 确定自动重装载值ARR:PWM周期 = (ARR+1) × 计数周期。周期20ms对应200个计数周期(20ms ÷ 0.1ms = 200),故ARR = 200-1 = 199。
  3. 计算CCR值(捕获/比较寄存器) :CCR值决定高电平脉宽,与角度呈线性关系。
    • 0°(0.5ms):CCR = 0.5ms ÷ 0.1ms = 5
    • 90°(1.5ms):CCR = 1.5ms ÷ 0.1ms = 15
    • 180°(2.5ms):CCR = 2.5ms ÷ 0.1ms = 25

通用公式:CCR = (Angle / 180.0) × (25 - 5) + 5,其中Angle为0~180°。

3、接线示意图

SG90舵机通常有三根线:

  • 棕色线(Brown):GND(接地)
  • 红色线(Red):VCC(电源,+5V)
  • 橙色线(Orange):信号线(PWM输入)

连接STM32开发板时:

  • 信号线 → PA1(TIM2通道2)
  • VCC → 5V电源(注意电流需足够)
  • GND → 共地

注意:若驱动多个舵机,建议使用外部独立电源供电,避免开发板LDO过载。

1、以舵机SG90为例:

PWM周期固定:20ms(频率=50Hz);

高电平范围:0.5~2.5ms(对应0~180°);

0.5ms→0°;1.5ms→90°(中间位置);2.5ms→180°;

2、参数计算

系统时钟72MHz,周期20ms。

设:PSC+1 =7200,计数频率10kHz(0.1ms计数一次),ARR+1 =200;

CCR值,线性关系:

CCR=5→0.5ms(0°);

CCR=15→1.5ms(90°);

CCR=25→2.5ms(180°);

3、接线

二、代码部分

练习:以TIM2为例,通道1→PA1,实现0°→180→0°,循环往复。

最经典且最简单的做法:在whiel()里放2个For循环,一个负责正转(0→180°),另一个负责反转(180→0)。

1、PWM初始化

cpp 复制代码
void PWM_Init(uint16_t ARR,uint16_t PSC)
{
	TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_OCInitTypeDef OC_Config;
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	//初始化GPIO
	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_BaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
	TIM_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
	TIM_BaseInitStructure.TIM_Period =ARR;
	TIM_BaseInitStructure.TIM_Prescaler =PSC;
	TIM_TimeBaseInit(TIM2,&TIM_BaseInitStructure);
	//配置OC
	TIM_OCStructInit(&OC_Config);
	OC_Config.TIM_OCMode =TIM_OCMode_PWM1;
	OC_Config.TIM_OutputState = TIM_OutputState_Enable;
	OC_Config.TIM_OCPolarity = TIM_OCPolarity_High;
	OC_Config.TIM_Pulse = 15;
	TIM_OC2Init(TIM2,&OC_Config);
	
	TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM2,ENABLE);
	TIM_Cmd(TIM2,ENABLE);			
}

2、舵机(Servo)初始化及设置角度函数

cpp 复制代码
#include "stm32f10x.h"                 
#include "PWM.h"

void Servo_Init()
{
	PWM_Init(200,7200-1);
}
void SetMyAngle(uint16_t Angle)
{	
	uint16_t Val;
	if(Angle>180)
	{
		Angle =180;
	}		
	Val =(uint16_t)((25.0-5.0)/180.0)*Angle+5);
	TIM_SetCompare2(TIM2,Val);
}

3、舵机(Servo)头文件

cpp 复制代码
#ifndef __SERVO_H
#define __SERVO_H

void Servo_Init();
void SetMyAngle(uint16_t Angle);

#endif

4、main函数

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"

uint16_t ang;

int main()
{
	OLED_Init();
	Servo_Init();
	SetMyAngle(0);//先归零	
	Delay_ms(1000);//等待舵机物理归位
    OLED_ShowString(1,1,"Angle:");
	while(1)
	{
        //0→180
		for(ang =0;ang <=180;ang++) 
		{
			SetMyAngle(ang);
			Delay_ms(10);	//延时决定转动速度
			OLED_ShowNum(1,7,ang,3);			
		}
        Delay_ms(1000);	//到头停止1s
        //180→0
		for(ang =180;ang >0;ang--)
		{
			SetMyAngle(ang);
			Delay_ms(10);
			OLED_ShowNum(1,7,ang,3);
		}	
        Delay_ms(1000);	//到头停止1s
	}	
}

注意:

1)平滑度控制:Delay_ms(10)这个参数决定了舵机转动的丝滑程度。

如果设为Delay_ms(1),舵机会转动非常快,会因为惯性产生抖动。如果设为10ms,转动会比较丝滑。这个过程中耗时约1.8s。可多次试验几次,调整参数。

2)数据类型:angle使用了uint16_t(无符号16位整数),在反向循环中,条件写的是angle>0,而不是angle>=0,因为无符号数减到0后再减1,会发送下溢,变成65535(一直大于条件>=0),导致死循环。

本文完!

相关推荐
承渊政道2 分钟前
【Python学习】(了解使用库、标准库、第三方库以及综合案例实操)
python·学习·pycharm·标准库·第三方库·使用库·综合案例
YM52e1 小时前
鸿蒙Flutter Card组件:Material设计风格卡片
android·学习·flutter·华为·harmonyos·鸿蒙
YangYang9YangYan2 小时前
2026通信工程专业学生无项目经验学习数据分析的价值与路径
学习·数据挖掘·数据分析
世人万千丶12 小时前
鸿蒙Flutter TextStyle样式配置
学习·flutter·harmonyos·鸿蒙
吃着火锅x唱着歌12 小时前
Effective C++ 学习笔记 条款37 绝不重新定义继承而来的缺省参数值
c++·笔记·学习
小弥儿12 小时前
GitHub今日热榜 | 2026-07-19
人工智能·学习·github·知识图谱
zhangrelay14 小时前
笔记本轻量高品质延寿工具完整分系统清单
运维·笔记·学习
巴巴媛66614 小时前
STM32学习笔记【38.DHT11实验】
笔记·stm32·学习
深圳市泰凌微电子15 小时前
HK航顺 HK32F407RGT7替STM32F405RGT6 微控制器32位MCU
stm32·单片机·嵌入式硬件
caimouse15 小时前
MM 学习笔记 01:miarm.h 核心头文件分析
笔记·学习·reactos