Наш канал в telegram

Программная реализация трехканального ШИМ на микроконтроллере PIC12F629 (программа управления RGB-светодиодом)

Представленная ниже программа предназначена для управления RGB-светодиодом с помощью микроконтроллера PIC12F629. Для этого в программе реализован программный трехканальный ШИМ (ссылку на статью, в которой описана теория того, как это реализовано, можно найти в конце этой статьи). Каждый канал имеет разрядность 2 бита, позволяя таким образом сделать 22=4 различных уровня яркости свечения каждого кристалла, что в совокупности даёт возможность отобразить 4*4*4=64 различных цвета. Частота ШИМ — 100 Гц.

Алгоритм:

Алгоритм трехканального ШИМ на PIC контроллере

Поскольку для каждого канала мы используем 2 бита, то можно все три канала закодировать одним байтом (то есть каждый цвет можно кодировать одним байтом).

В данной программе переменная "skor" служит для задания скорости смены цветов. Количество импульсов ШИМ с одной и той же уставкой (то есть кличество импульсов, отображающих один и тот же цвет) равно начальному значению переменной "skor". В нашем примере начальное значение "skor"=25, то есть каждая уставка действует в течении 25 импульсов (то есть один и тот же цвет отображается 25 раз). Поскольку частота у нас 100 Гц, то 25 импульсов — это 250 мс.

Если есть желание организовать загрузку необходимых цветов с компьютера, то нужно делать аппаратный контроль передачи и, на время обработки подпрограммы прерывания от таймера, запрещать приём данных. Если этого не сделать, то пересылка данных может сбить частоту импульсов. В результате какое-то время некоторые светодиоды могут казаться максимально включенными, а другие — полностью выключенными.

Текст программы под катом

    list p = 12f629
__config 01FC4h
;*** Переменные ******************************************
CBLOCK 0x20  ; Начальный адрес блока
Counter    ; счётчик (1 полный импульс = 3 отсчётам счётчика)
Temp       ; вспомогательная переменная
Temp2      ; ещё одна вспомогательная переменная
Skor       ; скорость смены цветов
RGB1       ; адрес этой переменной 24h
RGB2       ; в этих 7-ми байтах находятся наборы уставок
RGB3       ; для 7-ми цветов
RGB4       ; в каждом байте первые два бита для Blue,
RGB5       ; вторые два бита для Green, третьи для Red
RGB6
RGB7       ; адрес этой переменной 2Ah
ENDC
;*** Константы / Адреса регистров ************************
T1      equ  .48  ; нач.значение аппаратн. счётчика = 255-207=48; 207*16=3328
Status  equ  03h  ; Регистр выбора банка
GPIO    equ  05h  ; управление защелками порта (банк 0)
Cmcon   equ  19h  ; Регистр компаратора (банк 0)
TrisIO  equ  05h  ; выбор направления работы выводов порта (банк 1)
INTCON  equ  0Bh  ; разрешение(1)/запрет(0) прерываний (любой банк)
OPT_REG equ  01h  ; Настройка таймера (банк 1)
TMR0    equ  01h  ; Регистр таймера (банк 0)
OSCCAL  equ  10h  ; хранение калибров-ой константы (банк 1)
INDF    equ  0h   ; Регистр косвенной адресации
FSR     equ  04h  ; Регистр адреса при косвенной адресации
;*********************************************************
; Пусть у нас GP0, GP1, GP5 - выходы управления RGB,
; остальные ноги также сконфигурируем как выходы
; GP5 - Blue, GP0 - Red, GP1 - Green
; В силу того, что у нашего RGB общий плюс, имеем:
; когда на ноге 0 - соответств-ий канал включен, когда 1 - выключен
;*********************************************************
 
org 0
goto   start
org 4
;*** Подпрограмма прерывания от таймера ******************
taimer_prer
bcf    INTCON,7    ; запрет прерываний
movlw  T1          ; устанавлив.начальн.значение счётчика T1
movwf  TMR0
bsf    Status,5    ; и предделитель
movlw  b'00000011'
movwf  OPT_REG
bcf    Status,5
;*** Проверяем программный счётчик ***********************
bcf    Status,2   ; сбросить бит Z
btfsc  Counter,2  ; если счётчик не= 4, - следующ.команда пропуск-ся
clrf   Counter
btfss  Status,2   ; если выполн.обнуление, пропускаем след.команду
goto   Proverka   ; если счётчик не =0, то мы не отсчитали
; целый импульс - переходим к проверкам
;*** Сюда мы попадаем после каждого целого импульса ******
;*** Проверяем указатель на текущую уставку **************
;*** (если он равен 2Bh, то делаем его равным 24h) *******
movlw  2Bh
xorwf  FSR,0
btfss  Status,2   ; если FSR не = 2Bh, - следующ.команда выполн.
goto   Next
movlw  24h
movwf  FSR
;*** Уменьшаем Skor, если равна нулю, загружаем **********
;*** новую уставку и выставляем начальное значение *******
Next  clrf   GPIO       ; зажигаем все светодиоды
decfsz Skor,1     ; если Skor = 0, - пропускаем следующую команду
goto   Proverka
;-----------------------------
movf   INDF,0     ; читаем уставку по адресу, указанному в FSR
movwf  Temp       ; загружаем его в Temp
incf   FSR,1      ; переводим указатель на следующую уставку
movlw  .25        ; значение скорости
movwf  Skor
;*** Сравниваем все значения с уставками, и переключаем если надо
Proverka
swapf  Temp,0      ; после этого уст-ка Red будет в первых 2-х битах W
andlw  b'00000011' ; выделяем уставку Red
xorwf  Counter,0   ; если счётчик=уставке, то установится флаг Z
btfsc  Status,2    ; если Z=0, пропустить следующую команду
bsf    GPIO,0      ; погасить Red
;---------------------------------------
movf   Temp,0
movwf  Temp2       ; загружаем Temp в Temp2
rrf    Temp2,1
rrf    Temp2,0     ; сдвигаем на 2 бита вправо и записываем в W
andlw  b'00000011' ; выделяем уставку Green
xorwf  Counter,0   ; если счётчик=уставке, то установится флаг Z
btfsc  Status,2    ; если Z=0, пропустить следующую команду
bsf    GPIO,1      ; погасить Green
;---------------------------------------
movf   Temp,0
andlw  b'00000011' ; выделяем уставку Blue
xorwf  Counter,0   ; если счётчик=уставке, то установится флаг Z
btfsc  Status,2    ; если Z=0, пропустить следующую команду
bsf    GPIO,5      ; погасить Blue
;*** Выход ***********************************************
incf   Counter,1   ; увеличиваем программный счётчик
bcf    INTCON,2    ; сбросить флаг прерывания от таймера
bsf    INTCON,7    ; разрешить прерывания
retfie             ; выход
;*********************************************************
;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ************************
;*** Калибровка Генератора *******************************
start bsf    Status,5
Call   3FFh        ; Загрузить калибровочную константу в w
movwf  OSCCAL
;*** Установка направления работы и инициализация ног ****
bcf    Status,5    ; перейти в банк 0
movlw  .255        ; 00111111 - все выходы равны 1
movwf  GPIO        ; инициализация защелок
movlw  .7          ; биты 0..2 поднять
movwf  Cmcon       ; компаратор выключен
bsf    Status,5    ; Перейти в 1-й банк
clrf   TrisIO      ; все ноги сконфигурированы как выходы
;*** Конфигурируем таймер и включаем предделитель ********
clrwdt
movlw  b'00000011' ; предделитель =16,
movwf  OPT_REG     ; TMR0 работает от внутр.тактового сигнала
bcf    Status,5    ; переходим в банк 0
;*** Конфигурируем начальные значения переменных *********
clrf   Temp
movlw  .1
movwf  Skor      ; чтобы в первом цикле попасть на загрузку уставок
movlw  .4
movwf  Counter   ; начальное значение счётчика равно 4
movlw  24h
movwf  FSR       ; указатель на первую уставку
;*** Записываем уставки **********************************
movlw  b'00110000'  ; Красный
movwf  RGB1
movlw  b'00110100'  ; Оранжевый
movwf  RGB2
movlw  b'00111100'  ; Желтый
movwf  RGB3
movlw  b'00001000'  ; Зеленый
movwf  RGB4
movlw  b'00001011'  ; Голубой
movwf  RGB5
movlw  b'00000011'  ; Синий
movwf  RGB6
movlw  b'00100010'  ; Фиолетовый
movwf  RGB7
;*** Разрешаем прерывания от таймера *********************
clrf   INTCON       ; запретить все прерывания
bsf    INTCON,5     ; Разрешить прерывания от таймера
bsf    INTCON,7     ; Разрешить немаскированные прерывания
;*** РАБОЧАЯ ЧАСТЬ ***************************************
;*** Сканирование наличия принятой информации ************
Wait  nop                 ; здесь проц может поделать что-то полезное,
goto   Wait         ; пока не придёт прерывание от таймера
end

[свернуть]

Теория, как сделать программный n-канальный ШИМ

Схема подключения RGB-светодиодов к контроллеру и результаты работы программы

Скачать готовую прошивку и asm-файл

Добавить комментарий