Вы вошли на сайт, как Гость
Регистрация

Управление яркостью свечения светодиода

Программные примеры для микроконтроллеров AVR - AVRStudio
(Управление яркостью свечения светодиода с помощью широтно-импульсной модуляции)

Когда на вывод некоторого порта с постоянной частотой подается и снимается напряжение, получается последовательность импульсов, подобная импульсам системной синхронизации. Обычно при равномерных импульсах первую половину такта на выводе присутствует напряжение, а вторую — отсутствует. Такое распределение называется 50%-м рабочим циклом. Мы можем варьировать распределением нагрузки от 0% рабочего цикла (напряжение постоянно отсутствует) до 100% (напряжение постоянно подается).

Если сохранить частоту импульсов неизменной, но при этом снижать или увеличивать время использования светодиода за один такт, тем самым можно управлять мощностью, потребляемой светодиодом, и, в конечном итоге, — яркостью его свечения. Человеческий глаз воспринимает мигающие с большой частотой светодиоды так, как будто они постоянно включены. Кроме того, мы воспринимаем яркость быстро пульсирующего света как промежуточную между пиковой и средней. Это означает, что интенсивные импульсы с низким рабочим циклом выглядят ярче. Благодаря таким особенностям восприятия можно обеспечить свечение, которое кажется более ярким, задействовав широтно-импульсную модуляцию (ШИМ). К примеру, в случае таймера/счетчика Т/С1 для перехода в режим ШИМ следует установить разряды PWM10 и PWM11 регистра TCCR1A. В этом режиме Т/С1 работает как суммирующий и вычитающий счетчик, осуществляя циклические переходы от 0x0000 к максимальному значению и затем снова возвращаясь к 0x0000. Когда значение счетного регистра совпадает со значением регистра OCR1A, то на выводе микроконтроллера ОС1А устанавливается высокий или низкий уровень сигнала (определяется состоянием разрядов СОМ1А1 и СОМ1А0 регистра TCCR1A). Таким образом, если к выводу ОС1А подсоединить светодиод, то в режиме ШИМ "интенсивностью" его свечения можно управлять, изменяя значение в регистре сравнения OCR1. Реализация циклического увеличения и уменьшения "интенсивности" свечения светодиода, подсоединенного к выводу ОС1А, представлена в листинге 4.8. В этом примере продемонстрировано использование директив препроцессора #if , # elif и #endif , а также библиотечного макроса _BV, используемого для установки того или иного разряда в лог. 1.

Примечание: при компиляции проекта требуется добавить в проект следующие библиотеки: "avr/io.h", "avr/interrupt.h", "signal.h".

#if defined(__AVR_AT90S2313__)
#  define OC1 PB3
#  define OCR OCR1
#  define DDROC DDRB
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
#  define OC1 PB1
#  define DDROC DDRB
#  define OCR OCR1
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \
      defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \
      defined(__AVR_ATmega163__)
#  define OC1 PD5
#  define DDROC DDRD
#  define OCR OCR1A
#endif

#if defined(COM11)
#  define XCOM11 COM11
#elif defined(COM1A1)
#  define XCOM11 COM1A1
#endif

enum { UP, DOWN };

unsigned int pwm;
unsigned char direction;

INTERRUPT(SIG_OVERFLOW1)
{
  switch (direction)
  {
    case UP: if (++pwm == 1023) direction = DOWN;
              break;
    case DOWN: if (--pwm == 0) direction = UP;
                break;
  }
  OCR = pwm;
}

void main (void)
{
  TCCR1A = _BV(PWM10) | _BV(PWM11) | _BV(XCOM11);
  TCCR1B = _BV(CS10);
  TIMSK = _BV(TOIE1);
  OCR = 0;
  DDROC = _BV(OC1);
  sei ();
  while(1);
}

Файлы проекта можно скачать здесь: