Некорректная работа PWM на ATtiny85

Тема в разделе "Микроконтроллеры AVR", создана пользователем akefa, 26 ноя 2017.

Метки:
  1. akefa

    akefa Нуб

    При нажатии на кнопку, RGB светодиод должен мигнуть пару раз и остаться гореть заданным цветом, но столкнулся с проблемой что красный и синий цвет остаются тускло гореть, а зеленый нормально гаснет, в чем может быть проблема проблема?

    Подключено PB0 - blue, PB1 - red, PB4 - green, PB3 и PB2 кнопки.

    Код (C++):
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>

    #define RED _BV(PB1)
    #define GREEN _BV(PB4)
    #define BLUE _BV(PB0)
    #define TOUCH _BV(PB3)
    #define LIGHT _BV(PB2)
    #define DISABLED 0,0,0
    #define OFF 255,0,0
    #define ON 0,110,255

    bool pressed = false;

    int main(void) {

      DDRB |= RED;
      DDRB |= GREEN;
      DDRB |= BLUE;
      DDRB &= ~ TOUCH;
      DDRB &= ~ LIGHT;

      TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00) | _BV(WGM01);
      TCCR0B = _BV(CS00);
      TCCR1 = _BV(CS10);
      GTCCR = _BV(PWM1B) | _BV(COM1B1);

      sei();
      setColor(ON);

      while (1) {
        byte key = (PINB >> 2) & 1;
        byte button = (PINB >> 3) & 1;
        if (key) {
          setColor(OFF);
        } else {
          setColor(ON);
        }
        if (button && !pressed) {
          pressed = !pressed;
          blink();
        } else if (!button && pressed) {
          pressed = !pressed;
        }
      }
    }

    void setColor (int r, int g, int b) {
      OCR1B = g;
      OCR0A = b;
      OCR0B = r;
    }

    void blink() {
      setColor(DISABLED);
      _delay_ms(200);
      setColor(ON);
      _delay_ms(200);
      setColor(DISABLED);
      _delay_ms(200);
      setColor(ON);
      _delay_ms(200);
    }
     
    Последнее редактирование: 26 ноя 2017
  2. ostrov

    ostrov Гуру

    Не пойму зачем тут PWM?
     
  3. akefa

    akefa Нуб

    Что бы задать цвет, ну и дальше есть еще кусок кода в котором цвета плавно меняются.
     
  4. ostrov

    ostrov Гуру

    То есть при установке 0,0,0 зеленый не горит, а остальные тускло светятся?
     
  5. akefa

    akefa Нуб

  6. akefa

    akefa Нуб

    При этом если взять просто запись 1 или 0, без шим, чтобы поморгать, то все тухнет и загорается нормально.
     
  7. ostrov

    ostrov Гуру

    Вечерком попробую вникнуть. Что то тут не так, подозреваю в настройкпх ШИМ.
     
  8. ostrov

    ostrov Гуру

    Да, идут какие то хаотичные иголки при нуле. Грешу на совместное использование таймера 0 ШИМа и _delay_ms().
     
  9. rkit

    rkit Гуру

    Шим надо совсем отключать на нуле, если мне не изменяет память. Потому что он так работает - при сбросе счетчика ставит 1, при совпадении с output compare ставит 0. То есть один цикл все равно проскакивает.
     
    Последнее редактирование: 27 ноя 2017
  10. akefa

    akefa Нуб

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

    rkit Гуру

    Просто выключить и всё.
     
  12. akefa

    akefa Нуб

    Наверно глупый вопрос, подскажите как именно выключить шим, а потом включить обратно?
     
  13. ostrov

    ostrov Гуру

    У таймера 1 ничего не проскакивает. А у 0 таймера именно что хаотично. Да и при значениях отличных от 0 ШИМ какой то кривой, неравномерный. Чем то еше таймер занят будьто.
     
  14. akefa

    akefa Нуб

    И как можно проверить чем еще таймер занят?
     
  15. rkit

    rkit Гуру

    Это ваш код. Вы его писали. Вы включали шим. Значит вы должны знать, как его выключить.. Если вы не знаете, что код делает, а просто скопировали чужой, не читая, то это и есть корень вашей проблемы. Код нельзя бездумно копировать. Откройте даташит, и разберитесь, что делает каждая инструкция. Я этого делать за вас не буду, у меня свои дела есть.
     
  16. akefa

    akefa Нуб

    Ну это я понял, так отключить шим, это сбросить настройки таймеров, а потом снова их настроить ?
     
  17. rkit

    rkit Гуру

    Нет. Это отключить шим-вывод на пине. Всё.
     
    akefa нравится это.
  18. ostrov

    ostrov Гуру

    Флажками в регистрах таймер останавливается, ими же запускается, какими именно на память не скажу, надо даташит смотреть. Чем занят, как минимум millis считает. Может еще что. Первый вот (PB4) только ШИМом занят и все хор.
     
  19. akefa

    akefa Нуб

    Еще раз, или я правильно понял, мне нужно COM0A1 и COM0B1 перевести в 0, чтобы отключить их от таймера T0 и перевести в нормальный режим, этим самым я отключаю шим на выводах OCR0A и OCR0В, дальше записываю в порт pb0 и pb1 0 чтобы добится полного затухания светодиода, после COM0A1 и COM0B1 возвращаю в предыдущие состояние что бы включить шим обратно, я правильно понял логику?
    то есть так OCR0A ? TCCR0A |= 1<<COM0A1 : TCCR0A &= ~(1<<COM0A1); ???
     
    Последнее редактирование: 27 ноя 2017
  20. rkit

    rkit Гуру

    Нет, вы совершенно неправильно поняли логику. Логика такая: сначала учимся программировать микроконтроллеры, потом пишем программы. Не наоборот.