【含代码】STM32F103PWM控制多个SG90舵机教程(90°和180°) 控制SG92R MG90S MG995 MG996R舵机亦可 可控制二维云台PWM控制舵机 sg90舵机驱动

本文完整的工程代码获取方式放在文末,需要的自行获取。

如需其它模块学习教程,可在评论区留言或私信作者,免费更新!


前言

通过本文可以学到STM32F103C8T6控制多个舵机,相同的代码适用多种型号的舵机,如SG90、SG92R、MG90S、MG995、MG996R等舵机。

本文示例代码为控制四个SG90舵机(180°)的转动,可以控制舵机转动到任意特定的角度。

一、使用到的工具

1.Jiayou-01主控板(包含四路舵机控制口,使用方便);

2.SG90舵机四个;

3.12V锂电池(供电);

二、舵机介绍

1.什么是舵机?

        舵机是一种位置(角度)伺服的驱动器,内部安装了一个电位器(或其它角度传感器)检测输出轴转动角度,控制板根据电位器的信息能比较精确的控制和保持输出轴的角度。这样的直流电机控制方式叫闭环控制,所以舵机更准确的说是伺服马达,英文servo。
舵机的转动由PWM脉冲控制,每经过一个脉冲舵机转过一个特定的角度。同时舵机是一个闭环控制系统,因为,伺服电机本身具备发出脉冲的功能,所以伺服电机每旋转一个角度,都会发出对应数量的脉冲,这样,和伺服电机接受的脉冲形成了呼应,或者叫闭环,如此一来,系统就会知道发了多少脉冲给伺服电机,同时又收了多少脉冲回来,这样,就能够很精确的控制电机的转动,从而实现精确的定位。广泛应用于航模、遥控玩具、机器人、云台等等需要控制角度的场合。

2.常见的舵机

        SG90、SG92R、MG90S、MG995、MG996R等,这几款舵机区别主要就在齿轮材质和扭矩以及旋转角度的不同,SG90是基础使用的较为广泛的。MG90S相当于SG90的加强版,有金属齿可选,扭矩加大,在安装尺寸和SG90略微不同。同型号舵机的180度版本和360度版本在尺寸和外观上是一样的,只是可控旋转角度不同,如下图所示。

3.舵机接口定义

        舵机共有三条线,分别为VCC、GND、S(信号线);

        对于供电电压(本文SG90采用5V供电),可以根据自己使用的舵机型号而定,通过电商平台购买的在商品参数处可以查到对应舵机的供电电压。如下图所示:

4.舵机的控制方式

        我们通常说的和较常用的舵机一般指的是180度的舵机,也就是在0-180°内可控旋转的舵机,给这样的舵机一个特定的PWM信号,舵机会在0-180°内转到一个特定的角度。而给360度舵机一个特定的PWM信号,舵机会以一个特定的速度转动,转动方向也可以控制,但是不能控制旋转到某个特定的角度,类似于无级变速的减速电机,但与减速电机不同的是,360舵机是闭环控制,速度控制稳定。
        舵机的控制一般需要一个20ms(50Hz)左右的时基脉冲,该脉冲的高电平部分为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。

        以180度角度为例,那么对应的控制关系是这样的:

三、项目硬件接线原理

        系统选用了Jiayou-01主控板,主控板包含四个舵机驱动接口,本项目采用Jiayou-01主控板驱动舵机。(杜邦线接线电路稳定性极低,不建议用杜邦线连接,选购链接如下,需要的读者可以根据自己的情况选择性购买,购买主控板免费提供技术支持)

主控板链接:->Jiayou-01主控板链接<-点击可直达

1.供电电源(注:供电不足舵机工作可能会不正常

        因为舵机功率比较大,为了确保供电的稳定性,本项目采用12V锂电池供电,电池接到主控板通过降压模块降压至5V给舵机供电。降压电路如下图所示。

2.舵机接线图

①四个舵机分别接到STM32F103C8T6单片机PA0、PA1、PA2、PA3引脚上。

PA0、PA1、PA2、PA3是STM32F1定时器2 PWM输出的四个通道。

②实物电路连接图

四、代码实现

1.初始化TIM2产生频率为50Hz的PWM方波。

/*
*** TIM2  配置定时器2PWM控制SG90舵机 ***

*** PWM频率:50Hz ***

*** 接口:PA0->舵机1   PA1->舵机2   PA2->舵机3   PA3->舵机4 ***

*** 作者:陈加油嗯 ***

***关注微信公众号学习更多单片机知识:微信搜索“陈加油嗯” ***

*/
void myServo_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能定时器2时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIO外设;————假如要AFIO复            用功能模块时钟则要加上(  | RCC_APB2Periph_AFIO)
	
	//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5    
 
   //初始化输出TIM2四个通道PWM脉冲波形的引脚(CH1->PA0 CH2->PA1 CH3->PA2 CH4->PA3)
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM2
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM2 Channe PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC1
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC3
	TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC4
  
	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIM 2
}

2.控制TIM2通道的占空比,控制舵机。

舵机回零代码和转到最大角度代码如下:

/*
*** TIM2 四个通道输出PWM 控制SG90舵机 舵机回零 ***

*** PWM频率:50Hz   高电平0.5ms ***

*** 接口:PA0->舵机1   PA1->舵机2   PA2->舵机3   PA3->舵机4 ***

*** 作者:陈加油嗯 ***

***关注微信公众号学习更多单片机知识:微信搜索“陈加油嗯” ***

*/
void Servo1234_0du(void)
{
	TIM_SetCompare1(TIM2,50);  //舵机1 0.5ms
	TIM_SetCompare2(TIM2,50);  //舵机2 0.5ms
	TIM_SetCompare3(TIM2,50);  //舵机3 0.5ms
	TIM_SetCompare4(TIM2,50);  //舵机4 0.5ms
	
	Delay_ms(500);
}

/*
*** TIM2 四个通道输出PWM 控制SG90舵机 舵机转到最大角度 ***

*** PWM频率:50Hz   高电平2.5ms ***

*** 接口:PA0->舵机1   PA1->舵机2   PA2->舵机3   PA3->舵机4 ***

*** 作者:陈加油嗯 ***

***关注微信公众号学习更多单片机知识:微信搜索“陈加油嗯” ***

*/
void Servo1234_180du(void)
{
	TIM_SetCompare1(TIM2,250);  //舵机1 2.5ms
	TIM_SetCompare2(TIM2,250);  //舵机2 2.5ms
	TIM_SetCompare3(TIM2,250);  //舵机3 2.75ms
	TIM_SetCompare4(TIM2,250);  //舵机4 2.75ms
	
	Delay_ms(500);
}

3.主函数代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "myServo.h"

/*
*** main 主函数代码 ***

*** 定时器2初始化(控制舵机) OLED初始化 ***

*** 作者:陈加油嗯 ***

***关注微信公众号学习更多单片机知识:微信搜索“陈加油嗯” ***

*/

int main(void)
{
	Delay_ms(100);  //延时100ms,等电压稳定下来再初始化代码(可以防止OLED上电不亮等问题)
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	myServo_Init(1999,719);        //定时器2,产生PWM波,周期20ms,50HZ,控制舵机
	OLED_Init();          //OLED初始化
	OLED_ColorTurn(0);    //0正常显示,1 反色显示
	OLED_DisplayTurn(0);  //0正常显示 1 屏幕翻转显示
	OLED_Clear();         //清屏
	OLED_Refresh();       //更新显存到OLED(即刷新刚写入的数据,刷新屏幕)
	
	//OLED静态显示字符
	OLED_ShowString(0,0,"chenjiayou!",16,1);
	OLED_Refresh();             //更新显存到OLED(即刷新刚写入的数据,刷新屏幕)
	
	 
	while(1)
	{
		Servo1234_0du();   	//舵机转到0°
		Servo1234_180du(); 	//舵机转到180°
	}
}

五、实验现象

根据原理图接好线路,把工程代码下载到STM32F103单片机中,打开电源开关可以看到舵机在0度至180度之间循环转动。(可以根据自己的需求修改代码,可以控制舵机转动到任意你需要的角度

六、资料获取(代码、主控板链接)

获取方法:

关注微信公众号<陈加油嗯>,回复"STM32控制SG90舵机"即可获取源代码。

### STM32C8T6 微控制驱动四个舵机的方法 #### PWM信号配置 为了使STM32C8T6能够有效地控制多个舵机,在硬件上需利用定时器产生的PWM波形来实现。每个舵机通过接收特定占空比的PWM脉冲来进行角度定位[^3]。 对于STM32F103C8T6而言,其内部集成了高级定时器(TIM1),通用定时器(TIM2-TIM5)等可以用来生成PWM输出。当涉及到多路PWM输出时,通常会选择TIM1至TIM4中的任意一个作为主要工作单元,并对其进行通道重映射以便于连接外部设备如舵机接口。 #### GPIO初始化设置 在软件层面,首先要完成的是GPIO端口的初始化操作,这一步骤决定了哪些引脚会被分配给PWM功能。例如PA0~PA3分别被设定为CH1~CH4用于输出PWM信号给对应的舵机: ```c // 初始化GPIOA, 设置PA0-PA3为复用推挽输出模式 void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); } ``` #### 定时器与PWM参数调整 接下来是对选定的定时器进行必要的参数调节,包括周期(period)以及预分频系数(prescaler)[^5]。这些数值直接影响着最终输出PWM频率及分辨率,从而影响到舵机响应速度平稳度: ```c // TIM2初始化函数,产生PWM波形 void TIM_PWMInit(void){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 开启外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 ,ENABLE); // 配置自动重装载寄存器ARR(Period), PSC(Prescaler) TIM_TimeBaseStructure.TIM_Period = 999; /* 周期 */ TIM_TimeBaseStructure.TIM_Prescaler = 71; /* 分频因子 */ TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // CH1-CH4 输出比较模式配置 TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMODE_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC4Init(TIM2, &TIM_OCInitStructure); // 启动计数器并开启中断 TIM_Cmd(TIM2, ENABLE); TIM_CtrlPWMOutputs(TIM2, ENABLE); } // 更新指定通道PWM占空比 void SetServoPosition(uint16_t channel,uint16_t dutyCycle){ switch(channel){ case 1: TIM_SetCompare1(TIM2,dutyCycle); break; case 2: TIM_SetCompare2(TIM2,dutyCycle); break; case 3: TIM_SetCompare3(TIM2,dutyCycle); break; case 4: TIM_SetCompare4(TIM2,dutyCycle); break; } } ``` 上述代码片段展示了如何针对不同需求灵活改变各舵机的角度位置。其中`SetServoPosition()`允许动态修改某个具体舵机的工作状态,即通过更改相应通道下的CCRx值达到调整PWM宽度的目的。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值