Я думаю, что у меня может быть проблема переполнения стека или что-то подобное во встроенном коде прошивки. Я новый программист и никогда не имел дело с SO, поэтому я не уверен, происходит ли это так или нет.
Микропрограмма управляет устройством с колесом, равномерно расположенным вокруг него на магнитах, а на плате установлен датчик эффекта Холла, который определяет, когда магнит находится над ним. Моя прошивка управляет шаговым двигателем, а также подсчитывает шаги во время мониторинга датчика магнита, чтобы определить, не затормозилось ли колесо.
Я использую прерывание таймера на моем чипе (8 бит, 8057 акр.) Для настройки выходных портов для управления двигателем и для обнаружения останова. Код обнаружения останова выглядит следующим образом ...
// Enter ISR
// Change the ports to the appropriate value for the next step
// ...
StallDetector++; // Increment the stall detector
if(PosSensor != LastPosMagState)
{
StallDetector = 0;
LastPosMagState = PosSensor;
}
else
{
if (PosSensor == ON)
{
if (StallDetector > (MagnetSize + 10))
{
HandleStallEvent();
}
}
else if (PosSensor == OFF)
{
if (StallDetector > (GapSize + 10))
{
HandleStallEvent();
}
}
}
этот код вызывается каждый раз, когда запускается ISR. PosSensor - это магнитный датчик. MagnetSize - это количество шаговых шагов, которое требуется, чтобы пройти через магнитное поле. GapSize - это количество шагов между двумя магнитами. Поэтому я хочу определить, не застряло ли колесо с датчиком над магнитом или не над магнитом.
Это прекрасно работает в течение длительного времени, но затем через некоторое время произойдет первое событие остановки из-за 'StallDetector> (MagnetSize + 10)', но когда я смотрю на значение StallDetector, оно всегда около 220! Это не имеет смысла, потому что MagnetSize всегда около 35. Таким образом, событие останова должно было инициироваться как 46, но каким-то образом оно доходило до 220? И я не устанавливаю значение детектора остановки в другом месте в моем коде.
У вас есть какой-нибудь совет, как я могу отследить корень этой проблемы?
ISR выглядит так
void Timer3_ISR(void) interrupt 14
{
OperateStepper(); // This is the function shown above
TMR3CN &= ~0x80; // Clear Timer3 interrupt flag
}
HandleStallEvent
просто возвращает несколько переменных к их значениям по умолчанию, чтобы он мог предпринять еще один шаг ...
#pragma save
#pragma nooverlay
void HandleStallEvent()
{
///*
PulseMotor = 0; //Stop the wheel from moving
SetMotorPower(0); //Set motor power low
MotorSpeed = LOW_SPEED;
SetSpeedHz();
ERROR_STATE = 2;
DEVICE_IS_HOMED = FALSE;
DEVICE_IS_HOMING = FALSE;
DEVICE_IS_MOVING = FALSE;
HOMING_STATE = 0;
MOVING_STATE = 0;
CURRENT_POSITION = 0;
StallDetector = 0;
return;
//*/
}
#pragma restore