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

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

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

Задача

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

Микроконтроллер: PIC16F84A, кварц 4 МГц. Среда: MPLAB X + MPASM (или любой совместимый ассемблер). Как настроить среду и прошить контроллер — в статье программирование PIC.

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

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

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

ВыводПодключение
RB0светодиод через резистор 330 Ом
MCLRчерез 10 кОм на +5 В

Алгоритм

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

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

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

;=======================================================
; Проект 21. Программный ШИМ — плавная яркость светодиода
; PIC16F84A, 4 МГц. Светодиод на RB0
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

        cblock  0x0C
        duty                    ; текущая скважность 0..255
        pwmcnt                  ; счётчик внутри периода
        reps                    ; сколько периодов держать яркость
        endc

        ORG     0x000
        goto    Start

Start
        bsf     STATUS,RP0
        clrf    TRISB
        bcf     STATUS,RP0
        clrf    PORTB
        clrf    duty

Main
        ;--- разгораемся ---
Up
        call    PwmBlock
        incf    duty,f
        movf    duty,w
        xorlw   .255
        btfss   STATUS,Z
        goto    Up
        ;--- гаснем ---
Down
        call    PwmBlock
        decf    duty,f
        movf    duty,w
        btfss   STATUS,Z
        goto    Down
        goto    Main

;--- держим текущую яркость несколько периодов ШИМ ---
PwmBlock
        movlw   .8
        movwf   reps
Rep
        clrf    pwmcnt
Period
        movf    pwmcnt,w
        subwf   duty,w          ; duty - pwmcnt
        btfss   STATUS,C        ; если pwmcnt < duty — светит
        goto    Off
        bsf     PORTB,0
        goto    NextTick
Off
        bcf     PORTB,0
NextTick
        nop
        nop
        incfsz  pwmcnt,f        ; 256 шагов = период ШИМ
        goto    Period
        decfsz  reps,f
        goto    Rep
        return

        END

Пояснения

  • Сравнение делается вычитанием subwf и проверкой флага переноса C — у PIC нет отдельной команды сравнения.
  • Частота ШИМ должна быть выше ~100 Гц, иначе появится заметное мерцание.
  • Программный ШИМ занимает ядро целиком; если нужны другие задачи, берите аппаратный модуль CCP.

Что дальше

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