cubemx hal stm32 舵机 可减速 任意位置停止 驱动代码

本文介绍了如何在STM32F407VE微控制器上使用CubeMX配置并实现舵机控制,包括设置定时器以50Hz频率工作,控制舵机角度范围,以及提供舵机初始化、值设置、获取和停止功能的函数定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

舵机样图

CubeMX配置

对于 STM32 F407VE
定时器配置

这里的84是来自APB1那路2倍频得到:
定时器频率

代码部分

两个舵机都是180度的

servo.c

#include "servo.h"
#include "tim.h"
#include "stdio.h"

__IO uint32_t g_SteerUWT[2] = {0};
uint16_t g_SteerDeg[2] = {0};
uint8_t g_SteerSele[2] = {0};

uint16_t g_servoMidAngle[2] = {SERVO1_MID, SERVO2_MID};


/*对于 舵机 设置角度值*/


//# 设置频率为50hz也就是20ms一个周期,
//# 控制舵机范围是在0.5ms到2.5ms之间,也就是2.50%到12.50%之间
//# 最小精度是0.01ms,也就是0.05%
//# 对于20000:
//#			 0.05% ==   10
//# 		 2.50% ==  500
//#			12.50% == 2500
void servo_Init(void)
{
	HAL_TIM_Base_Start_IT(&SERVO1_TIM);	//开启定时器
	HAL_TIM_Base_Start_IT(&SERVO1_TIM);	//开启定时器

	HAL_TIM_PWM_Start(&SERVO1_TIM, SERVO1_CHANNEL);
	HAL_TIM_PWM_Start(&SERVO1_TIM, SERVO2_CHANNEL);

	SERVO_1 = g_servoMidAngle[0];
	SERVO_2 = g_servoMidAngle[1];
}

/*
seleSteer:选择不同舵机
val:500~2500对应0~180度
*/
void servo_value_set(uint8_t seleSteer, uint16_t val)
{
	g_SteerDeg[seleSteer] = val;	// val*10+500;
	g_SteerSele[seleSteer] = 1;
}

uint16_t servo_get_value(uint8_t seleSteer)
{
	uint32_t getVal;
	switch(seleSteer)
	{
		case SERVO1:
			getVal = SERVO_1;
			break;
		case SERVO2:
			getVal = SERVO_2;
			break;
		default:
			break;
	}
	printf("servo : %d\n", getVal);

	return (uint16_t)getVal;
}

void serco_clear_move(uint8_t seleSteer)
{
	g_SteerSele[seleSteer] = 0;
}

// 舵机缓慢移动循环
void servo_scan(void)
{
	uint8_t i=0;
	while(i < SERV0_MAX)
	{
		if(g_SteerSele[i] == 1)
		{
			if(g_SteerUWT[i] < uwTick - SERVO_RETARD_VAL)
			{
				g_SteerUWT[i] = uwTick;
			}
			else
			{
				goto scan1;
			}
			switch(i)
			{
				case SERVO1:
					if(SERVO_1<=g_SteerDeg[i])
					{
						SERVO_1 += 10;
						if(SERVO_1>g_SteerDeg[i])
						{
							g_SteerSele[i] = 0;
						}
					}
					else if(SERVO_1>g_SteerDeg[i])
					{
						SERVO_1 -= 10;
						if(SERVO_1<=g_SteerDeg[i])
						{
							g_SteerSele[i] = 0;
						}
					}
					break;
				case SERVO2:
					if(SERVO_2<=g_SteerDeg[i])
					{
						SERVO_2 += 10;
						if(SERVO_2>g_SteerDeg[i])
						{
							g_SteerSele[i] = 0;
						}
					}
					else if(SERVO_2>g_SteerDeg[i])
					{
						SERVO_2 -= 10;
						if(SERVO_2<=g_SteerDeg[i])
						{
							g_SteerSele[i] = 0;
						}
					}
					break;
				default:
					break;
			}
		}
scan1:
		i++;
	}
}



servo.h

#ifndef __SERVO_H_
#define __SERVO_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include "main.h"


#define SERVO1_TIM        htim2
#define SERVO1_CHANNEL    TIM_CHANNEL_1

#define SERVO2_TIM        htim2
#define SERVO2_CHANNEL    TIM_CHANNEL_2

#define SERVO_1		SERVO1_TIM.Instance->CCR1
#define SERVO_2		SERVO2_TIM.Instance->CCR2

// 舵机循环减速值,减速值越大速度越慢
#define SERVO_RETARD_VAL 2

// 左加右减
// 上加下减
typedef enum
{
	SERVO1_MID = 1500,	// 
	SERVO2_MID = 1500,	// 
}SERVO_MID_ANGLE;

typedef enum
{
	SERVO1,			// 底部舵机,决定x位置
	SERVO2,			// 顶部舵机,决定y位置
	SERV0_MAX    
}SERVO_NUM;

extern uint16_t g_servoMidAngle[2];


void servo_Init(void);
void servo_value_set(uint8_t seleSteer, uint16_t val);
uint16_t servo_get_value(uint8_t seleSteer);
void serco_clear_move(uint8_t seleSteer);
void servo_scan(void);

/*	//使用方法
	
初始化:
	servo_Init();

调用:
	// 选择舵机1,转动舵机范围为 500 -- 2500
	servo_value_set(seleSteer, val);

	// 获取舵机当前的占空比
	servo_get_value(seleSteer);
*/

#ifdef __cplusplus
}	/*extern "C"*/
#endif

#endif //__SERVO_H_


代码使用

初始化:

	// 舵机 初始化
	servo_Init();

循环:

	// 舵机循环
	servo_scan();

设置舵机占空比:

	// 选择舵机,转动舵机范围为 500 -- 2500
	servo_value_set(seleSteer, val);

获取舵机占空比:

	// 获取舵机当前的占空比
	servo_get_value(seleSteer);

使舵机停止在当前移动的位置:

serco_clear_move(seleSteer);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入一下?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值