读取 MSP430 IO 寄存器太快?

发布于 2024-12-23 15:19:55 字数 706 浏览 5 评论 0原文

我正在开发一个系统,其中 MSP430 通过 SPI 总线与另一个芯片进行通信。我通过 SPI 总线发送一系列设置命令,并轮询从芯片的就绪线。我使用 IAR 作为我的 IDE,并且在没有任何优化的情况下编译代码。代码看起来像这样:

for(int i = 0; i < NUM_SETUP_COMMANDS; i++)
{
    SendSetupCommand(); //puts data in SPI Tx buffer, sets Chip select low

    while(P1IN & 0x40) //wait for Chip ready line to go low
    {
        for(int x; x < 1024; x++)
        { 
            //do nothing 
        }
    }

    HandleReadyLine(); //Transmit/Receive data on SPI bus
 }

无论有没有空的内部 for 循环,此代码都可以正常工作。所有设置消息均通过 SPI 总线正确传输。如果没有内部 for 循环,此代码块大约需要 10 秒。使用内部 for 循环,此代码块大约需要 100 毫秒。

似乎尽可能快地读取 P1IN,而不使用内部 for 循环,会导致 P1IN 无法快速更新。这有什么意义吗?添加/删除内部 for 循环会导致如此剧烈的时序变化是否有明确的原因?

I'm working on a system where a MSP430 is communicating with another chip over its SPI bus. I'm sending a series of setup commands over the SPI bus and polling on the slave chip's Ready line. I'm using IAR as my IDE and I'm compiling the code without any optimization. The code looks something like this :

for(int i = 0; i < NUM_SETUP_COMMANDS; i++)
{
    SendSetupCommand(); //puts data in SPI Tx buffer, sets Chip select low

    while(P1IN & 0x40) //wait for Chip ready line to go low
    {
        for(int x; x < 1024; x++)
        { 
            //do nothing 
        }
    }

    HandleReadyLine(); //Transmit/Receive data on SPI bus
 }

With and without the empty inner for loop, this code work correctly. All the setup messages are transmitted across the SPI bus correctly. Without the inner for loop, this code block takes around 10 seconds. With the inner for loop, this code block takes about 100 ms.

It seems like reading P1IN as fast as possible, without the inner for loop, causes P1IN to not get updated as fast. Does this make any sense? Is there a clear reason that adding/removing the inner for loop would cause such a drastic timing change?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原野 2024-12-30 15:19:55

应该没有什么区别。

一些调试建议:

我建议将内部循环的迭代减少到零,看看这是否会改变系统时序。还可以尝试将内部循环替换为 nop,看看是否具有相同的效果。您还可以查看生成的程序集,看看两个编译之间是否存在明显的差异。最后,(如果可以的话)确定 SPI 线路的范围,看看两者之间的行为是否有任何差异。

It shouldn't make any difference.

A few debug suggestions:

I would suggest reducing the iterations of the inner loop to zero to see if that changes the system timing. Also try swapping the inner loop for a nop and see if that has the same effect. You might also take a look at the generated assembly and see if there is anything obvious between the two compilations. Lastly, (if you can) scope the SPI lines and see if there is any difference in behaviour between the two.

给我一枪 2024-12-30 15:19:55

该循环可能已优化。
确保它没有被优化的一种方法是执行虚拟计算,例如

for(int i = 0; i < NUM_SETUP_COMMANDS; i++)
{
    SendSetupCommand(); //puts data in SPI Tx buffer, sets Chip select low

    while(P1IN & 0x40) //wait for Chip ready line to go low
    {
        volatile unsigned int i;
        for(int x; x < 1024; x++)
        { 
            j++; 
        }
    }
    HandleReadyLine(); //Transmit/Receive data on SPI bus
}

这里的关键是“易失性”关键字,它禁止编译器对变量 j 进行优化,因此不应删除循环。

The loop is probably optimized.
One way to make sure it is not optimized is to preform a dummy computation such as

for(int i = 0; i < NUM_SETUP_COMMANDS; i++)
{
    SendSetupCommand(); //puts data in SPI Tx buffer, sets Chip select low

    while(P1IN & 0x40) //wait for Chip ready line to go low
    {
        volatile unsigned int i;
        for(int x; x < 1024; x++)
        { 
            j++; 
        }
    }
    HandleReadyLine(); //Transmit/Receive data on SPI bus
}

The key here is the "volatile" keyword which forbids optimization of variable j by the compiler, thus your loop should not be removed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文