.device ATtiny24 .nolist .include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\tn24def.inc" .list ;при программировании фузов выбираем работу контроллера от внешнего кварцевого резонатора с частотой больше ;8МГц, без деления на 8, включаем BOD на напряжение 4,3В ;определяем 5 регистров: .def temp =r16 ;определение регистра временного хранения .def sost =r17 ;определение регистра состояния системы ;бит 0 - система в режиме переключения выходного напряжения .def cntr =r18 ;определение счетчика времени переключения выходного напряжения .def datl =r19 ;определение младшего регистра данных АЦП .def dath =r20 ;определение старшего регистра данных АЦП ;таймер 0 будет работать режиме normal и отсчитывать временные интервалы. тактировать его будем с делителем 1024. ;при тактовой контроллера 20Мгц переполнение будет наступать каждые 50нс*1024*256=13,1мс. ;по этому прерыванию будем опрашивать кнопку, читать АЦП, корректировать регистр совпадения таймера 1 ;и инкрементировать счетчик времени cntr, если контроллер перешел в режим изменения напряжения ;таймер 1 будет работать в решиме 9-битного fastPWM и генерировать на выводе PA6 (OC1A) сигнал ШИМ для ;преобразователя частотой 39кГц. при этом рабочим диапазоном будут только младшие 8 бит, таким образом ;коэффициент заполнения ШИМ ограничим 50%, а диапазон выходных напряжений примерно 900-1800В ;таким образом в таблицу векторов прерываний записываем 2 вектора: rjmp init ;переход на начальную инициализацию reti reti reti reti reti reti reti reti reti reti rjmp ovf ;переход на подпрограмму обработки прерывания по переполнению таймера 0 ;инициализация: init: clr sost ;на всякий случай сбрасываем рабочие регистры clr cntr ldi temp,low(RAMEND) ;определяем указатель стека out SPL,temp ldi temp,0b00000000 ;включаем таймер 0 в режим normal с делением на 1024 out TCCR0A,temp ldi temp,0b00000101 out TCCR0B,temp ldi temp,0b10000010 ;включаем таймер 1 в режим 9-битный ШИМ на вывод OC1A out TCCR1A,temp ldi temp,0b00001001 ;частота таймера 1 равна тактовой частоте out TCCR1B,temp clr temp out TCCR1C,temp ;обнуляем регистр out OCR1AL,temp ;обнуляем младший байт регистра сравнения ШИМ out OCR1AH,temp ;обнуляем старший байт регистра сравнения ШИМ ldi temp,0b11000000 ;определяем PA6,PA7 как выходы, а остальные как входы out DDRA,temp ldi temp,0b10000000 ;PA7 устанавливаем в 1, PA6 - в 0, входы не подтягиваем out PortA,temp ldi temp,0b00000000 ;определяем порт B как входы out DDRB,temp ldi temp,0b00000100 ;подтяжка PB2 к питанию (кнопка) out PortB,temp ldi temp,0b11100111 ;разрешаем АЦ-преобразование с коэфф. деления 128 - это примерно 156кГц out ADCSRA,temp ldi temp,0b00000000 ;режим непрерывного преобразования out ADCSRB,temp ldi temp,0b01000001 ;внешний ИОН,АЦП подключен к входу ADC1(PA1) out ADMUX,temp ldi temp,0b00000001 ;разрешаем прерывания от таймера 0 по переполнению out TIMSK0,temp sei ;общее разрешение прерываний ;контроллер проинициализировали, теперь он непрерывно оцифровывает вход ADC1, считает интервалы и формирует ШИМ ;по выходу OC1A. но пока на этом выводе нет ничего, т.к. в регистры сравнения мы записали нули. основная программа ;крутится в цикле: cicle: rjmp cicle ;при возникновении прерывания от таймера 0 мы попадаем сюда. пока попробуем просто сформировать на выходе ;преобразователя фиксированное стабилизированное напряжение: ovf: wdr ;сбрасываем сторожевой таймер in datl,ADCL ;читаем младший байт результата АЦП in dath,ADCH ;читаем старший байт результата АЦП in temp,OCR1AL ;читаем текущее значение регистра сравнения ШИМ ;делитель на схеме сделан так, чтобы диапазон выходных напряжений преобразователя 900-1800В попадал в диапазон ;напряжений на входе АЦП 0-2,5В. при этом опорное у нас 5В, следовательно нас интересуют младшие 9 бит ;результата преобразования, а для простоты будем рассматривать данные с 1 по 8 бит (отбросим 0 и 9): lsr dath ;сдвигаем старший байт результата вправо ror datl ;сдвигаем младший байт результата вправо с учетом предыдущего переноса tst dath ;если старший байт не нулевой, то напряжение меньше 900В brne M1 ;и мы переходим на метку М1 (увеличиваем коэффициент заполнения) cpi datl,250 ;если старший байт нулевой, то сравниваем младший байт с уставкой ;меняя это значение от 0 до 255, после прошивки контроллера мы должны получить на выходе преобразователя ;фиксированное и стабилизированное выходное напряжение 900-1800В. зависимость обратная. пульсации должны составить ;+-7В. brsh M1 ;если результат больше уставки или равен ей, то также переходим на М1 tst temp ;если результат меньше уставки, то проверяем значение регистра ШИМ на ноль breq M2 ;если ноль, то переходим на М2 dec temp ;иначе уменьшаем значение регистра ШИМ (уменьшаем напряжение) rjmp M2 ;и также переходим на М2 M1: cpi temp,255 ;проверяем значение регистра ШИМ на максимум breq M2 ;если максимум, то переходим на М2 inc temp ;иначе увеличиваем значение регистра ШИМ (увеличиваем напряжение) M2: out OCR1AL,temp ;полученное значение записываем в регистр reti ;и выходим из прерывания