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