我想我的嵌入式固件代码可能有堆栈溢出问题或类似的问题。我是一个新的程序员,从来没有处理过这样的问题,所以我不确定这是不是正在发生的事情。
固件通过一个轮子控制一个设备,这个轮子周围有均匀分布的磁铁,而电路板上有一个霍尔效应传感器,当磁铁在上面时可以感应到。我的固件操作步进器,并计数步骤,同时监测磁铁传感器,以检测车轮是否已熄火。
我在我的芯片上使用定时器中断(8位,8057acrh.)来设置输出端口,以控制电机和失速检测。失速检测代码如下所示…

    //   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点?在我的代码中,我没有在其他地方设置stall detector的值。
你对我如何找出这个问题的根源有什么建议吗?
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发生更改时,就不会开始测试新值。

07-26 00:29