传递值在 avr c 中错误地转换为 uint32_t

Passing value converted wrong to uint32_t in avr c

我在 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值为9,830,400,二进制为1001 0110 0000 0000 0000 0000,150为二进制1001 0110,为什么要左移16位?

我不知道为什么,但也许 #include 也有一个 delay_ms 函数,它似乎是 uint16_t 参数。我会检查它。 我将我的 timer.h 包含在相应的 xxxx.c 文件中,现在它也能正常工作了。

根据 OP 的评论,int 是两个字节,并且不包括可能声明为 delay_ms 的 header。那么会发生什么:

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

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