加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

这听起来像是堆栈溢出吗?

发布时间:2020-12-16 09:27:15 所属栏目:百科 来源:网络整理
导读:我想我的嵌入式固件代码中可能存在堆栈溢出问题或类似问题.我是一个新的程序员,从来没有处理过SO所以我不确定这是不是发生了什么. 固件控制带有轮子的设备,轮子周围均匀分布磁铁,并且板上有一个霍尔效应传感器,可以检测磁铁何时在其上方.我的固件操作步进器
我想我的嵌入式固件代码中可能存在堆栈溢出问题或类似问题.我是一个新的程序员,从来没有处理过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更改时,您不会开始测试新值.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读