AFON // радиотехник affonya@mail.ru
← Проекты на AVR

Проект 21. Программный ШИМ — плавная яркость

Яркость меняется плавно за счёт широтно-импульсной модуляции, реализованной программно. Приём работает на любом выводе любого контроллера.

Задача

Плавно разжигать и гасить светодиод без аппаратного модуля ШИМ.

Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.

Что понадобится

  • ATmega8
  • кварц 8 МГц + 2×22 пФ
  • светодиод + резистор 330 Ом

Схема подключения

ВыводПодключение
PB0светодиод через резистор 330 Ом

Алгоритм

  1. Считать счётчик периода от 0 до 255.
  2. Пока счётчик меньше скважности — держать вывод включённым, иначе выключенным.
  3. Повторить период несколько раз, чтобы яркость была видна.
  4. Увеличивать скважность до максимума, затем уменьшать.

Листинг на ассемблере

Код проверен ассемблером и собирается без ошибок. Скачать: a21.asm · a21.hex (готовая прошивка).

;=======================================================
; Проект 21. Программный ШИМ — плавная яркость светодиода
; ATmega8, 8 МГц. Светодиод на PB0
;=======================================================
.include "m8def.inc"
.def    temp = r16
.def    duty = r17
.def    pcnt = r18
.def    reps = r19

.cseg
.org    0x0000
        rjmp    RESET

RESET:
        ldi     temp, low(RAMEND)
        out     SPL, temp
        ldi     temp, high(RAMEND)
        out     SPH, temp
        ldi     temp, (1<<PB0)
        out     DDRB, temp
        clr     duty

MAIN:
UP:                                     ; разгораемся
        rcall   PWM_BLOCK
        inc     duty
        cpi     duty, 255
        brne    UP
DOWN:                                   ; гаснем
        rcall   PWM_BLOCK
        dec     duty
        brne    DOWN
        rjmp    MAIN

;--- держим текущую яркость несколько периодов ---
PWM_BLOCK:
        ldi     reps, 8
REP:
        clr     pcnt
PERIOD:
        cp      pcnt, duty              ; счётчик меньше скважности?
        brsh    PWM_OFF
        sbi     PORTB, PB0
        rjmp    PWM_NEXT
PWM_OFF:
        cbi     PORTB, PB0
PWM_NEXT:
        nop
        nop
        inc     pcnt
        brne    PERIOD                  ; 256 шагов — период ШИМ
        dec     reps
        brne    REP
        ret

Пояснения

  • Сравнение делается прямо командой cp с переходом brsh («если больше или равно») — короче, чем приём с вычитанием и флагом переноса на PIC.
  • Конец периода ловится по inc с последующим brne: при переполнении регистра из 255 в 0 устанавливается флаг нуля.
  • Программный ШИМ занимает ядро целиком; если нужны другие задачи, берите аппаратный таймер.

Что дальше

Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры AVR.