Search code examples
directorystm32pwm

STM32 communication with A4899 stepper motor driver


I want to write a stepper motor driver with a STM32L152RE.
I would like to control the position of the stepper motor with a potentiometer.

As I am new, I do not know how to communicate with (DIR, STEP).
Can someone give me a light or show me a way?
I'm using an A4988 - DMOS Microstepping Driver with Translator And Overcurrent Protection

I tried to use STM32 tim, but I could not.


Solution

  • Actually I have wrote whole driver for a4988, it is irq based. But I can't uncover it. I can describe a path how to start. Anyway you should have some kind of hardware, because A4988 needs extra components for current control (resistors), and some capacitors.. You could try POLOLU HW.

    If you have some kind of custom board, there may be some flaws.. So recheck pins. Especially ROSC pin, SENSE1, SENSE2 pins as those may cause that motor wont work even if other pins are ok.

    ROSC pin is for low power mode, so here you should calculate, if you just ignore it, be sure to connect at least to 10k resistor. Don't let it float. SENSE1, SENSE2 pins can be connected to 0.25omh resistors. You should check it.

    Also from power pins very decisive VREG pin. It should get from 0 to 2000mV if I remember. Actually it controls current for your motor. So it depends on your stepper motor. Here also may appear nasty flaws. For example you have small stepper motor, and setting too high VREG value, than A4988 will sink too much current and your motor will glitch. Anyway you should read A4988 data sheet very accurately.

    DIR PIN is simply for direction, push-pull pin configuration and HIGH/LOW values controls direction, clock wise, anti clock wise.

    RESET INPUT PIN A4988 must get HIGH from your MCU.

    ENABLE INPUT PIN A4988 must get LOW from your MCU.

    SLEEP INPUT PIN A4988 must get HIGH from your MCU, also it is very useful to control it when your stepper job done, else if you leave it always HIGH, stepper motor will eat current and will heat up at idle state.

    Also there are 3 MICROSTEPPING PINS, those are for controlling stepping. As you just starting to play, it will be enough connect those pins to GND, you'll get full stepping regime.If you'll control those pins you can get other regimes like 1/2 stepping, 1/4,1/8,1/16...
    And general pin is STEP pin, it should be driven with TIMER as PWM output with constant pulse width and alternating period.

    Here is an example of STEP PIN control:

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
    GPIO_InitTypeDef init;
    init.GPIO_Mode = GPIO_Mode_AF;
    init.GPIO_OType = GPIO_OType_PP;
    init.GPIO_Pin = GPIO_Pin_9;
    init.GPIO_PuPd = GPIO_PuPd_UP;
    init.GPIO_Speed = GPIO_Speed_Level_2;
    GPIO_Init(GPIOA,&init);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_2);
    

    for example I connect STEP output from MCU PA9 to A4988 STEP input. Which can be driven from timer as PWM. Check your concrete MCU datasheet. Firstly output pin should be configured as AF, with push-pull and resistor is UP. Also setup line for alternating pin.

    Now configuring timer:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    
    TIM_TimeBaseInitTypeDef timerInitStructure;
    timerInitStructure.TIM_Prescaler = 48;
    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    timerInitStructure.TIM_Period = 0;
    timerInitStructure.TIM_ClockDivision = 0;
    timerInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1, &timerInitStructure);
    TIM_OCInitTypeDef osc;
    osc.TIM_OCMode = TIM_OCMode_PWM1;
    osc.TIM_OutputState  = TIM_OutputState_Enable;
    osc.TIM_OutputNState = TIM_OutputNState_Disable;
    osc.TIM_Pulse = 1000;
    osc.TIM_OCPolarity = TIM_OCNPolarity_High;
    osc.TIM_OCNPolarity = TIM_OCNPolarity_Low;
    osc.TIM_OCIdleState =TIM_OCIdleState_Reset;
    osc.TIM_OCNIdleState =TIM_OCNIdleState_Set;
    TIM_OC2Init(TIM1, &osc);
    TIM_Cmd(TIM1, ENABLE);
    

    Here I configure 1us timer, as my MCU frequency is 48MHz. Also you have configure that timer would drive PWM output.
    TIM1->CCR = 10; with this register I can control pulse width, in this example it is 10us.

    TIM1->ARR = 30; with ARR register I can control period, so it means STEP pulse frequency which is equal to stepper motor speed. In this case 30us.

    If you are using HAL and CUBEMX you can get those configurations pretty fast.