繁体   English   中英

AVR C函数可从Main起作用,但不能从其他Function起作用

[英]AVR C Function works from Main but not from other Function

我和我的朋友正在从事一个涉及attiny编程的项目48。 我们在Atmel Studio 6.2中进行编码。

为了让我们在C和嵌入式编程中立足,我们正在尝试制作LED闪光灯。 这是到目前为止的代码:

用户名

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闪烁。

我们已经处理了代码,并确定从main()调用时,Delay_Ms(ms)起作用,而从Init()调用时,则不起作用。 我们怀疑这与定义,defs,includes或头文件的顺序有关,但是作为缺乏经验的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!
   }
}

该代码对我有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM