.
; Автор:
; Дата:
; Версия:
; Название файла:
; Для AVR: ATtiny2313
; Тактовая частота: 8МГц
; ***************************************************************************************************************
; Выполняемые функции: Инициалицация ШИМ, управление двумя кнопками
; ==================================================
; .device ;
; .nolist ;
; .include ; Присоединение файла описаний
; .list ; Включение листинга
; =================================================== Псевдокоманды управления
.def temp = r16 ; Определение основного рабочего регистра temp
.def temp1 = r17 ; Определение дополнительного рабочего регистра temp1
.def temp2 = r18 ; Определение дополнительного рабочего регистра temp2
.def temp3 = r19 ; Определение дополнительного рабочего регистра temp4
.def temp4 = r20
.def temp5 = r21
.def temp6 = r22
.equ time = 9 ; Присвоение перменой time
; ================================================== Начало программного кода
.cseg ; Выбор сегмента программного кода
.org 0 ; Установка текущего адреса на ноль
; =================================================== Начало программы
init:
; =================================================== Инициализация стека
ldi temp,low(RAMEND) ; Устанавливаем младший бит из значения RAMEND прописанного по
out SPL,temp ; умолчанию в файле tn2313def.inc
.if (RAMEND)>=0x0100 ; Если значение опреративной памяти превышает число 256 то,
ldi temp,high(RAMEND) ; Устанавливаем старший бит из значения RAMEND прописанного по
out SPH,temp ; умолчанию в файле tn2313def.inc
.endif ; Конец условия
; =================================================== Инициализация Оперативной памяти
ldi ZL,low(SRAM_START) ; Устанавливаем адрес начала ОЗУ прописанного по
ldi ZH,high(SRAM_START) ; умолчанию в файле tn2313def.inc
clr temp ; Очищаем r16
flush:
st Z+,temp ; Обнуляем ячейку памяти
cpi ZH,high(RAMEND+1) ; Если не достигли конца старшего байта оперативной памяти
brne flush ; то продолжаем обнулять
cpi ZL,low(RAMEND+1) ; Если не достигли конца младшего байта оперативной памяти
brne flush ; то продолжаем обнулять
clr ZL ; Очищаем индексы младшего
clr ZH ; и старшего байтов памяти
; =================================================== Инициализация регистров общего назначения
ldi ZL, 30 ; Адрес самого старшего регистра
clr ZH ; Обнуляем
dec ZL ; Уменьшаем адрес на единицу
st Z, ZH ; Записываем в регистр 0
brne PC-2 ; Зацикливаемся до полного обнуления
; =================================================== Инициализация Главного предделителя
ldi temp,(1<
out CLKPR, temp ; регистр CLKPR
clr temp ; Обнуляем регистр temp
out CLKPR, temp ; Деление тактовой частоты в регистре CLKPR равно 1
; =================================================== Инициализация портов
ldi temp, (1<
out PortD,temp ; отключает подтягивающие резисторы портов D
com temp
out DDRD,temp ; переводит все биты порта D на вывод
ser temp
out DDRB,temp
clr temp
out PortB, temp
; =================================================== Инициализация таймера T0
ldi temp,(1
; =================================================== Определение скважности ШИМ
ldi temp2, time
Correct:
out OCR0A, temp2
; =================================================== Начало основной программы
Sensor: ; Опрос кнопок
SBIS PinD,0 ; опрашивает 0 бит регистра ввода
ldi temp4,0b00000001 ; и записывает в temp4 значение 1, если 0 бит равен 0 (при нажатии)
SBIS PinD,1 ; опрашивает 1 бит регистра ввода
ldi temp4,0b00000010 ; и записывает в в temp4 значение 2, если 1 бит равен 0 (при нажатии)
SBRC temp4,0 ; если 0 бит регистра temp4 равен 1,
rjmp plus ; то переход на метку plus
SBRC temp4,1 ; если 1 бит регистра temp4 равен 1,
rjmp minus ; то переход на метку minus
rjmp Sensor
; =================================================== Расчет шага ШИМ
plus:
rcall delay ; Переход в подпрограмму задержки
ldi temp, 121 ; Проверяем, нет ли переполнения при
add temp2, temp ; следующем шаге
brcs plus_1 ; Если переполнение есть, то переходим на метку plus_1
ldi temp, 112 ; Если переполнения нет, смещаемся на
sub temp2, temp ; один шаг вперед, равный заданному шагу скважности
rjmp Correct ; Возврат на опрос кнопок
plus_1:
ldi temp2,135 ; Записываем конечное положение шага
rjmp Correct ; Возват на опрос кнопок
minus:
rcall delay ; Переход в подпрограмму задержки
ldi temp, 10 ; Проверяем, нет ли переполнения (результат меньше нуля) при
sub temp2, temp ; следующем шаге
brcs minus_1 ; Если переполнение есть, то переходим на метку minus_1
inc temp2 ; Если переполнения нет, смещаемся на
rjmp Correct ; один шаг назад, равный заданному шагу скважности
minus_1:
ldi temp2, 9 ; Записываем начальное положение шага
rjmp Correct ; Возврат на опрос кнопок
; =================================================== Программная задержка
delay:
clr temp4 ; обнулить регистр temp1
clr temp5 ; обнулить регистр temp2
ldi temp6,1 ; записать в регистр temp3 число 1
delay1:
dec temp4 ; вычесть из значения регистра temp1 единицу
brne delay1 ; если значение temp1 не равно 0 перейти к метке Pause1
dec temp5 ; вычесть из значения регистра temp2 единицу
brne delay1 ; если значение temp2 не равно 0 перейти к метке Pause1
dec temp6 ; вычесть из значения регистра temp3 единицу
brne delay1 ; если значение temp1 не равно 0 перейти к метке Pause1
ret ; выйти из подпрограммы
;Не будем сильно изощряться, а используем предыдущие программы как шаблоны, а для наглядности подключим две кнопк;и для управления скважностью сигнала и светодиод в качестве нагрузки. Составим схему в протеусе и после компиляц;ии немного понажимаем на кнопки. На осциллограмме хорошо видно, как меняется скважность сигнала, соответственно ;меняется напряжение на выходе, и светодиод плавно гаснет и загорается.
; Опрос кнопок идентичен предыдущей программе и в разьясении, я думаю не нуждается.
; Инициализация ШИМ:
ldi temp,(1< out TCCR0A, temp
ldi temp, (1<
out TCCR0B, temp
; =================================================== Определение скважности ШИМ
ldi temp2, time ; Запись начальной константы
Correct:
out OCR0A, temp2 ; Скважность ШИМ
;Участок программы формирования шага ШИМ построен по принципу определения переполнения, т.е. мы прибавляем (вычит;аем)по какой то константе до тех пор, пока не произойдет переполнение. Можно сделать шаг равный 1, правда пересч;ет будет идти дольше, и будет равен 254 шагам.
.equ time = 1 ; Присвоение перменой time
plus:
rcall delay ; Переход в подпрограмму задержки
ldi temp, 2 ; Проверяем, нет ли переполнения при
add temp2, temp ; следующем шаге
brcs plus_1 ; Если переполнение есть, то переходим на метку plus_1
ldi temp, 1 ; Если переполнения нет, смещаемся на
sub temp2, temp ; один шаг вперед, равный заданному шагу скважности
rjmp Correct ; Возват на опрос кнопок
plus_1:
ldi temp2,254 ; Записываем конечное положение шага
rjmp Correct ; Возврат на опрос кнопок
minus:
rcall delay ; Переход в подпрограмму задержки
ldi temp, 2 ; Проверяем, нет ли переполнения (результат меньше нуля) при
sub temp2, temp ; следующем шаге
brcs minus_1 ; Если переполнение есть, то переходим на метку minus_1
inc temp2 ; Если переполнения нет, смещаемся на
rjmp Correct ; один шаг назад, равный заданному шагу скважности
minus_1:
ldi temp2, 1 ; Записываем начальное положение шага
rjmp Correct ; Возврат на опрос кнопок
;Или более простой вариант:
plus:
rcall delay ; Переход в подпрограмму задержки
clz ; Очистить флаг нуля
inc temp2 ; Переходим на один шаг и проверяем, не равен ли результат нулю
breq plus_1 ; Если равен, то переходим на метку plus_1
rjmp Correct ; Возват на опрос кнопок
plus_1:
dec temp2 ; вычитаем единицу
rjmp Correct ; Возврат на опрос кнопок
minus:
rcall delay ; Переход в подпрограмму задержки
clz ; Очистить флаг нуля
dec temp2 ; Переходим на один шаг и проверяем, не равен ли результат нулю
breq minus_1 ; Если равен, то переходим на метку minus_1
rjmp Correct ; Возврат на опрос кнопок
minus_1:
inc temp2 ; прибавить единицу
rjmp Correct ; Возврат на опрос кнопок
Начальное значение скважности задается строкой в начале программы:
.equ time = 9 ; Присвоение перменой time
Программную задержку можете заменить задержкой от встроенного таймера Т1, взяв из предыдущих примеров. Если Вы собираетесь использовать другие семейства, например Mega, то внимательно изучите регистры и назначение их битов. Вы убедитесь, что разница совсем небольшая, а принципы остаются общими. Даже если Вы начнете изучать ARM, быстро убедитесь, что общие принципы сохраняются.
Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2021 © ChipMK.ru
![]() |
|