2024-11-08 12:43 AM
Hello
I am currently doing a project that require to control a BLDC motor with an STM32 MCU card.
I will first state the list of all the materials that i have, the goal of the project and then talk about my problem.
For this project i have :
- Nucleo-F411RE
- Driver mosfet LF2388B
- Three phase full bridge MTI85W100GC
- BLDC motor ECI-63-60-K1
and i'm using STM32cubeIDE software.
The goal of this project is to control the BLDC motor with the nucleo card. First I detect the position of the motor, then I determine wich phase the motor is and then rotate to the next phase, and regulate the speed with the current sensor.
My first approach was to generate six PWM
I'm using the pin like that :
PB9, PB8, PB6 == position sensor for the motor
PA1, PA4, PB0 == current sensor
PA8 for A, PA10 for A',
PA0 for B, PB10 for B',
PA6 for C, PA7 for C'
I need them to work by pair like this :
Here is the code that I used to control the phase :
#############begin_code#############
//Value used in the code
int valA = 0;
int valB = 0;
int valC = 0;
char str1[60];
char str2[60];
int buttonpressed = 0;
enum Phase {
A, B, C, D, E, F
};
//detecte the phase you are in
enum Phase detectPhase(int valA, int valB, int valC) {
if (valA == 1 && valB == 0 && valC == 0) {
return A;
} else if (valA == 1 && valB == 1 && valC == 0) {
return B;
} else if (valA == 0 && valB == 1 && valC == 0) {
return C;
} else if (valA == 0 && valB == 1 && valC == 1) {
return D;
} else if (valA == 0 && valB == 0 && valC == 1) {
return E;
} else if (valA == 1 && valB == 0 && valC == 1) {
return F;
} else {
return -1; // Phase inconnue
}
}
//determine the next phase
enum Phase nextPhase(enum Phase currentPhase) {
switch (currentPhase) {
case A: return B;
case B: return C;
case C: return D;
case D: return E;
case E: return F;
case F: return A;
}
}
void Run_engine(enum Phase phase){
switch(phase){
case A : { //1,0,0
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); //A
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3); //A'
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3); //B'
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); //C
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); //C'
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); //B
break;
};
case B :{ //1,1,0
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); //A
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3); //B'
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); //C
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2); //C'
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3); //A'
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); //B
break;
};
case C : { //0,1,0
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); // A
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1); //B
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3); //B'
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2); //C'
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3); //A'
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //C
break;
};
case D :{ //0,1,1
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);//A
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);//A'
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);//B
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);//C'
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);//B'
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);//C
break;
};
case E : { //0,0,1
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);//A'
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);//B
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//C
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);//C'
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);//B'
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);//A
break;
}case F : { //1,0,1
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);//A'
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);//B
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);//B'
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//C
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);//C'
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);//A
break;
};
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
//capteur position moteur
if (GPIO_Pin == GPIO_PIN_9 || GPIO_Pin == GPIO_PIN_8 || GPIO_Pin == GPIO_PIN_6){
if (buttonpressed == 1){
valA = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
valB = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8);
valC = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6);
enum Phase phase2 = nextPhase(detectPhase(valA, valB, valC));
Run_engine(phase2);
sprintf(str1,"engine running at phase : %d, and next phase is : %d\r\n",detectPhase(valA, valB, valC),phase2);
HAL_UART_Transmit_IT(&huart2,(uint8_t*)str1,strlen(str1));
}
}
//start engine
if (GPIO_Pin == GPIO_PIN_13) {
if (buttonpressed == 0){
valA = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
valB = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8);
valC = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6);
enum Phase phase = detectPhase(valA, valB, valC);
enum Phase phase2 = nextPhase(phase);
Run_engine(phase2);
sprintf(str2,"engine running at phase : %d, and next phase is : %d\r\n",phase,phase2);
HAL_UART_Transmit_IT(&huart2,(uint8_t*)str2,strlen(str2));
buttonpressed = 1;
}
else if (buttonpressed == 1) {
stop_engine();
sprintf(str2,"engine stop\r\n");
HAL_UART_Transmit_IT(&huart2,(uint8_t*)str2,strlen(str2));
buttonpressed = 0;
}
#############End_code#############
There is nothing in my While(1){}, everything is happening in the callback function. (I put the whole project whith this post).
Now my problem is that when I activate the PWM with HAL_TIM_PWM_Start(), they are not synchronised and the motor isn't running or just make noises.
I would like to know if there is a more efficient way to activate/deactivate the PWM and if not how can I configure the PWM in trigger mode compare to the first one on the run.
Excuse me if a made grammatical mistake, english is not my native language.
Best regards.
A.DLRS