
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);



















