Я думаю, что у меня может возникнуть проблема с переполнением стека или что-то подобное в моем встроенном коде прошивки. Я новый программист и никогда не занимаюсь 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? И я не устанавливаю значение детектора останова в другом месте в моем коде.
У вас есть какие-либо советы о том, как я могу отследить корень этой проблемы?
ИСР выглядит следующим образом
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
Похоже, что это решило проблему. Я до сих пор не знаю, как StallDetector смог получить до 200+, но я добавил одну строку кода, которая кэширует значение PosSensor в начале этой функции, изменила пару имен переменных и теперь работает более 1500 последовательных ходов без проблем! – PICyourBrain
PosSensor и LastPosMagState были выключены. Это позволило StallDetector приблизиться к значению (GapSize + 10). Тогда состояние гонки поражает; PosSensor включается после if (PosSensor! = LastPosMagState), но раньше, если (PosSensor == ON), поэтому StallDetector не получает значение 0, если это должно было быть, что позволяет сравнить значение GapSize'd StallDetector с вашим MagnetSize – ajs410
Охххх, это имеет смысл! Спасибо за exp. – PICyourBrain