2021-04-10 06:09 AM
I am only able to use 2 GPIO pins with an STM32F767ZI on a Nucleo-144 board. The issue doesn't appear to be with any specific pins, it's just that only 2 pins seem to output any voltage at all.
Take this code for example:
main.c
#include "./headers/stm32f767xx.h"
#include <stdint.h>
int main(void)
{
initMotor(0);
initMotor(1);
initMotor(2);
uint32_t a = 0;
while (1)
{
if (a >= 25000)
{
stepMotor(0);
stepMotor(1);
stepMotor(2);
a = 0;
}
a++;
}
}
./drivers/motor.c
#include "../headers/stm32f767xx.h"
void initMotor(int step_pin)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
GPIOG->MODER |= (0b01 << (step_pin * 2));
GPIOG->OTYPER &= ~(0b1 << step_pin);
GPIOG->ODR &= ~(0b1 << step_pin);
}
void stepMotor(int step_pin)
{
GPIOG->ODR ^= (0b1 << step_pin);
}
Using this code, only 2 of the 3 GPIO ports give out a voltage as I would expect them to. If main.c is modified to remove any of the three motors/pins, the other two will work (they give out a voltage which changes from HIGH to LOW every time period).
This issue extends even when adding LEDs which are already on the board.
Only a maximum of 2 GPIO pins (regardless of whether it is GPIOA, GPIOB, etc.) ever seem to work.
I am very unsure of the cause of this, and would appreciate any direction that people can point me in.
Solved! Go to Solution.
2021-04-11 04:10 AM
and adding the fifth and final motor as well as an extra variable... GP0, GP2 and GP4 all output 3.30V, whereas the other two (GP1 and GP3) output 0V
and once again, the trend with the registers is the same:
0x40021800 (G_MODER)
0x111 - 0000000100010001
0x40021804 (G_TYPER)
0x0 - 0000000000000000
0x40021814 (G_ODR)
0x1f - 0000000000011111
taking away this extra variable, PG0 PG1 and PG3 spin/step instead. again, the voltages output by these pins reflect this (3.30V) and the other pins (PG2 and PG4) are at 0V
the registers also reflect this:
0x40021800 (G_MODER)
0x45 - 0000000001000101
0x40021804 (G_TYPER)
0x0 - 0000000000000000
0x40021814 (G_ODR)
0x1f- 0000000000011111
2021-04-11 10:30 AM
Post your code, complete, as is, don't edit it.
JW
2021-04-11 10:37 AM
https://github.com/Starman3787/motor-driver-test (it is a little big to post here)
the 'main' branch contains the fully updated code that i am using currently
2021-04-11 02:01 PM
I see nothing suspicious there.
From where I sit, the only option now is that you step through the code in debugger and observe, what happens with GPIOG_MODER in each step.
Alternatively, you can go through the disasm, if you are comfortable with that. Or post it, it's a fairly simple program so it shouldn't be that long.
JW
2021-04-11 04:51 PM
thanks for looking into this and the suggestion.
i added a breakpoint at the end of the motor initialisation function. each time the program stopped, i examined the MODE register, and it seemed to have the correct values. when it reached the loop, all motors spun correctly!
my best guess from this is that perhaps the MODE register was being set too quickly? the delay from having breakpoints between each call to the initMotor() function seemed to solve the issue of the MODE register not being set properly.
i'll try looking into this a little more and will update you if i find anything dramatic
2021-04-12 03:55 AM
Try to remove
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
from initMotor(), and place it at the beginning of main(). Also try to add a readback of RCC->AHB1ENR after that.
JW
2021-04-13 03:07 AM
gave that a go and it completely fixed the issue, without the use of breakpoints between each initialisation function
do you know why it behaved like this? surely if the clock register has already been set for that GPIO, OR'ing it any further shouldnt change anything?
2021-04-13 04:16 AM
> do you know why it behaved like this?
No, it's a mystery to me.
Can you please contact ST through the web support form, giving link to this thread and to that github repo? Maybe we'll hear some explanation.
JW
2021-04-13 04:34 AM
will do, thanks so much for the assistance, i really appreciate it.
i will let you know here if i hear anything from ST about this
2021-04-13 06:24 AM
The RM0410 section 5.2.12 explains this. After enabling any peripheral clock, there is a general requirement to wait at least 2 peripheral clock cycles. And take a note - it's peripheral, not core or some other clock cycles.