-1

我对微控制器编程比较陌生,所以我开始在 ATtiny85 上进行试验。

第一个程序只是打开一个 LED 并稍有延迟(经典闪烁程序)。

现在我想慢慢增加 LED 的亮度。这是代码:

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

#define LED PB0

void setup(void);
void loop(void);
void analogOutput(int8_t brightness);

int main(void)
{
    setup();
    while (1)
    {
        loop();
    }

    return 0;
}

void setup()
{
    TCCR0A = (1 << WGM00) | (1 << WGM01);
    TCCR0B = (1 << CS00) | (1 << CS01);
    DDRB = (1 << LED);
    PORTB = 0;
}

void loop()
{
    int8_t brightness = 0;
    analogOutput(brightness);
    _delay_ms(500);
    for (brightness = 0; brightness < 256; ++brightness)
    {
        analogOutput(brightness);
        _delay_ms(10);
    }
}

void analogOutput(int8_t brightness)
{
    if (brightness == 0)
    {
        // digital output LOW
        TCCR0A &= ~(1 << COM0A1);
        PORTB &= ~(1 << LED);
    }
    else if (brightness == 255)
    {
        // digital output HIGH
        TCCR0A &= ~(1 << COM0A1);
        PORTB |= (1 << LED);
    }
    else
    {
        PORTB &= ~(1 << LED);
        // analog output
        TCCR0A |= (1 << COM0A1);
        OCR0A = brightness;
    }
}

我预计 LED 会关闭半秒钟,然后增加亮度。但是,如果我运行代码,LED 就会变得更亮,就好像_delay_ms(500)被忽略了一样。

analogOutput函数的灵感来自 Arduino 库的函数。

这里有什么问题?为什么延迟没有按预期工作?

编辑

我改变了我的循环功能,新内容:

void loop()
{
    analogOutput(127);
    _delay_ms(500);
    analogOutput(255);
    _delay_ms(500);
}

这行得通,我现在有一个 LED 可以不断地从变暗切换到完全打开和返回。

4

2 回答 2

1

__delay_ms()编译器将其转换为浪费周期的指令,因此只要您F_CPU与处理器的当前速度匹配,它就应该按预期工作。

我会在您的代码中查找其他未按预期工作的地方。

加电时的半秒延迟不是一个很好的诊断测试,因为它发生得很快,只有一次,然后可能还会发生其他事情。

也许改为尝试在两个不同的亮度级别之间闪烁,其间有 500 毫秒的延迟。从视觉上看,这应该是明确的。

如果它按预期工作,那么可以尝试做一个亮度斜坡并改变循环内的延迟,看看它是否按预期工作。

最终你会努力解决不符合预期的事情,然后你就会知道问题出在哪里。您仍然可能不明白发生了什么,但至少您可以在这里提出更具体的问题,并且更有可能得到有用的答案。

报告你的结果!

于 2020-05-01T18:12:15.597 回答
1

我觉得很蠢。。这只是一个溢出错误,因为我在for循环中使用uint8_t并设置< 256,条件始终为真(255 + 1 = 0)。

我的解决方案是使用 uint16_t 进行循环

于 2020-05-01T20:06:05.817 回答