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 -- 2500servo_value_set(seleSteer, val);// 获取舵机当前的占空比servo_get_value(seleSteer);
*/#ifdef __cplusplus
} /*extern "C"*/
#endif#endif //__SERVO_H_
代码使用
初始化:
// 舵机 初始化servo_Init();
循环:
// 舵机循环servo_scan();
设置舵机占空比:
// 选择舵机,转动舵机范围为 500 -- 2500servo_value_set(seleSteer, val);
获取舵机占空比:
// 获取舵机当前的占空比servo_get_value(seleSteer);
使舵机停止在当前移动的位置:
serco_clear_move(seleSteer);