AVR C功能适用于Main,但不适用于其他功能

时间:2015-10-04 17:44:55

标签: c avr

我和我的朋友正在开展一个涉及编程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,包含或头文件的顺序有关,但作为缺乏经验的C程序员,我们有点迷失。

我们可以使用内置的延迟功能,但将来可能会出现这个问题!

任何提示赞赏!

3 个答案:

答案 0 :(得分:1)

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

使用内置_delay_ms();它已经过正确校准,并且在优化时不会消失。

答案 1 :(得分:0)

我可以建议这种方法吗?

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

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

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

答案 2 :(得分:0)

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

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

int main(void)
{

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

此代码适用于我。