_delay_ms, кажется, не работает при использовании PWM - PullRequest
0 голосов
/ 01 мая 2020

Я относительно новичок в программировании микроконтроллеров, поэтому я начал экспериментировать на ATtiny85.

Первая программа просто включала светодиод и выключалась с небольшой задержкой (classi c blinky program).

Теперь я хотел медленно увеличить яркость светодиода. Вот код:

#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;
    }
}

Я ожидал, что светодиод выключится на полсекунды, а затем увеличит яркость. Но если я запускаю код, светодиод просто становится более ярким, как если бы _delay_ms(500) игнорировалось.

Функция analogOutput основана на функции библиотеки Arduino.

Что здесь не так? Почему задержка не работает должным образом?

РЕДАКТИРОВАТЬ

Я изменил свою функцию l oop, новое содержимое:

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

Это работает, у меня теперь есть Светодиод, который постоянно переключается с затемненного на полностью включенный и обратно.

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Я чувствую себя глупо ... Это была просто ошибка переполнения, так как я использовал uint8_t и установил < 256 в для l oop, условие всегда было истинным (255 + 1 = 0).

Мое решение было использовать uint16_t для l oop

1 голос
/ 01 мая 2020

__delay_ms() преобразуется компилятором в инструкции по потере цикла, поэтому, если ваш F_CPU соответствует текущей скорости процессора, он должен работать как положено.

Я бы искал другие места в вашем коде, которые не работают так, как вы ожидаете.

Полсекундная задержка при включении питания не является хорошим диагностическим тестом c, поскольку он происходит быстро, только один раз, и тогда могут происходить и другие события.

Возможно, вместо этого попробуйте мигать между двумя различными уровнями яркости с задержкой в ​​500 мс. Визуально это должно быть однозначным.

, если это работает, как ожидалось, тогда, возможно, попробуйте сделать изменение яркости и изменить задержку внутри l oop, чтобы увидеть, работает ли это как ожидалось.

В конце концов вы добьетесь того, что не так, как ожидалось, и тогда вы узнаете, в чем проблема. Еще возможно, что вы не поймете, что происходит, но, по крайней мере, вы сможете задать здесь более конкретный c вопрос и с большей вероятностью получить полезный ответ.

Сообщите в ответ с ваши результаты!

...