STM32F103RCT6 PWM控制A3982步进电机驱动程序

本项目提供基于STM32F103RCT6单片机和A3982步进电机驱动芯片的PWM控制步进电机速度的驱动程序。

硬件连接:

  • MCU: STM32F103RCT6
  • 步进电机驱动芯片: A3982
  • PWM引脚: PB0 (TIM2 CH1)
  • DIR引脚: PB10
  • ENABLE引脚: PB11
  • A相输出引脚: 1和24
  • B相输出引脚: 4和21

软件代码:

pwm_driver.h

#ifndef __PWM_DRIVER_H
#define __PWM_DRIVER_H

#include 'stm32f10x.h'

#define PWM_PERIOD 1000  // PWM周期,单位为us

void PWM_Init(void);
void PWM_SetDutyCycle(uint16_t dutyCycle);

#endif

pwm_driver.c

#include 'pwm_driver.h'

void PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM2, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / (1000000 * PWM_PERIOD) - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);

    TIM_Cmd(TIM2, ENABLE);
    TIM_CtrlPWMOutputs(TIM2, ENABLE);

    GPIO_WriteBit(GPIOB, GPIO_Pin_0 | GPIO_Pin_10 | GPIO_Pin_11, Bit_SET);
}

void PWM_SetDutyCycle(uint16_t dutyCycle)
{
    TIM_SetCompare1(TIM2, dutyCycle);
}

stepper_driver.h

#ifndef __STEPPER_DRIVER_H
#define __STEPPER_DRIVER_H

#include 'stm32f10x.h'

#define DIR_PIN GPIO_Pin_10
#define ENABLE_PIN GPIO_Pin_11
#define A_PHASE_PIN_1 GPIO_Pin_1
#define A_PHASE_PIN_24 GPIO_Pin_4
#define B_PHASE_PIN_4 GPIO_Pin_4
#define B_PHASE_PIN_21 GPIO_Pin_1

void Stepper_Init(void);
void Stepper_SetDirection(uint8_t direction);
void Stepper_Enable(void);
void Stepper_Disable(void);
void Stepper_Step(void);

#endif

stepper_driver.c

#include 'stepper_driver.h'

void Stepper_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DIR_PIN | ENABLE_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = A_PHASE_PIN_1 | A_PHASE_PIN_24 | B_PHASE_PIN_4 | B_PHASE_PIN_21;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM2, ENABLE);
}

void Stepper_SetDirection(uint8_t direction)
{
    if (direction == 0) {
        GPIO_WriteBit(GPIOB, DIR_PIN, Bit_RESET);
    } else {
        GPIO_WriteBit(GPIOB, DIR_PIN, Bit_SET);
    }
}

void Stepper_Enable(void)
{
    GPIO_WriteBit(GPIOB, ENABLE_PIN, Bit_RESET);
}

void Stepper_Disable(void)
{
    GPIO_WriteBit(GPIOB, ENABLE_PIN, Bit_SET);
}

void Stepper_Step(void)
{
    static uint8_t step = 0;

    switch (step) {
        case 0:
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_1, Bit_SET);
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_24, Bit_RESET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_4, Bit_RESET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_21, Bit_SET);
            break;
        case 1:
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_1, Bit_RESET);
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_24, Bit_SET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_4, Bit_RESET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_21, Bit_SET);
            break;
        case 2:
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_1, Bit_RESET);
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_24, Bit_SET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_4, Bit_SET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_21, Bit_RESET);
            break;
        case 3:
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_1, Bit_SET);
            GPIO_WriteBit(GPIOB, A_PHASE_PIN_24, Bit_RESET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_4, Bit_SET);
            GPIO_WriteBit(GPIOB, B_PHASE_PIN_21, Bit_RESET);
            break;
    }

    step = (step + 1) % 4;
}

main.c

#include 'pwm_driver.h'
#include 'stepper_driver.h'

// 延时函数,需要根据实际情况自行实现
void delay_us(uint32_t us);

int main(void)
{
    PWM_Init();
    Stepper_Init();

    Stepper_SetDirection(0); // 设置步进电机方向
    Stepper_Enable(); // 使能步进电机

    while (1) {
        // PWM占空比递增
        for (int i = 0; i < 1000; i++) {
            PWM_SetDutyCycle(i);
            Stepper_Step();
            delay_us(1000);
        }

        // PWM占空比递减
        for (int i = 1000; i > 0; i--) {
            PWM_SetDutyCycle(i);
            Stepper_Step();
            delay_us(1000);
        }
    }
}

注意:

  • 以上代码仅供参考,实际应用中可能需要根据硬件环境进行修改。
  • delay_us 函数需要根据实际情况自行实现。
  • 请确保在使用前正确连接硬件并配置工程。
STM32F103RCT6 PWM控制A3982步进电机驱动程序

原文地址: https://www.cveoy.top/t/topic/jr6L 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录