Программирование c нуля в AVRStudio 5 (ч.10)

Автор: Радик Просмотров: 7105

 

 

;****************************************************************************************************************

; Автор:
; Дата:
; Версия:
; Название файла:
; Для 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-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru