将值转换为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中。为什么将16bit向左移动?

解决方法

根据OP的注释,int是两个字节,并且未包含可能声明为delay_ms的标头。然后会发生什么:

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

解决方案是在调用例程的源文件中包含delay_ms声明。另外,在编译器中启用警告并予以注意。编译器可能会警告不要使用delay_ms,而无需声明。

,

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