Featured image of post 电机驱动1

电机驱动1

电机

电源就是插上后,直接供电,启动,所以没有写相关的代码

分析原理图

image-20260416234928590

image-20260416235019250

1
2
3
4
PWM1   =>		PA0
PWM2   =>		PA1
PWM3   =>		PA2
PWM4   =>		PA3

STM32F103C8T6的引脚对应

image-20260416235242561

PWM是使用TIM2定时器的四个通道

HAL库配置TIM2

image-20260417001047394

image-20260417001150000

设置定时器

  • 预分频系数

    主控芯片 72Mhz 计数一次的周期为 1/72M => 1/72us 计数时间太短

    • 定时器计数的频率等于 72/预分频
    • 选择预分频系数为4
    • 由于预分频系数从0开始,0也就是1分频,所以4分频写4-1

image-20260417002400478

  • 重装载系数
    • 重装载的值代表定时器计数多少次为1轮
    • 选择了一个好算的1000次为1轮
    • 周期 = 1000 * 1/18M = 55.55us 55us一个周期

同理由于重装载值也是从0开始计数,所以写1000 -1

  • 占空比
    • 通道比较值 / 重装载值
    • 通道比较值不用减一,自己设定 这里设置为200
    • 200/1000 也就是20%,一个周期的20%的时间是有效电平

硬件

使用的是8520的空心杯电机

85直径 8.5 mm

20长度 20 mm

程序

程序部分,就是启动定时器,设置占空比

都有对应的函数

Int_motor.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef INT_MOTOR_H
#define INT_MOTOR_H

#include "tim.h"
#include "Com_debug.h"

typedef struct
{
    TIM_HandleTypeDef *tim; // 定时器句柄
    uint16_t channel;       // 定时器通道
    uint16_t speed;         // 电机速度值    
    
} Motor_Struct_T;

/**
* @brief  传入的参数其实是电机速度值 最大为1000 默认200
* @param motor 电机结构体指针
*/
void Int_motor_set_speed(Motor_Struct_T *motor);

/**
* @brief  启动电机
* @param motor 电机结构体指针
*/
void Int_motor_start(Motor_Struct_T *motor);

#endif // INT_MOTOR_H

Int_motor.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "Int_motor.h"

/**
* @brief  传入的参数其实是电机速度值 最大为1000 默认200
* @param speed 电机速度值
*/
void Int_motor_set_speed(Motor_Struct_T *motor){
    if(motor->speed > 1000) {
       debug_printf("motor speed out of range, setting to 1000");
       return ;
    }
  
    // 设置定时器的占空比
    __HAL_TIM_SET_COMPARE(motor->tim, motor->channel, motor->speed);

}

/**
* @brief  启动电机
* @param motor 电机结构体指针
*/
void Int_motor_start(Motor_Struct_T *motor){
    // 启动定时器
    HAL_TIM_PWM_Start(motor->tim, motor->channel);
}

motor_task

任务就是简单调用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//电机结构体
Motor_Struct_T left_top_motor = {
    .tim = &htim2,              // 定时器
    .channel = TIM_CHANNEL_1,   // 定时器通道1
    .speed = 200                // 默认速度值
};
Motor_Struct_T right_top_motor = {
    .tim = &htim2,              // 定时器2
    .channel = TIM_CHANNEL_2,   // 定时器通道2
    .speed = 200                // 默认速度值
};
Motor_Struct_T left_bottom_motor = {
    .tim = &htim2,              // 定时器2
    .channel = TIM_CHANNEL_3,   // 定时器通道3
    .speed = 200                // 默认速度值
};
Motor_Struct_T right_bottom_motor = {
    .tim = &htim2,              // 定时器2
    .channel = TIM_CHANNEL_4,   // 定时器通道4
    .speed = 200                // 默认速度值
};


void flight_task( void * arg ){
	//获取基准时间
    TickType_t xLastWakeTime = xTaskGetTickCount();
	while(1){
        //1.设置电机转速
        left_top_motor.speed = 400;
        //2.启动电机
        Int_motor_start(&left_top_motor);
        Int_motor_start(&right_top_motor);
        Int_motor_start(&left_bottom_motor);
        Int_motor_start(&right_bottom_motor);

        vTaskDelayUntil(&xLastWakeTime,FLIGHT_TASK_PERIOD);
    }
}

到后面设置摇杆后,通过摇杆的上下推,来设置油门

从0-1000

最后更新于 2026-04-18 01:45