Управляемый ШИМ на основе микроконтроллера 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Гц |