将转换错误的值传递给avr c中的uint32_t



我在Atmel Studio 7中为我的atmega2560模拟代码。我有一个delay_ms函数。我这么称呼它:

delay_ms(150);

我有这个功能

void delay_ms(uint32_t mstime){
uint32_t tnow=millis();
tnow+=mstime;
while (tnow>=millis());
}

在函数中,mstime值为9830400,它在二进制1001 0110 0000 0000 0000中,150在二进制1001 011 0中。为什么它向左移动了16位?

根据OP的注释,int是两个字节,并且不包括可能声明delay_ms的标头。然后发生的是:

  • 当调用delay_ms时,编译器根据历史C行为插入int delay_ms();的默认声明
  • 由于delay_ms的声明没有参数原型,因此delay_ms(150)中的150将作为两个字节的int传递
  • delay_ms的定义中,参数被定义为uint32_t,它是四个字节。因此,该函数查找四个字节的参数
  • 额外的两个字节恰好包含零,并且由于机器的字节序,被用作uint32_t的低两个字节,传递的两个字节(0x0096(被用作高两个字节
  • 这形成了OP观察到的0x00960000(9830400(值

解决方案是在调用例程的源文件中包含delay_ms的声明。此外,在编译器中启用警告并注意它们。编译器可能在没有声明的情况下警告使用delay_ms

我不知道为什么,但可能#include<avr/io.h>还有一个delay_ms函数,它似乎是uint16t参数。我会检查一下的。我在相应的xxxx.c文件中包含了我的timer.h,现在它也可以工作了。

最新更新