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

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

 

 

 

 

:

Проект в Proteus будет выглядеть так

 

 

alt

Программа:

; ****************************************
; Автор:                                 *
; Дата:                                  *
; Версия:                                *
; Название файла:                        *
; Для AVR:  ATtiny2313                   *
; Тактовая частота:  8мГц                *
; ****************************************

; Выполняемые функции:  реверсивные бегущие огни

; ==================================================
; .device             ;
; .nolist             ;
; .include            ;
; .list               ;
; ===================================================
.def temp=r16         ; директива .def назначает регистру r16 имя temp
.def temp1=r17        ; директива .def назначает регистру r17 имя temp1
.def temp2=r18        ; директива .def назначает регистру r18 имя temp2
.def temp3=r19        ; директива .def назначает регистру r19 имя temp3
;====================================================
; Начало программы
.cseg                 ; директива .cseg определяет начало сегмента кодов
.org 0                ; начало первой строки программы
; ====================================================
; Инициализация стека (в AVR Studio 5 инициализируется по умолчанию)
; ldi temp,Ramend     ; определение
; out SPL, temp       ; верхушки стека
; ====================================================
ser temp              ; устанавливает все биты регистра temp  в 1
clr temp1             ; обнуляет регистр temp1
ldi temp2,0b00000001  ; записываем в temp2 число 1
out DDRB,temp         ; переводит все биты порта B на вывод
out DDRD,temp2        ; переводит все биты порта D на ввод  кроме 0 бита      
out PortB,temp1       ; отключает подтягивающие резисторы портов B
out PortD,temp2       ; отключает подтягивающие резисторы портов D кроме 0 порта
 
ldi temp,0b00000001   ; определяет рисунок бегущего огонька

Loop:
SBIC PinD,0           ; опрашивает  0 бит регистра ввода
rjmp right            ; и переходит на строку right, если 0 бит равен 1

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
rcall delay           ; вызов подпрограммы задержки
rjmp Loop            ; Возвращаемся к метке Cicle, зацикливаемся
; ====================================================
delay:    
clr temp1             ; обнулить регистр temp1
clr temp2             ; обнулить регистр temp2
ldi temp3,2           ; записать в регистр temp3 число 2

delay1:    
dec temp1             ; вычесть из значения  регистра temp1 единицу
brne delay1           ; если значение temp1 не равно 0 перейти к метке Pause1

dec temp2             ; вычесть из значения  регистра temp2 единицу
brne delay1           ; если значение temp2 не равно 0 перейти к метке Pause1

dec temp3             ; вычесть из значения  регистра temp3 единицу
brne delay1           ; если значение temp1 не равно 0 перейти к метке Pause1
ret                   ; выйти из подпрограммы

Работает программа очень просто, огонек начинает двигаться в обратную сторону, если нажать кнопку. Очень легко сформировать бегущую тень, если в строке формирования рисунка прописать все единицы и оставить один нулик. Поэкспериментируйте с разными рисунками огней.
Должно выглядеть примерно так:
“бегущий огонек”:    beg_og1.wmv (1,01МБ)
“бегущая тень”:       beg_ten1.wmv (878,09К)
“бегущая полоска”: beg_polos1.wmv (831,7К)

Программа “бегущих огней”, но написанная несколько иначе:

; ****************************************
; Автор:                                 *
; Дата:                                  *
; Версия:                                *
; Название файла:                        *
; Для AVR:  ATtiny2313                   *
; Тактовая частота:  8мГц                *
; ****************************************

; Выполняемые функции: реверсивные бегущие огни - 2

; ==================================================
; .device
; .nolist
; .include
; .list
; ===================================================
.def temp=r16         ; директива .def назначает регистру r16 имя temp
.def temp1=r17        ; директива .def назначает регистру r17 имя temp1
.def temp2=r18        ; директива .def назначает регистру r18 имя temp2
.def temp3=r19        ; директива .def назначает регистру r19 имя temp3
;====================================================
; Начало программы
.cseg                 ; директива .cseg определяет начало сегмента, где будет расположен основной код программы.
.org 0                ; начало первой строки программы
; ====================================================
; Инициализация стека
ldi temp,Ramend
out SPL, temp
; ====================================================
ser temp              ; устанавливает все биты регистра temp  в 1
clr temp1             ; обнуляет регистр temp1
ldi temp2,0b00000001  ; записываем в temp2 число 1
out DDRB,temp         ; переводит все биты порта B на вывод
out DDRD,temp2        ; переводит все биты порта D на ввод  кроме 0       
out PortB,temp1       ; отключает подтягивающие резисторы портов B
out PortD,temp2       ; отключает подтягивающие резисторы портов D кроме 0
 
ldi temp,0b11111110   ; определяет рисунок бегущего огонька

Loop:
out PortB,temp
 
SBIC PinD,0           ; опрашивеет  0 бит регистра ввода
rjmp left             

right:
clc
SBIC PinB,0           ; опрашивеет  0 бит регистра ввода     
sec
ror temp
rjmp led

left:
clc
SBIC PinB,7           ; опрашивеет  7 бит регистра ввода      
sec
rol temp

led:
rcall delay           ; вызов подпрограммы задержки
rjmp Loop             ; Возвращаемся к метке Loop, зацикливаемся
; ====================================================
delay:    
clr temp1             ; обнулить регистр temp1
clr temp2             ; обнулить регистр temp2
ldi temp3,2           ; записать в регистр temp3 число 2

delay1:    
dec temp1             ; вычесть из значения  регистра temp1 единицу
brne delay1           ; если значение temp1 не равно 0 перейти к метке Pause1

dec temp2             ; вычесть из значения  регистра temp2 единицу
brne delay1           ; если значение temp2 не равно 0 перейти к метке Pause1

dec temp3             ; вычесть из значения  регистра temp3 единицу
brne delay1           ; если значение temp1 не равно 0 перейти к метке Pause1
ret                   ; выйти из подпрограммы

В программе появились новые команды и строчки. Мы изучим их в процессе отладки.
А сейчас вернемся в IDE AVR Studio 5 и рассмотрим более подробно некоторые функции. Сначала копируем или пишем программу в редактор. Компилируем программу нажимая F7 или кликаем по среднему значку панели сборки проекта:

 

alt

 

 

Назначения клавиш слева - направо:
Сборка проекта (Build)
Сборка решения (Build Solution) F7
Отмена (Cancel)
По результатам сборки в окне Output, будет предоставлен отчет о процессе компиляции, а в Solution Explorer будут показаны файлы полученные в результате сборки. Программа создает несколько файлов .hex, .lss, .map, .obj. Файл .hex для программирования микроконтроллера, .lss содержит подробный листинг программы и отчет о компиляции, который можно изучить, если дважды кликнуть по этому файлу, .map файл показывает карту оперативной памяти и задействованные в программе регистры.

 

alt

 

Как правило, написание программы занимает меньшее время, чем сам процесс ее отладки. Поэтому сегодня рассмотрим общие принципы отладки программ.
Отладка (Debug), начинается с компиляции программы, и если обнаружены явные ошибки, в нижнем окне появляется предупреждения, которые указывают на ее место расположения.

 

alt

 

 

Отладка программы может выполняться в режимах симуляции и эмуляции.
Симуляция не требует специальных отладочных средств и проводится непосредственно в самой программе. Эмуляция предполагает подключение отладочных плат или программаторов, и позволяет наблюдать процесс отладки наглядно сразу в “железе”. Повторюсь, что для AVR Studio 5 можно самому собрать аналог STK500, весьма мощный и функциональный программатор-отладчик.
Мы будем выполнять отладку в режиме симуляции. Для управления процессом симуляции существует панель отладки (Debug Toolbar)

 

alt

Назначение кнопок панели отладки указаны в таблице

alt

 

В процессе отладки можно наблюдать за изменениями значений переменных в окне Locals

 

alt

 

Контролируя значения переменных, можно понять логику программы.
Для трассировки программы (пошаговой отладки) предназначена (AVR Debug Toolbar) – панель отладки AVR.

 

alt

 

 

Назначение кнопок панели указаны в таблице

 

alt

Мы уже пользовались опцией просмотра состояния процессора, еще раз посмотрим функции этого окна.

 

alt

 

 

Параметры состояния процессора перечислены ниже

 

alt

 

В этом окне, а так же отдельно можно посмотреть текущее состояние регистров общего назначения и 16-битные регистры X,Y,Z.

 

alt

Окно просмотра памяти позволяет наблюдать, а при необходимости и модифицировать все виды памяти.

 

alt

 

Окно дезассемблирования показывает программу на языке ассемблера. Это окно актуально для языков высокого уровня, когда нужно посмотреть, как составлена та или иная команда в кодах ассемблера.

 

alt

Для контроля и управления регистрами ввода-вывода существует окно просмотра периферии IO View

 

alt

Теперь вернемся к нашим бегущим огонькам.
Начало, в-принципе, знакомое и повторяется в предыдущих программах, появилась новая строчка:
Инициализация стека.
Что такое стек? Зачем он нужен?
Стек-это участок оперативной памяти, состоящий из нескольких ячеек, для временного хранения данных, связанных с вызовом подпрограмм.

Стек ассоциируют с разными предметами, например блинами положенными друг на друга или патронами в магазине автомата Калашникова. Суть стека такова – зашел последним - вышел первым. Чтобы съесть самый нижний блин, который был первым нужно сначала съесть верхние, которые легли позже, чтобы выстрелить патроном, который мы вставили раньше всех, нужно использовать те, которые вставили позже. Самый последний  будет использован первым.
Стек в AVR используется для хранения адресов при выходе из подпрограмм и для кратковременного хранения данных.
Для обращения к стеку (стековой памяти) существует специальный регистр – указатель стека SPH:SPL, для микроконтроллеров с большим объемом ОЗУ, и SPL для небольших объемов ОЗУ.
В AVR стековая память работает по принципу уменьшения на единицу, где верхушкой является самый последний адрес ОЗУ, у ATTINY2313 это 0х00DF. Адрес ОЗУ 0х00DF называется RAMEND (конец ОЗУ). Таким образом, стековая память заполняет ОЗУ – сверху вниз, от большего адреса к меньшему.
При включении микроконтроллера, регистр SPL обнуляется, и если не инициализировать верхушку стека, заполнения стековой памяти не происходит, возникает сбой. В AVR Studio 5 процесс инициализации стековой памяти происходит по умолчанию, поэтому строки инициализации не обязательны, но и не будет ошибкой, если мы пропишем эти стоки. Давайте проверим.
Компилируем нашу программу, где строки инициализации прописаны как комментарии. Кликнем по значку (Step into) F11.
Справа появляется окно Processor (окно состояния процессора), если окно не появилось нужно сделать, как указано во второй части.
Смотрим вторую строчку Stack Pointer (Указатель стека), где указан адрес 0X00DF, который выделен красным цветом, говорящий, что изменения в ячейке сделаны в предыдущем такте, самой программой. Попробуем изменить адрес верхушки стековой памяти. Выйдем из режима отладки, кликнув (Stop Debugging) Ctrl+Shift+F5. Отредактируем строки инициализации и вместо RAMEND запишем произвольное число большее, чем адреса регистров ввода-вывода, т.е. начиная с 0х0060, например 0х0074.
Получаем такие строки:

;====================================================
;Инициализациястека 
ldi temp,0Х0074     ;определение
out SPL, temp       ;верхушкистека 
;====================================================

Входим в режим трассировки F11, смотрим в параметрах состояния процессора строчку Stack Pointer, красной строчкой выделен адрес 0х00DF, кликнем по F11, два раза. Адрес верхушки стека стал равен 0х0074, т.е. мы инициализировали стековую память по адресу 0х0074. В режиме отладки, мы можем инициализировать любой участок ОЗУ, просто 2 раза кликнув по строчке Stack Pointer и вручную набрав нужный нам адрес.

 

alt

 

 

У стековой памяти есть еще оно полезное свойство, мы можем произвольно записать значение регистра общего назначения в стек c помощью команды push. И наоборот записать значение из стека в регистр общего назначения командой pop.
команда push – записывает значение РОН в стековую память по адресу, установленному в указателе стека, и вычитает из этого адреса единицу.
команда pop – записывает в РОН значение стековой памяти по адресу, установленному в указателе стека, и добавляет к этому адресу единицу.
Обратите внимание, что первая строка (Program Counter) стала равна 2 – это адрес программной строки, которая сейчас будет выполнена. (Program Counter) сокращенно PC – счетчик команд, это регистр в котором значение в процессе выполнения линейной программы инкрементируется, но при выполнении команд перехода значение PC может резко меняется. Для того, чтобы выполнение программы продолжить с нужной нам стоки, можно вместо метки записать выражение PC+/-N.
Например программу задержки можно записать без меток, таким образом:

dec temp1
brne PC-1

dec temp2
brne PC-3

dec temp3
brne PC-5
ret

Попробуйте переписать и убедиться, что программа работает. Можно легко перейти на любую строку программы, набрав ее в строчке Program Counter.
Итак, мы рассмотрели основные функциональные окна AVR Studio 5 и написали несколько программ. Как вы убедились программа достаточно проста по структуре и интуитивно понятна.
Для программирования микросхем рекомендую собрать аналог STK5000 по ссылке: http://ra4nal.qrz.ru/stk500.shtml
или прямо отсюда - stk500.rar (523,61К)
отлично работает и незаменим в случаях, когда неправильно прошиты фьюзы (биты конфигурации).
В последующих статьях рассмотрим внутреннюю структуру контроллеров AVR, и особенности программного управления. Акцент будет перенесен на особенности написания програм в ассемблере, уже выходя за рамки контроллера ATTINY2313, что даст вам болше возможностей для самостоятельного творчества.

                                                             (Продолжение следует)


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

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