РадиоКот :: Шим для начинающих - аппаратный шим, практическое применение на примере Tiny13A
Например TDA7294

РадиоКот >Статьи >

Теги статьи: ШИМAVRДобавить тег

Шим для начинающих - аппаратный шим, практическое применение на примере Tiny13A

Автор: asw
Опубликовано 07.09.2011
Создано при помощи КотоРед.
2011

Поздравляю кота с Днём рождения!

                В данной статье будет рассмотрен вариант настройки аппаратного ШИМ сигнала в МК AVR Tiny13A, его применение на примере управления яркостью  светодиодной ленты (данное устройство встроено в ТФТ монитор вместо штатной подсветки).

                Часть 1. Настройка.

                Для данного устройства будем использовать таймер счётчик Т0 (он тут собственно единственный, так что выбирать не приходится).  Для регулировки яркости выберем режим Fast PWM (быстрый ШИМ). Как видно из даташита (стр.73) за это отвечают биты WGM00, WGM01, WGM02 регистров TCCR0A и TCCR0B. (Маленькое отступление: в ходе настройки было выявлено, что при записи 1 в бит WGM02, режим быстрого ШИМ с участием регистров сравнения OCR0A (OCR0B) не включается, на выходе присутствовал только сигнал высокого уровня. Поэтому была выбрана другая рабочая конфигурация. Если кто пояснит  детальнее, буду благодарен) В биты WGM00, WGM01 записываем 1. Так же в регистре TCCR0A присутствуют биты COM0A0, COM0A1 (COM0B0, COM0B1) - они отвечают за режимы работы блоков сравнения А (В) соответственно (стр. 70 даташита). Выбираем режим сброс вывода OC0A (OC0B) в 0 при равенстве регистров TCNT0 (счётный регистр) и OCR0A (OCR0B) (регистры сравнения), получается не инвертированный ШИМ, т.е. записываем 1 в бит COM0A1 (COM0B1).

(Отступление: а почему собственно, регистры сравнения, да потому, что туда записываем нужное число, какое необходимо в конкретной задаче, в данной статье это число будет менять скважность выходного сигнала нашего устройства, а следовательно и яркость линейки светодиодов)

 

В коде данная строка настройки выглядит так: outi tccr0a, 0b10100011; режим fast pwm

( outi - это макрос, т.е. маленький шаблон действий, которые часто выполняются. Как известно, операции с числами производятся через регистры общего назначения, т.е. чтобы вывести число в порт, сначала его надо записать в РОН. Вот именно это и делает данный макрос.)

Без макроса так:  ldi r16, 0b10100011

                                   out tccr0a, r16

Осталось выбрать частоту работы нашего ШИМ. Её следует выбирать в данном случае такой, чтобы не было видно мерцания светодиодной ленты. Вообще частота ШИМ в данном режиме считается по формуле из даташита, стр. 66.  У меня частота вышла 585гц. (частота МК 9,6 Мгц, делитель на 8 в программе и делитель на 8 во фьюзах) За выбор частоты предделителя в данном МК отвечает регистр TCCR0B. Биты - CS00, CS01, CS02. Записываем 1 в бит CS01, чем включаем делитель на 8. (стр. 73-74 даташита)

Код:  outi tccr0b, 0b00000010; делитель на 8
 

Теперь сконфигурируем нужные пины МК. Используя даташит, видим, что ШИМ сигнал выводится на определённые ножки МК, OC0A и OC0B, что соответствует 5й и 6й ножке МК (стр. 2 даташита)

Эти выводы нужно сконфигурировать как выходы, для этого нужно записать 1 в биты 0 и 1 регистра DDRB (В - порт МК, причём единственный здесь).  На выводах 7 и 2 расположены кнопки (кто-то скажет что это расточительно, но в данном случае выводов пока хватает, а вешать гирлянду на АЦП нет смысла, не говоря уже о регистрах сдвига и тп, хотя место позволяет), одна из них регулирует яркость, другая отвечает за включение и выключение. Эти выводы МК конфигурируем как входы с подтяжкой (подтяжку хорошо бы использовать внешнюю, например 4.7к с плюса питания на вывод МК), таким образов в биты 2 и 3 регистра DDRB записываем 0, после чего в регистр PORTB в эти же биты выводим 1.  (что-то не хочет нгормально отображаться при публикации данный кусок, в приложении есть проект, там всё нормально)

Код:   

          ldi r16, (1

             out ddrb, r16

             ldi r16, (1

             out portb, r16

 

 Часть2. Программа.

Алгоритм таков: при нажатии на кнопку регулировки, яркость изменяется от минимума до максимума и от максимума до минимума. При первом включении яркость 0. При нажатии кнопки включения выключения соответственно светодиоды гаснут или зажигаются.  После выключения питания МК запоминает текущую яркость.  Пишем программу. Вначале настройка, имена регистров по вкусу (полный текст будет приведён в конце статьи):

;ШИМ с регулировкой кнопкой и сохранением яркости в EEPROM, +принудительное включение-выключение отдельной кнопкой

;путь к файлу апноута

.include  "tn13adef.inc"

.cseg

.def counter=r25

;настройка портов, таймеров, предделителей

.MACRO outi //  Макрос отправка константы в регистр в/в     

   ldi    r16, @1         

   out    @0, r16         

.ENDMACRO

 

ldi r16,RAMEND                      ; инициализация стека

out SPL,r16 

 

ldi r17, 0                                    ;начальное значение регистров

mov r0, r17    

ldi  counter, 0                          ; начальное значение счётчика 

outi tccr0a, 0b10100011      ; режим fast pwm

outi tccr0b, 0b00000010      ; делитель на 8

outi gtccr, 0b00000001        ; сброс предделителя

rcall EEPROM_read                ; вызов функции чтения из ЕЕРROM

 

;out ocr0a, r21                        ; начальные значения скважности канала А

;out ocr0b, r21 

;mov r0, r21

out ocr0a, r0         ; начальные значения скважности канала В

out ocr0b, r0

ldi r16, (1<

out ddrb, r16

ldi r16, (1<

out portb, r16

 

 

Далее собственно сама программа. В ней мы делаем проверку на нажатие кнопок, и если какая-то из 2х нажата, то переходим к подпрограммам обработки нажатий, т.е. выполняем необходимое действие.

knopka:               

sbic pinb, 3                ; нажата ли кнопка выключения?

rjmp kn                      ; если нажата, то попадаем на строку сравнения счётчика, так мы узнаём включали мы свет или выключали

cpi counter, 1           ; сравнение счётчика с константой

breq wkl                    ; переход к подпрограмме включения

rcall wikl                    ; вызов подпрограммы выключения

kn:                              ; нажата ли кнопка регулировки яркости?

sbic pinb, 2               ; если да, то пропускаем следующую команду

rjmp knopka            ; т.е. выходим из цикла проверки нажатия кнопки
 

Далее следует блок чтения массива, т.к. значения яркости будем считывать именно оттуда. 

read:

ldi ZH, High(array*2)     ;загрузка начального адреса массива

ldi ZL, Low(array*2)

ldi r18, 0                            ;изменение адреса массива на нужный нам

add ZL, r17

adc ZH, r18

 

lpm                                    ; загрузка данных по адресу в регистр R0

out ocr0a, r0                   ; вывод значения в регистр сравнения,

out ocr0b, r0                   ; изменение скважности сигнала ШИМ

cpi r17, 116                     ; проверка достиг ли массив конца

breq  init

inc r17                             ; увеличиваем адрес элемента массива

                                          ; чтобы использовать следующий в нём элемент

rcall loop                         ; вызов подпрограммы простой програмной задержки

sbic pinb, 2                     ; если кнопка отпущена, то сделаем запись в EEPROM

rcall EEPROM_write     ; сделать запись настроек

rjmp knopka

 

Далее стоит подпрограмма принудительного выключения.

wikl:                         ;принудительное выключение подсветки

outi ocr0a, 0

outi ocr0b, 0          ;выключить свет

ldi counter, 1         ; запись 1 в счётчик, знак отличия режимов включения и отключения

pr:                            ; проверка отпущена ли кнопка

sbis pinb, 3

rjmp pr

rcall loop2               ; вызов програмной задержки

rjmp kn

Далее следуют блоки записи и чтения в энергонезависимую память, код взят из даташита и немного модернизирован под свои нужды, особого интереса не представляет, потому не буду его приводить здесь (можно ознакомиться в самой программе в конце статьи) После данных блоков идёт подпрограмма загрузки начального адреса массива значений яркости, после него подпрограммы програмных задержек. Ну и на последнем месте массив яркости. Таблица имеет 116 значений, уже адаптирована к восприятию (вроде бы дёргания не заметно при регулировке).

 

array:                 ; массив значений яркости (скважности)            

.db 0,1,2,3,4,5,6,6,7,8,9,10

.db 11,12,12,13,14,15,16,17, 19,20,21,23,24,26,28,30

.db 32,34,36,39,42,44,48,51,54,58,62,66,71,76,81,87

.db 93,100,106,114,122,130,139, 149, 159,170,182,195,208,223,238,255

.db 255,238,223,208,195,182,170,159, 149,139,130,122,114,106,100,93

.db 87,81,76,71,66,62,58,54, 51,48,44,42,39,36,34,32

.db 30,28,26,24,23,21,20,19,17,16,15,14,13,12,12,11

.db 10,9,9,8,7,6,6,5

 

Вот и вся программа, она собственно довольно примитивная, рассчитана на новичков в программировании. За код не ругайте, программистом не был никогда и сейчас им не являюсь.

Часть 3. Схема и готовое устройство.

Как было сказано выше, устройство делалось для управления подсветкой ЖК монитора. В имеющемся мониторе умер инвертор, 2 лампы и что самое нехорошее, отсутствовали ВСЕ сигналы управления инвертором, ни яркости ни выключения отключения не было. Так что решено было сделать своё. В начальной версии кнопки отключения не было, так монитор и отправился к владельцу (это было безвозмездное ремонтирование, в целях обучения). Вместо ламп были применены светодиодные ленты, 2 штуки, потребление одной ленты составило 500ма (точнее отрезков ленты определённой длины). Из этого следует, что в МК будут подключены управляющие транзисторы. Питание их осуществляется от штатного источника напряжения монитора (в моей ленте применяется параллельное соединение групп последовательно соединённых по три штуки светодиодов, это для ленты на 12 вольт, группы по 3 светодиода имеют свой ограничитель тока - резистор, потом источник тока ленте не нужен). Сама схема:

 

Печатная плата разрабатывалась для крепление на штатное место инвертора, потому в размере не стеснялся. Вид платы:

 

 

Полевые транзисторы взяты с материнской платы, N канальные. Контроллер использовался в корпусе SO8W (он пошире чем обычный SO).  Резисторы в затворах для защиты контроллера и компенсация возбуждения на высоких частотах (на печатной плате проводники от управляющей ножки МК до затвора транзистора должны быть минимальной длины). Резисторы с затвора на землю для исключения самооткрывания транзисторов. Конденсаторы на 100n обычные блокировочные, электролиты на 100мкф. Можно ещё добавить подтяжку вывода Reset к плюсу питания. Так же, если подключать светодиоды непосредственно к выводу МК, то сигнал ШИМ нужно сглаживать RC цепью. Штырьки на печатной плате сделаны для удобства внутрисхемного программирования.

Несколько фото на последок:

 

 

 

 

 

 


Файлы:
Прошивка скомпилированная
Печатная плата
Даташит
Проект в АВР студио 4.18


Все вопросы в Форум.




Как вам эта статья?

Заработало ли это устройство у вас?

23 0 0
3 0 0

Эти статьи вам тоже могут пригодиться: