我和我的朋友正在开展一个涉及编程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程序员,我们有点迷失。
我们可以使用内置的延迟功能,但将来可能会出现这个问题!
任何提示赞赏!
答案 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!
}
}
此代码适用于我。