STM32标准库_09 | PWM驱动舵机

本篇文章主要介绍如何使用定时器产生PWM并驱动舵机。

1.开发环境

软件环境

使用MDK5.25版本,芯片包为STM32F4系列。

硬件环境

开发板:STM32F407VGT6开发板,是一款大容量芯片,最高能跑168MHz。

烧录器:STlink或者Jlink。

舵机:MG90S舵机

红色线为VCC,棕色线为GND,黄色线为信号线(接单片机PWM输出)

2.工程搭建

直接复制之前的工程做修改即可。

舵机控制原理

舵机的控制通常采用信号频率为50HZ(即周期为20ms)的脉冲宽度调制(PWM),当高电平的脉宽在0.5ms-2.5ms之间时舵机就可以对应旋转到不同的角度,MG90S舵机是180°的舵机,它的脉冲宽度与角度的关系,如下图所示。

0.5ms对应0°,

1ms对应45°,

1.5ms对应90°,

2ms对应135°,

2.5ms对应180°。

程序编写

PWM部分

使用通用定时器或者高级定时器,本实验选择PD15引脚,定时器4的CH4通道。
假设需要的分辨率为1.8°,那么定时器重装载值为1000-1=999。
那么预分频根据定时器时钟频率(84MHz)与舵机需要信号频率(50Hz)来定,即50=84M/(预分频系数+1)/(重装载值+1)为1679。

TIM4_Int_Init(999,1679); //定时器初始化

GPIO配置

/*
*********************************************************************************************************
*	函 数 名: PWM_gpio配置
*	功能说明: PWM输出引脚设置
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/ 
void Servo_Gpio_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 	//使能PORTD时钟	
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;           //GPIOD15
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;   //速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;         //上拉
	GPIO_Init(GPIOD,&GPIO_InitStructure);                //初始化PD15
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_TIM4); //GPIOD15复用为定时器4
	
}

定时器配置

/*
*********************************************************************************************************
*	函 数 名: TIM4_Int_Init
*	功能说明: 定时器初始化函数
*	形    参: 1.自动重装值  2.时钟预分频数
*	返 回 值: 无
*********************************************************************************************************
*/ 
void TIM4_Int_Init(u16 reload ,u16 prescaler)
{
	Servo_Gpio_Config();
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  ///使能TIM4时钟
	
	TIM_TimeBaseInitStructure.TIM_Period = reload; 	     //自动重装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=prescaler;   //定时器分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM4
	
	//初始化TIM4 Channel4 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_OCInitStructure.TIM_Pulse = 0;				//比较初始值
	TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC4
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR4上的预装载寄存器
 
	TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE使能 	
	TIM_Cmd(TIM4,ENABLE); 	//使能定时器4
	
}

舵机控制

//设置舵机角度
void Set_Servo_Angle(uint8_t angle)
{
	float T;
	uint32_t count;
	if(angle > 180)
	{
		return;
	}
	T = 0.5 + (angle*2/180);
	count = 999 * T / 20;
	TIM_SetCompare4(TIM4,count);
}

3.效果测试

4.总结

舵机是靠PWM输出指定占空比的波形而控制旋转的角度的,他的应用场景非常广泛,多用在机器人与机械臂的关节结构中,单个舵机可模拟按键按下,多个舵机可用于机器人抓取结构,四足机器人等。

代码已全部上传到gitee

posted @ 2022-08-07 18:07  半截心跳  阅读(1391)  评论(0编辑  收藏  举报