Search code examples
cstm32bare-metalnucleostm32f7

Why is the pin on a Nucleo 144 not outputting a high enough voltage, despite the output being set to HIGH?


I am trying to control a stepper motor, using a A4988 driver along with a Nucleo 144 board with an STM32F767ZI on it.

The A4988 driver expects a single rise in voltage to HIGH in order to step the motor.

Having made some voltage readings using a multimeter, I have found that during and even while the program is paused, there is a steady voltage of around 1.2V being output by the pin.

I also added some lines to toggle an LED (built onto the board) whenever the output to the A4988 driver is toggled between HIGH and LOW, which works fine.

Here is the code:

main.c

#include "./headers/stm32f767xx.h"
#include <stdint.h>

int main(void)
{
    initMotor(0);
    initLed(0);
    uint32_t a = 0;
    while (1)
    {
        if (a >= 300000)
        {
            toggleLed(0);
            stepMotor(0);
            a = 0;
        }
        a++; 
    }
}

./drivers/motor.c

#include "../headers/stm32f767xx.h"

void initMotor(int step_pin)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN; // enable GPIOG clock
    GPIOG->MODER &= ~(0b11 << (step_pin * 2)); // clear bits
    GPIOG->MODER |= (0b01 << (step_pin * 2)); // set mode to OUTPUT
    GPIOG->OTYPER &= ~(0b1 << step_pin); // set output type to PUSH-PULL
    GPIOG->PUPDR |= (0b10 << (step_pin * 2)); // pull the pin down
    GPIOG->ODR &= ~(0b1 << step_pin); // set output to LOW
}

void stepMotor(int step_pin)
{
    GPIOG->ODR ^= (0b1 << step_pin); // toggle between LOW and HIGH
}

./drivers/led.c

#include "../headers/stm32f767xx.h"

void initLed(int pin)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable GPIOG clock
    GPIOB->MODER |= (0b01 << (pin * 2)); // set mode to OUTPUT
    GPIOB->OTYPER &= ~(0b1 << pin); // set output type to PUSH-PULL
    GPIOB->ODR &= ~(0b1 << pin); // set output to LOW
}

void toggleLed(int pin)
{
    GPIOB->ODR ^= (0b1 << pin); // toggle between LOW and HIGH
}

I've verified, using a multimeter, that the voltage being provided to the board via an STLINK USB is 5V (which I believe is sufficient), and the driver is also receiving the correct voltage of 5V.

I do not believe this to be a problem to do with the A4988 driver. I have tried multiple of the same driver from various manufacturers, and still I get the same result. The motors are also being supplied a high enough voltage (12V) but are not drawing it all in.

I have come to the conclusion that it is most likely an issue originating from the Nucleo 144 board, but a little stuck as to what the actual issue is.

I am using GPIO G pin 0, which is labelled "IO" on the board.

Any suggestions as to what I should try next, or ideas as to what it could be, are greatly appreciated.


As requested, here is a diagram of my setup:

diagram


Solution

  • If you configure the output to be PUSH/PULL, adding a PULLDOWN resistor will divide the output voltage over the resistor. Do not use PU/PD resistors with PP, because it is always driven and doesn't need a PU/PD.