У меня проблема с STM32F091RCT на Nucleo, который я использую для управления драйвером шагового двигателя DRV8825.
Основная цель раздела кода ниже состоит в том, чтобы остановить шаговый двигатель, когда он вращается слишком сильно, используя прерывание от переключателя Холла и магнит. Я также использую библиотеки HAL для STM32 и, конечно, язык C.
У меня есть эти файлы:
motor.h:
typedef struct{
volatile uint8_t STOP_FLAG
} Motor;
motor.c:
#include "motor.h"
void ClearStopFlag(Motor *motor)
{
motor->STOP_FLAG = 0;
}
void SetStopFlag(Motor *motor)
{
motor->STOP_FLAG = 1;
}
uint8_t GetStopFlag(Motor *motor)
{
return motor->STOP_FLAG;
}
void Init(Motor *motor)
{
ClearStopFlag(motor);
}
void Rotate(Motor *motor)
{
int i;
for(i = 0; i < 50; i++) // every iteration is a motor step
{
if(GetStopFlag(motor)) break;
// irrelevant code switching the output used for driver step input ----
}
}
void Disable(Motor *motor)
{
// Code that sets the GPIO pin responsible for ENABLE pin in the driver ----
}
hall.c:
#include "motor.h"
#include "exec.h"
extern Motor m;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
SetStopFlag(&m);
}
exec.c:
#include "hall.h"
#include "motor.h"
Motor m;
void SomeFunction(void)
{
Init(&m);
Rotate(&m); // here GPIO ISR in hall.c doesn't set the STOP_FLAG while Rotate() is executing
}
main.c:
#include "exec.h"
int main(void)
{
SomeFunction();
return 0;
}
Прежде всего, исходный код намного сложнее, я не включил здесь некоторые заголовки, которые используются для прототипов функций, других полей структуры Motor, других функций и т. Д. У меня сейчас нет доступа к коду это также намного чище.
Я много тестировал, и проблема в том, что функция обратного вызова прерывания GPIO не может изменить переменную STOP_FLAG. Вот как это ведет себя:
- прерывание работает хорошо - когда я пытаюсь включить диод в секции прерывания - оно включается; когда я пытаюсь отключить драйвер с помощью функции Disable () из motor.c, он работает и устанавливает правильный порт GPIO
- когда я пытаюсь установить STOP_FLAG в ISR без функции, которая использует
m->STOP_FLAG = 1;
, она не работает
- когда я вызываю функцию SetStopFlag () из exec.c (например, в SomeFunction () перед строкой Rotate ()), она работает правильно
Кто-нибудь знает, почему hall.c имеет проблемы с доступом к полю struct?