|
Управление яркостью свечения светодиода
Программные примеры для микроконтроллеров 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);
}
|
Файлы проекта можно скачать здесь:
|
|
|