Управляемый ШИМ на основе микроконтроллера AT90S1200
      При проектировании и создании данного устройства преследовалась цель создать простой, надежный, а главное универсальный цифровой регулятор на основе самого дешового МК AVR фирмы Atmel - AT90S1200.
      Устройство получилось действительно простым, как по части электроники, так и по части програмного обеспечения. А гибкость программы данного ШИМ регулятора разрешает использовать его для управления любыми устройствами.
      И так, перейдем к аппаратной части устройства (Рис.1). Ядром всего устройства является МК AT90S1200. Его ресурсов более чем хватает для организации ШИМа.
      К выводам 12,13 и 14 подключается клавиатура из трех кнопок (“On/Off”,”+”,”-“).
      К выводу 16 подключается светодиод, который показывает режим работы ШИМа.
      Вывод 15, собствено и является выходом ШИМа.

.INCLUDE "1200def.inc"
;==============================================================
;Программа управляемого ШИМа для AT90S1200
;==============================================================
.ORG 000 ;Вектор сброса
rjmp reset
.ORG 002 ;Вектор прерывания по переполнению таймера
inc r27 ;Додаем единицу к регистру r27
sbrc r27,0 ;Проверяем на четность младший бит r27
rjmp pause ;Если четный то пауза
sbrs r27,0 ;Проверяем на четность младший бит r27
rjmp impulse ;Если не четный то импульс
pause:
cbi portb,3 ;Устанавливаем на выводе PB3 логический 0
out tcnt0,r28 ;Загружаем таймер длительностю логической 1
rjmp exit_timer ;Идем на выход из прерывания
impulse:
sbi portb,3 ;Устанавливаем на выводе PB3 логический 1
out tcnt0,r29 ;Загружаем таймер длительностю логического 0
rjmp exit_timer ;Идем на выход из прерывания
exit_timer:
reti ;Выход из процедуры припывания
reset:
ldi r31,$18 ;настраиваем порт В
out ddrb,r31 ;PB0,PB1,PB2--как входы,а PB3,PB4--как выходы
ldi r28,$99 ;Задаем начальную длительность импульса
ldi r29,$66 ;Задаем начальную длительность паузы
ldi r31,$17 ;Включаем подтягивающие резисторы
out portb,r31 ;к входам PB0,PB1,PB2
ldi r31,$01 ;Настраиваем роботу таймера
out tccr0,r31 ;Тактировка от частоти генратора МК без делителя
ldi r31,$02
out timsk,r31 ;Розрешение прерывания от таймера
stop:
cbi portb,4 ;Сбрасываем вывод PB4 в ноль чем зажыгаем светодиод
ldi r27,$0
rjmp scan1 ;Отправляемся на сканирование клавиатуры
scan1:
sbis pinb,0 ;Если нажата кнопка ON/OFF(PD0)
rjmp start ;то идем на старт
sbis pinb,1 ;Если нажата кнопка "+"(PD1)
rjmp start ;то идем на старт
sbis pinb,2 ;Если нажата кнопка "-"(PD2)
rjmp start ;то идем на старт
rjmp scan1 ;Если ничего не нажато то повторяем цыкл сканирования клавиатуры заново
start:
sbi portb,4 ;Устанавливаем лог.1 на выводе PB4 чем гасим светодиод
sbi portb,3 ;Устанавливаем лог. 1 на выходе ШИМ (PB3)
out tcnt0,r29 ;Загружаем в таймер счечик начальное значение длины импульса ШИМа
sei ;Разрешаем прерывания
rcall pause_scan ;Вызываем подпрогаму задержки
rjmp scan2 ;Переходим на сканирование клавиатуры
scan2:
sbis pinb,0 ;Если нажата кнопка ON/OFF(PD0)
rjmp off ;то переходим на на часть програмы выключение
sbis pinb,1 ;Если нажата кнопка "+"(PD1)
rjmp plus ;то переходим на часть програмы увеличения значения ШИМ
sbis pinb,2 ;Если нажата кнопка "-"(PD2)
rjmp minus ;то переходим на часть програмы уменьшения значения ШИМ
rjmp scan2 ;Если нечего не нажато то повторяем цыкл сканирования клавиатуры заново
off:
cli ;Запрещаем все прирывания и от таймера в том числе
cbi portb,3 ;Устанавливаем на выходе ШИМа (PB3) лог. 0
rcall pause_scan ;Вызываем подпрограму задержки сканирования клавиатуры
rjmp stop ;Идем в начало програми на метку stop
plus:
ldi r26,$ff ;Задаем максимальное значение ШИМ
cpse r26,r28 ;Проверяем не максимальное ли значение
rjmp plus1 ;если нет то идем на часть програмы увеличения значения ШИМ
rjmp scan2 ;если максимальное значение то идем назад на сканирование кнопок
minus:
ldi r26,$33 ;Задаем минимальное значение ШИМа
cpse r26,r28 ;Проверяем ни минимальное ли значение
rjmp minus1 ;если нет то идем на часть програмы уменьшения значения ШИМа
rjmp scan2 ;Если же значение минимальное то возвращаемся на цыкл сканирования клавиатуры
plus1:
ldi r26,$33 ;Задаем дискретность ШИМа тоесть значение на которое будет увеличиватся или уменшатся значение ШИМ
add r28,r26 ;Увеличиваем длительность импульса
sub r29,r26 ;Уменьшаем значение паузы
rcall pause_scan ;Вызываем подпрограму задержки
rjmp scan2 ;Возвращаемся назад на сканирование клавиатуры
minus1:
ldi r26,$33 ;Задаем дискретность ШИМа тоесть значение на которое будет увеличиватся или уменшатся значение ШИМ
add r29,r26 ;Увеличиваем длительность паузы ШИМа
sub r28,r26 ;Уменьшаем длительность импульса ШИМа
rcall pause_scan ;Вызываем подпрограму задержки
rjmp scan2 ;Возвращаемся назад на сканирование клавиатуры
;==============================================================
;Подпрограма задержки.Основная задача етой подпрограмы защита от дребезга контактов кнопок а также задает интервал с которым будет действовать автоповтор при удержании кнопки.
;==============================================================
pause_scan:
ldi r25,3
D100_3: clr r24 ;Обнуляем регистр
D100_2: clr r23 ;Обнуляем регистр
D100_1: dec r23 ;Отнимаем единицу от значения даного регистра
brne D100_1 ;Проверяем условие перехода
dec r24 ;Отнимаем единицу от значения даного регистра
brne D100_2 ;Проверяем условие перехода
dec R25 ;Отнимаем единицу от значения даного регистра
brne D100_3 ;Проверяем условие перехода
ret ;выходим из подпрограмы
.EXIT
.INCLUDE "1200def.inc"
.ORG 000
rjmp reset
.ORG 002
inc r27
sbrc r27,0
rjmp pause
sbrs r27,0
rjmp impulse
pause:
cbi portb,3
out tcnt0,r28
rjmp exit_timer
impulse:
sbi portb,3
out tcnt0,r29
rjmp exit_timer
exit_timer:
reti
reset:
ldi r31,$18
out ddrb,r31
ldi r28,$c3
ldi r29,$3c
ldi r31,$17
out portb,r31
ldi r31,$01
out tccr0,r31
ldi r31,$02
out timsk,r31
stop:
cbi portb,4
ldi r27,$0
rjmp scan1
scan1:
sbis pinb,0
rjmp start
sbis pinb,1
rjmp start
sbis pinb,2
rjmp start
rjmp scan1
start:
sbi portb,4
sbi portb,3
out tcnt0,r29
sei
rcall pause_scan
rjmp scan2
scan2:
sbis pinb,0
rjmp off
sbis pinb,1
rjmp plus
sbis pinb,2
rjmp minus
rjmp scan2
off:
cli
cbi portb,3
rcall pause_scan
rjmp stop
plus:
ldi r26,$ff
cpse r26,r28
rjmp plus1
rjmp scan2
minus:
ldi r26,$f
cpse r26,r28
rjmp minus1
rjmp scan2
plus1:
ldi r26,$a
add r28,r26
sub r29,r26
rcall pause_scan
rjmp scan2
minus1:
ldi r26,$a
add r29,r26
sub r28,r26
rcall pause_scan
rjmp scan2
pause_scan:
ldi R25,2
D100_3: clr r24
D100_2: clr r23
D100_1: dec r23
brne D100_1
dec r24
brne D100_2
dec R25
brne D100_3
ret
.EXIT
Частота резонатора |
Частота ШИМ |
455КГц |
6930Гц |
2МГц |
7140Гц |
5,12МГц |
18000Гц |
8МГц |
28400Гц |
14,318МГц |
51000Гц |