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

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

 

; ****************************************
; Автор:                                 *
; Дата:                                  *
; Версия:                                *
; Название файла:                        *
; Для AVR:  ATtiny2313                   *
; Тактовая частота:  8мГц                *
; ****************************************
; Выполняемые функции:  Реверсивные бегущие огни с задержкой от встроенного таймера
; в режиме сравнения, с управлением от 2-х кнопок по  внешним прерываниям INT1 и INT0
; ==================================================
      ; .device                          ;
      ; .nolist                          ;
      ; .include                         ; Присоединение файла описаний
      ; .list                            ; Включение листинга

; =================================================== Псевдокоманды управления
       .def     temp = r16               ; Определение основного рабочего регистра temp
       .def     temp1 = r17              ; Определение дополнительного рабочего регистра temp1
       .def     temp2 = r18              ; Определение дополнительного рабочего регистра temp2
       .def     temp3 = r19              ; Определение дополнительного рабочего регистра temp4
       .equ     time = 3024              ; Присвоение перменой time значения 3024 (время задержки)

; =================================================== Начало программного кода
            .cseg                        ; Выбор сегмента программного кода
            .org    0                    ; Установка текущего адреса на ноль

; =================================================== Векторы прерываний
        rjmp    init                     ; Переход на начало программы
                rjmp    INT_0
                rjmp    INT_1
                reti                     ; Прерывание по захвату таймера T1
                rjmp    pr_tim           ; Прерывание по совпадению T1
                reti                     ; Прерывание по переполнению T1
                reti                     ; Прерывание по переполнению T0
                reti                     ; Прерывание UART прием завершен
                reti                     ; Прерывание UART регистр данных пуст
                reti                     ; Прерывание UART передача завершена
                reti                     ; Прерывание по компаратору
                reti                     ; Прерывание по изменению на любом контакте
                reti                     ; Таймер/счетчик 1. Совпадение B
                reti                     ; Таймер/счетчик 0. Совпадение B
                reti                     ; Таймер/счетчик 0. Совпадение A
                reti                     ; USI Стартовая готовность
                reti                     ; USI Переполнение
                reti                     ; EEPROM Готовность
                reti                     ; Переполнение сторожевого таймера

; =================================================== Начало программы
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
                ldi     temp, 0                   ; Обнуляем регистр temp
                out     CLKPR, temp               ; Деление  тактовой частоты  в регистре CLKPR равно 1

; =================================================== Инициализация портов
                ser     temp                      ; устанавливает все биты регистра temp  в 1
                clr     temp1                     ; обнуляет регистр temp1 - все биты регистра temp1 в 0
                ldi     temp2,(1< 
                out     DDRB,temp                 ; переводит все биты порта B на вывод 
                out     DDRD,temp1                ; перевод битов PD3 и PD2 на ввод     
                out     PortB,temp1               ; отключает подтягивающие резисторы портов B
                out     PortD,temp2               ; подключение подтягивающих резисторов на PD3 и PD2

; =================================================== Инициализация таймера T1
                ldi     temp,(1<                  
                out     TCCR1B, temp 
                ldi     temp, high(time)          ; Старший полубайт кода совпадения
                out     OCR1AH, temp              ; Запись в регистр совпадения старш.
                ldi     temp, low(time)           ; Младший полубайт кода совпадения
                out     OCR1AL, temp              ; Запись в регистр совпадения младш.

; =================================================== Запись в регистр маски прерываний
                ldi     temp,(1<
                out     TIMSK, temp

; =================================================== Инициализация прерываний
                ldi     temp,(1

 

                out     GIMSK,temp                ; инициализация внешних входов INT1 и INT0
                ldi     temp,(1< 
                out     MCUCR,temp                ; инициализация прерываний по спадающему фронту входного сигнала
                SEI                               ; разрешение прерываний
; =================================================== Рисунок бегущего огонька

                ldi     temp, 0b10000000          ; Запись начального значения
; =================================================== Глобальное разрешение прерываний и зацикливание

                sei                               ; Разрешение прерываний
Loop:           rjmp    Loop                      ; Пустой бесконечный цикл
; =================================================== Подпрограмма обработки прерываний таймера

pr_tim:
                SBRC    temp3,0                   ; если 0 бит регистра temp4 равен 1,
                rjmp    left                      ; то переход на метку left
                SBRC    temp3,1                   ; если 1 бит регистра temp4 равен 1,
                rjmp    right                     ; то переход на метку right

left:           rol     temp                      ; циклический сдвиг влево через флаг C
                brcc    led                       ; если перенос очищен, то перейти на метку led
                ldi     temp1,0b00000001          ; если C=1, то записываем
                add     temp, temp1               ; в 0 бит единицу
                rjmp    led                       ; и переходим на метку led

right:          ror     temp                      ; циклический сдвиг вправо через флаг C
                brcc    led                       ; если перенос очищен, то перейти на метку led
                ldi     temp1,0b10000000          ; если C=1, то записываем   
                add     temp, temp1               ; в 7 бит единицу

led:            out     PortB,temp                ; вывод в порт D значения регистра temp
                reti
; =================================================== Подпрограммы прерываний кнопок

INT_0:
                ldi temp3,1                       ; Запись состояния кнопки PD2
                reti

INT_1:
                ldi temp3,2                       ; Запись состояния конпки PD3
                reti
В этой программе мы добавили еще одну кнопку, нажатие на которую позволяет менять направление огонька. Направление меняется по прерыванию от внешнего сигнала (от кнопок). В практических конструкциях обычно так не делают, но демонстрация внешних прерываний представлена весьма наглядно.

 

Схема в протеусе будет выглядеть как на рисунке:

 

alt


Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

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