功能相同的代码,不同的结果

时间:2017-01-06 20:20:33

标签: c++ arduino arduino-uno

我有两段代码,完全相同,但实际上并没有。任何人都可以解释原因吗?

代码通过spi将数据发送到运行显示器的FPGA。我几乎没有代码存储在芯片上,所以我试图尽可能地减少。由于某种原因,下面的变化最终破裂,程序的其余部分与它完全相同。

//Looping to execute code twice doesnt work
for (byte i = 0; i < 3; i++)
      {
        temp2 = temp % 10;
        temp /= 10;
        temp2 |= 0x40;
        for (byte k = 0; k < 2; k++)
        {
          SPI.transfer(reg[j]);
          delayMicroseconds(10);
          SPI.transfer(temp2);
          delayMicroseconds(10);
        }
        reg[j] -= 1;
      }

//But copy-paste does
for (int i = 0; i < 3; i++)
          {
            temp2 = temp % 10;
            temp /= 10;
            temp2 |= 0x40;
            SPI.transfer(reg[j]);
            delayMicroseconds(10);
            SPI.transfer(temp2);
            delayMicroseconds(10);
            SPI.transfer(reg[j]);
            delayMicroseconds(10);
            SPI.transfer(temp2);
            delayMicroseconds(10);
            reg[j] -= 1;
          }

3 个答案:

答案 0 :(得分:0)

最可能的解释是,其他一些代码依赖于满足特定时序约束的循环,如果没有则失败。

您引入的可能影响时间安排的更改包括:

  • i更改为byte类型,而不是int。这可能会影响时间 - int通常是“本机”类型,通过各种措施可以提高操作效率。使用byte可能会更改外循环的时序。例如,如果byte的类型小于int,则对字节的操作可能涉及到int的转换。
  • 基本上你已经用内循环替换了重复的语句序列。根据优化设置,编译器可能会展开循环(实际上产生与第一个代码示例相同的行为),或者它可能不会。如果编译器没有展开循环,那么循环结构本身的开销(初始化变量k,在每次迭代时检查和递增它等)都会影响代码的时序。

如果对符合特定时序约束的代码有所依赖,则需要在某处记录。如果没有记录要求,我建议你记录它(例如将其作为特定要求输入),然后记录派生的要求(例如,使用int来控制外部循环的一个要求[如果需要]和另一个要求是内部循环在代码中展开而不是依赖于编译器优化。)

答案 1 :(得分:0)

  

......出于某种原因打破......

永远不会好,如果某些东西“破裂”,它会对不同的草图产生不同的影响。

reg[j] -= 1; 

如果是这很痛,因为j超出界限,无论是否存在变量k,它都可能有不同的效果。

尝试隔离问题并使其可重现...... 我打赌问题不在发布部分。 ;)

答案 2 :(得分:0)

在您的原始帖子中:“ ...我的芯片上的代码存储空间快用完了……”。 您的RAM怎么样? 有一次我在自己的代码中看到了类似的东西,那是当我只是用完RAM并且变量破坏了堆栈或堆栈破坏了我的变量时。 请记住,C / C ++需要一些“工作”内存来跟踪所有内容。 从可用RAM的一端分配变量,并从另一端分配堆栈。当您使用过多的RAM或您的函数嵌套得太深时,两者会相互碰撞并相互干扰/破坏。

|************ Available RAM ************|
| Variables >>>>>>>>>>>>>>>>!!<<< Stack |

Variables grow >
Stack grow <
Problem !!