AVR C 函数适用于 Main 但不适用于其他函数

AVR C Function works from Main but not from other Function

我和我的朋友正在做一个涉及编程 attiny48 的项目。 我们在 Atmel Studio 6.2 中编码。

为了熟悉 C 语言和嵌入式编程,我们正在尝试制作 LED 闪光灯。这是我们目前的代码:

User.h

ifndef USER_H_
#define USER_H_

#include <avr/io.h>

// # Defines

#define F_CPU 1000000UL

// Function Prototypes
extern void Delay_Ms(uint16_t ms);
extern void Init(void);

extern uint8_t Check_Infrared(void);
extern void Toggle_PC0 (void);
#endif /* USER_H_ */

User.c

#include <avr/io.h>
#include <delay.h>
#include "User.h"

void Delay_Ms(uint16_t ms)
{
    uint32_t Delay_Cycles;


    for (Delay_Cycles = (ms * (F_CPU/10000)) ; Delay_Cycles > 0 ; Delay_Cycles--);
}

void Init(void)
{
    // Define Output Pins
    DDRC = DDRC |(1<<DDC0); // PC0 is digital output

    while(1)
    {
        PINC = (1<<PINC0); // Toggle PC0, This is the LED we have connected
        //_delay_ms(1000);  This is the builtin Delay which works here
        Delay_Ms(1000);  //we have established that this fails
    }
}

Main.c

#include <avr/io.h>
#include "User.h"

int main(void)
{
    Init();
    while(1)
    {
        PINC = (1<<PINC0); // Toggle PC0
        Delay_Ms(1000);  //if we let it get here, it works!
    }
}

所以发生的事情是:main() 调用函数 Init(),我们在其中复制了应该使 LED 闪烁的 while 循环。在这里,它不起作用。 如果我们在 Init() 函数中注释掉 while(1) 循环,则 main() 中的 while(1) 循环运行并且 LED 闪烁。

我们玩过代码并确定 Delay_Ms(ms) 在从 main() 调用时有效,但在从 Init() 调用时无效。我们怀疑这与定义顺序、defs、include 或头文件有关,但作为没有经验的 C 程序员,我们有点迷茫。

我们可以只使用内置的延迟功能,但以后这个问题可能会在其他地方出现!

感谢任何提示!

您的 Delay_Ms() 功能将无法按您预期的方式运行。如果未启用优化,内部循环编译为大约 20 条指令,因此 运行 比预期慢得多。但是,如果启用优化,整个循环都会被优化掉,导致延迟完全消失。 (整个函数最终只是编译成一条 ret 指令!)

使用内置_delay_ms();校准正确,优化后不会消失

我可以推荐这种方法吗?

void Delay_Ms(uint16_t ms)
{
    while(ms--){
        _delay_ms(1);//built in util/delay.h
    }
}

它会随着时间的推移失去一些准确性(可能每毫秒 1us),但这样你可以使用更大值的延迟(我怀疑你意识到你不能直接使用 _delay_ms)

如果你想要准确的延迟,你需要用计时器来实现它们...

我认为你的切换代码是错误的。

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{

   while(1)
   {
       PORTC ^= (1<<PINC0); // Toggle PC0
       _delay_ms(1000);  //This will work!
   }
}

这段代码对我有用。