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!
}
}
这段代码对我有用。
我和我的朋友正在做一个涉及编程 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!
}
}
这段代码对我有用。