我认为我的嵌入式固件代码中可能存在堆栈溢出问题或类似问题。我是一名新程序员,从未处理过 SO,所以我不确定这是否正在发生。
固件控制一个带有轮子的设备,轮子周围有均匀分布的磁铁,电路板有一个霍尔效应传感器,可以感应磁铁何时在其上方。我的固件操作步进器并计算步数,同时监控磁传感器以检测车轮是否失速。
我在我的芯片上使用定时器中断(8 位,8057 acrh。)来设置输出端口以控制电机和失速检测。失速检测代码如下所示...
// 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
最佳答案
PosSensor 是否不稳定?也就是说,您是在某处更新 PosSensor,还是直接读取 GPIO?
我假设 GapSize 相当大(> 220?)在我看来你可能有竞争条件。
// PosSensor == OFF, LastPosMagState == OFF
if(PosSensor != LastPosMagState)
{
StallDetector = 0;
LastPosMagState = PosSensor;
}
else
{
// Race Condition: PosSensor turns ON here
// while LastPosMagState still == OFF
if (PosSensor == ON)
{
if (StallDetector > (MagnetSize + 10))
{
HandleStallEvent();
}
}
else if (PosSensor == OFF)
{
if (StallDetector > (GapSize + 10))
{
HandleStallEvent();
}
}
}
您应该在执行 StallDetector++ 之后立即缓存 PosSensor 的值一次,以便在您的代码期间 PosSensor 发生变化时,您不会开始测试新值。
关于c - 这听起来像堆栈溢出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2654895/