这里是一个简单的7段显示,有一个按钮,问题是,每当我使时钟1兆赫,显示并不像预期的那样运行,但当我使用8兆赫时钟时,它工作良好。以下是代码:
#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD &= ~(1<<PD4);
DDRC |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3);
PORTC = 0;
while (1)
{
if(PIND & (1<<PD4)){
_delay_ms(25);
if(PIND & (1<<PD4)){
PORTC++;
}
}
}
}

发布于 2020-11-15 17:44:49
F_CPU应该与proteus中的硬件熔断器配置相同,您可以通过双击atmega 16并更改CKSEL熔断器来更改它们

一些信息也许能帮上忙
_delay_ms()它只向西,一些CPU周期取决于所需的时间,在计算中使用F_CPU。300ms,以确保程序不会处理相同的单击超过一次,如果按住键,它将以可视的方式增加。错误行为分析
25ms是一个很短的时间..。一个正常的人类点击将围绕200-300ms,所以在每次点击时,微控制器将考虑它不止一个。
当我使用8兆赫时钟时,它可以正常工作。
当您将F_CPU更改为8 8MHZ时,_delay_ms()会按此速度进行计算,并将向西移动更多的周期.而实际速度是1 1MHZ
这种速度的差异( F_CPU和实际速度之间的差异)导致了8倍慢的延迟=‘25 ms’*8 ='200 ms‘。
简单的解决方案将_delay_ms(25)增加到_delay_ms(200),以达到同样的效果。
更新(关于延迟工作的信息)
_delay_ms只是浪费CPU周期的循环,它阻止CPU工作。
微控制器的频率由硬件熔断器决定,因此您需要告诉软件使用抛出的频率,定义F_CPU,这样软件就会知道每一个周期都需要时间= 1/F_cpu。
当您需要延迟时,软件已经知道每个时钟所花费的时间,因此它将计算出实现所需延迟时间所需的周期数(,如果您需要延迟1ms延迟,而每个时钟连接1 us,则需要等待1000个周期才能实现这些延迟)。
在程序集中,有名为nop的指令,只需一个循环即可执行,什么也不做。
下面的代码不正确,但编译器在程序集中翻译_delay_ms()时会产生类似的情况
for(int i=0;i<50;i++)nop;这段代码将使50 nop和wast 50循环(实际上超过50,因为访问和增量变量nop将消耗一些周期,但忽略了这一点)
阅读更多
https://stackoverflow.com/questions/64847435
复制相似问题