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