A191919 A191919 - 2 months ago 20
C Question

STM32 run async function

Function

FirstMotorRotateToLeft()
engage first motor, function
SecondMotorRotateToLeft()
enagage second motor. The main question is how to run two motors in the same time?

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void Delay(unsigned int t)
{
unsigned int i;
for (i=0;i<t;i++);
}

void GPIOD_Initialize(){
GPIO_InitTypeDef GPIOC_Stepper;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
GPIOC_Stepper.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_7;
GPIOC_Stepper.GPIO_Mode=GPIO_Mode_Out_PP;
GPIOC_Stepper.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIOC_Stepper);

GPIO_InitTypeDef GPIOD_Stepper;
GPIOD_Stepper.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_7;
GPIOD_Stepper.GPIO_Mode=GPIO_Mode_Out_PP;
GPIOD_Stepper.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIOD_Stepper);
}
void SecondMotorRotateToLeft()
{
GPIO_Write(GPIOD,GPIO_Pin_5);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_5| GPIO_Pin_3);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_3);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_3|GPIO_Pin_7);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_7);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_7|GPIO_Pin_1);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_1);
Delay(time);

GPIO_Write(GPIOD,GPIO_Pin_1|GPIO_Pin_5);
Delay(time);
}
void FirstMotorRotateToLeft()
{
GPIO_Write(GPIOC,GPIO_Pin_5);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_5| GPIO_Pin_3);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_3);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_3|GPIO_Pin_7);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_7);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_7|GPIO_Pin_1);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_1);
Delay(time);

GPIO_Write(GPIOC,GPIO_Pin_1|GPIO_Pin_5);
Delay(time);
}

int main(void)
{
const int time = 10000;
GPIOD_Initialize();
while(1)
{
FirstMotorRotateToLeft();
SecondMotorRotateToLeft();
}
}

Answer

With that super-synchronuous monolithic design, running them at the same time is going to be hard.

I would suggest re-designing both motor functions into smaller steps, each of which can be expressed as a state machine. Then just step both state machines quickly after each other, and you should be fine.

How to do this is a bit hard to quickly show, since it tends to become quite a lot of code, but perhaps something like this could serve as inspiration:

typedef enum { MOTOR_OFF, MOTOR_... } MotorState;

static MotorState runFirstMotor(MotorState state, uint32_t clock)
{
}

static MotorState runSecondMotor(MotorState state, uint32_t clock)
{
}

The idea is that the two functions implement the state machines for the two motors. Each function accepts the current state and current system time, and return the new state (which might be different if the state machine generated a state transition).

The clock is supposed to be the current time in some suitable unit, perhaps milliseconds. You'd get this from one of the system timers (perhaps even SysTick since you're on an STM32). The state machines use this to implement delays (together with more ... state, which is not shown).

It looks like the pin-poking is identical for the two motors except living on different GPIO ports so perhaps can factor that out.