В начало | Зарегистрироваться | Заказать наши киты почтой
 
 
 
 

Програмирование в AVR Studio 5 с самого начала. Часть 6

📆18 января 2012   ✒️galrad   🔎23.362   💬2  

Продолжим разбор теоретических основ, без которых невозможно полноценное создание программ.
Основной синтаксис AVRASM совместим с AVRASM2 с исключениями, отмеченными ниже:
• Ключевые слова
• Директивы препроцессора
• Комментарии
• Продолжения строк
• Строки и символьные константы
• Составные инструкции в строке
Ключевые слова. В отличие от AVRASM встроенные идентификаторы (ключевые слова) зарезервированы и не могут быть переопределены. Ключевые слова включают все инструкции (команды), регистры R0-R31 и X, Y, Z и все функции. Ключевые слова Ассемблер распознаёт независимо от регистра, в котором они набраны, за исключением чувствительных к регистру опций, в которых ключевые слова набираются в нижнем регистре (т.е. "add" зарезервирован, а "ADD" – нет).
Директивы препроцессора. AVRASM2 считает директивами препроцессора все строки, начинающиеся с '#' (или первый непустой символ в строке, так как пробелы и символы табуляции игнорируются).
Комментарии. Дополнительно к классическим комментариям Ассемблера, начинающимся с ';', AVRASM2 признает комментарии в Cи-стиле:
. . . . . . . . . .  ;  Остальная часть строки является комментарием.
// Подобно ';' остальная часть строки является комментарием. 
/* Блок комментариев  может располагаться в нескольких строках.
    Этот стиль комментариев не может быть вложенным */ 

Ассемблер распознает разделители комментария (';') в стиле AVRASM, а также комментарии Cи-стиля. Однако ';' используется в синтаксисе языка Cи, что может привести к конфликту при использовании ';' в качестве разделителя комментария, поэтому не рекомендуется использовать комментарии в стиле Ассемблера вместе с директивами препроцессора AVRASM2.
Продолжение строки. Подобно Cи, строки исходных кодов могут быть продолжены посредством '\ '– обратной косой черты в конце строки. Это особенно полезно для длинных макроопределений препроцессора и для длинных директив .db.
Пример:
.db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 11,12, 21, 214,235,634,  \n', 0, 2, \ 
12, 3,"’это продолжение  верхней строки", '\n', 0, 3, 0

Строки и символьные константы. AVRASM2 понимает строки и символы так же, как AVRASM, кроме того, служебные символы, которые не поддерживаются AVRASM. Строка, заключенная в двойные кавычки ("), может быть использована только вместе с директивой .db. Строка передается буквально, никакие служебные символы и NUL-окончания не распознаются. Символьные константы, заключенные в одиночные кавычки ('), могут использоваться везде, где допустимо целое выражение. Служебные символы в Cи-стиле распознаются с тем же значением, как в Cи



Ассемблером также распознаются \ooo (ooo = восьмеричное число) и \xhh (hh = шестнадцатеричное число).
Примеры:
.db "Hello\n"
 // - эквивалент:
.db 'H', 'e', 'l', 'l', 'o', '\\', 'n,

Для того чтобы создать эквивалент Cи-строки "Привет, мир \n", делают следующим образом:
.db " Hello, world", '\n', 0

Составные инструкции в строке. AVRASM2 допускает составные инструкции (команды) и директивы в строке, но их использование не рекомендовано. Это нужно для того, чтобы поддерживать распаковку (расширение) многострочных макроопределений препроцессора.
Операнды. Дополнительно к операндам AVRASM, AVRASM2 поддерживает выражения с плавающей точкой.

Ассемблер поддерживает ряд операторов, которые перечислены в таблице (чем выше положение в таблице, тем выше приоритет оператора). Выражения могут заключаться в круглые скобки, такие выражения вычисляются перед выражениями за скобками.

Операторы




Функции AVRASM

В Ассемблере определены следующие функции:
LOW (выражение) – возвращает младший байт выражения;
HIGH (выражение) – возвращает второй байт выражения;
BYTE2 (выражение) – то же, что и функция HIGH;
BYTE3 (выражение) – возвращает третий байт выражения;
BYTE4 (выражение) – возвращает четвёртый байт выражения;
LWRD (выражение) – возвращает биты 0-15 выражения;
HWRD (выражение) – возвращает биты 16-31 выражения;
PAGE (выражение) – возвращает биты 16-21 выражения;
EXP2 (выражение) – возвращает 2 в степени (выражение);
LOG2 (выражение) – возвращает целую часть log2(выражение).

Функции AVRASM2

Следующие функции определены только в AVRASM2:
INT (выражение) – преобразовывает выражение с плавающей точкой в целое (т.е. отбрасывает дробную часть);
FRAC (выражение) – выделяет дробную часть выражения с плавающей точкой (т.е. отбрасывает целую часть);
Q7 (выражение) – преобразовывает выражение с плавающей точкой в форму пригодную для инструкций FMUL/ FMULS/FMULSU (знак + 7-битовая дробная часть);
Q15 (выражение) – преобразовывает выражение с плавающей точкой в форму пригодную для инструкций FMUL/ FMULS/FMULSU (знак + 15-битовая дробная часть);
ABS ( ) – возвращает абсолютную величину постоянного выражения;
DEFINED (символ) – возвращает «истина», если символ прежде определен директивами .equ, .set или .def. Обычно используется вместе с директивами if (.if defined(foo)), но может быть использовано в любом контексте. В отличие от других функций DEFINED(символ) требует наличия круглых скобок вокруг своего аргумента.

Ассемблер AVRASM2 различает регистр символов (AVRASM не различает).

Ну, вот выложил минимум теории необходимой для программирования современных контроллеров. (Отрывки из учебного пособия по ассемблеру, автор Зубарев Александр Александрович).
Если вглядываться в последние тенденции, то видно, что ассемблер унифицируется и разные производители вынуждены “приходить к общему знаменателю”, а именно аналогии языка Си.

Снова к практике!

Чтобы быстро писать программы, программист создает свои библиотеки – небольшие микропрограммы в виде сборок - макроопределений, например микропрограммы задержки, или модули инициализации ЖКИ. Удержать в голове множество таких микропрограмм физически невозможно, тем более, что многие программисты даже не помнят все команды, от силы 40-60, а остальные берут из справочника по мере необходимости. Проще один раз написать микропрограмму и использовать в виде макроопределения при создании других программ. Макроопределению можно дать любое произвольное название так, как вам нравиться. Чтобы пользоваться готовыми макроопределениями достаточно нескольких директив. Вспомним их.

.INCLUDE вложить другой файл
Встретив директиву INCLUDE, компилятор открывает указанный в ней файл, компилирует, его пока файл не закончится или не встретится директива EXIT, после этого продолжает компиляцию начального файла со строки, следующей за директивой INCLUDE. Вложенный файл может также содержать директивы INCLUDE.

Синтаксис:
.INCLUDE "имя_файла"
Пример:
; файл iodefs.asm: 
.EQU sreg   = 0x3f      ; Регистр статуса. 
.EQU sphigh = 0x3e    ; Старший байт указателя стека. 
.EQU splow  = 0x3d    ; Младший байт указателя стека. 
; файл incdemo.asm 
.INCLUDE iodefs.asm  ; Вложить файл. 
        in r0,sreg    ; Прочитать регистр статуса.


.MACRO начало макроса
С директивы MACRO начинается определение макроса. Макрос (макроопределение) – это микропрограмма, состоящая из последовательности операторов, которые несколько раз встречаются в тексте программы. Эта последовательность операторов включается в тело макроса. Кроме этого, макрос имеет заголовок, состоящий из имени и списка параметров, и окончание. После того как макрос определен, повторяющиеся участки кода в тексте программы заменяются на его имя. Это сокращает текст программы. При встрече имени макроса позднее в тексте программы компилятор заменит его имя на операторы из тела макроса. Таким образом, исполнение макроса заключается в его «расширении».
Макрос в AVRASM может иметь до 10 параметров, к которым в его теле обращаются через @0 – @9. Макрос в AVRASM2 может иметь неограниченное число параметров.
При вызове параметры перечисляются через запятые. Определение макроса заканчивается директивой ENDMACRO.
По умолчанию в листинг включается только вызов макроса, для разворачивания макроса необходимо использовать директиву LISTMAC. Макрос в листинге показывается знаком +.
Синтаксис:
.MACRO имя_макроса
Пример:
.MACRO SUBI16            ; Начало макроопределения.
       subi @1,low(@0)  ; Вычесть младший байт параметра 0 из параметра 1.
       sbci @2,high(@0); Вычесть старший байт параметра 0 из параметра 2.
.ENDMACRO                ; Конец макроопределения.
.CSEG                              ; Начало программного сегмента.
        SUBI16 0x1234,r16,r17  ; Вычесть 0x1234 из r17:r16.


Пример:
Создадим макрос под именем write

.macro write
 ldi @0,@5
 ldi @2,@3
 ldi @4,@1
 .endm

Вызываем  макрос  и прописываем параметры
;
write r16,0x1,r17,0x2,r18,0x3
;
После выполнения макроса в регистры записываются числа
R16=3
R17=2
R18-1



.ENDM
.ENDMACRO конец макроса
Директива определяет конец макроопределения и не принимает никаких параметров. Для информации по определению макросов смотрите директиву MACRO.
Синтаксис:
.ENDMACRO
.ENDM
Пример:
.MACRO SUBI16          ; Начало определения макроса.
        subi r16,low(@0)  ; Вычесть младший байт первого параметра. 
        sbci r17,high(@0)  ; Вычесть старший байт первого параметра. 
.ENDMACRO 



.LISTMAC включить разворачивание макросов в листинге
После директивы LISTMAC компилятор будет показывать в листинге содержимое макроса. По умолчанию в листинге показываются только вызов макроса и передаваемые параметры.
Синтаксис:
.LISTMAC
Пример:
.MACRO MACX     ; Определение макроса.
        add  r0,@0      ; Тело макроса.
        eor  r1,@1 
.ENDMACRO          ; Конец макроопределения.
.LISTMAC              ; Включить разворачивание макросов. 
     MACX r2,r1; Вызов макроса (в листинге будет показано тело макроса).


Рассмотрим практический пример в нашей последней программе (бегущие огни).
Если мы зададим программе задержки макроопределение PAUSE в виде

MACRO PAUSE
dec @0
brne PC-1

dec @1
brne PC-3

dec @2
brne PC-5
.ENDMACRO


То сама программа задержки примет вид:

delay:
PAUSE temp1, temp2, temp3
ret


Но не следует забывать, что фактический объем программы не уменьшается. Написанная таким образом программа приобретает более короткий и понятный для нас вид, но во время компиляции все строки указанные в макроопределении полностью прописываются.

Ну вот, вроде как пора и к программированию возвращаться!
Директивы, операторы и функции посмотрели и запомнили.
Теперь нужно инициализировать микроконтроллер. Под инициализацией понимается активация встроенных устройств, установка векторов прерываний, подключение портов, полная очистка оперативной памяти от возможного “мусора”. Конечно - же при корректно составленной программе вроде–бы и никакой очистки не нужно, но почему-то в силу неясных причин, нередко без начальной очистки ОЗУ, контроллер виснет или начинает вести себя непредсказуемо...
Чтобы избежать этого, нам нужно очистить область стека(RAMEND), область данных ОЗУ (SRAM_START-RAMEND), область регистров общего назначения(r0–r31).

Процедуры очистки выглядят следующим образом:
Очистка Стековой памяти
ldi r16,low(RAMEND);
 out SPL,r16;
 .if (RAMEND)>=0×0100;
 ldi r16,high(RAMEND);
 out SPH,r16;
 .endif;
 .ENDM;


Очистка области данных ОЗУ
LDI    ZL,Low(SRAM_START); Адрес начала ОЗУ в индекс
LDI    ZH,High(SRAM_START)
CLR    R16          ; Очищаем R16
Flush:        
ST     Z+,R16      ; Сохраняем 0 в ячейку памяти
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  ; Зацикливаемся до полного обнуления


Все три микропрограммы можно записать как макроопределения, поместить в один отдельный файл, каждый под своим названием. Сам файл можно вызвать с помощью директивы .INCLUDE, после чего становятся доступными макроопределения.
В процессе инициализации, можно задать режим полноценного использования регистров r0-r15, так же как r16-r31. Макроопределение будет выглядеть следующим образом:

.MACRO LDIL
PUSH    R17; Сохраним значение одного из старших регистров в стек.
LDI    R17,@1; Загрузим в него наше непосредственное значение
MOV    @0,R17; Перебросим значение в регистр младшей группы. 
POP     R17  ; Восстановим из стека значение старшего регистра.
.ENDM


Теперь с помощью одной команды LDIL rX,Y
можно легко записать в регистр rX, любое 1байтное число Y,
где rX может быть r0-r15
(Не забываем, что созданная нами команда LDIL rX,Y в пять раз медленнее настоящей команды LDI и занимает объем в пять строк…)

С помощью макросов (макроопределений) можно разрешить множество неоднозначных ситуаций, связанных с адресацией, управлением устройств ввода вывода, и.т.п. создавая свою библиотеку…

Далее рассмотрим прерывания, работу встроенных таймеров,
использование ШИМ

Камрад, рассмотри датагорские рекомендации

🌼 Полезные и проверенные железяки, можно брать

Опробовано в лаборатории редакции или читателями.




 

Читательское голосование

Нравится

Статью одобрили 13 читателей.

Для участия в голосовании зарегистрируйтесь и войдите на сайт с вашими логином и паролем.
 

Поделись с друзьями!

 

 

Связанные материалы

 

Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 5... Для того чтобы писать более сложные программы, нужно хорошо представлять структуру и...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 2... Пишем первую программу!Большинство начинают с мигания светодиодов, и мы не исключение. Если...
Схема на Датагоре. Новая статья «Чёрная дыра»... Привет всем! Буду краток. Мы выпали из Сети на пару дней. У нас были серьёзные технические...
Схема на Датагоре. Новая статья Программа обмена по RS-232 на языке C# в среде Microsoft Visual Studio... Сограждане, применяющие микроконтроллеры, часто испытывают потребность использования функций...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 3... Мы научились включать и выключать светодиоды, а как сделать, чтобы они сами заморгали? Понятно,...
Схема на Датагоре. Новая статья Библиотеки для подключения COG-индикаторов TIC-55 и TIC-3321 к микроконтроллерам AVR... …простите, а вы не подскажите, как пройти в библиотеку? Небольшая предысторияПрежде, я уже имел...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 4... Сегодня рассмотрим программу “бегущих огней” и “бегущих теней”. Примеры “бегущих огней” можно...
Схема на Датагоре. Новая статья Усилитель Ural PB5.700. Ремонт... При подключении была попутана полярность. При подаче питания от ЛБП блок уходит в защиту по току...
Схема на Датагоре. Новая статья Визуализация для микроконтроллера. Часть 2. TFT дисплей 1.8" (128х160) на ST7735... Следующий из рассматриваемых нами модулей обладает полноцветным дисплеем под управлением...
Схема на Датагоре. Новая статья Трансивер 2,4 ГГц Nordic Semiconductor nRF24L01. Перевод таблиц даташита, пояснения и коды для организации сети... Wireless Transceiver Module NRF24L01+ 2.4GHz, 4 шт. на Али Привет, датагорцы! Выкладываю перевод...
Схема на Датагоре. Новая статья Stevie Wonder - I just called to say I love you... Клип и слова песни есть. Споём? No new years day To celebrate No chocolate covered candy hearts to...
Схема на Датагоре. Новая статья Грызём микроконтроллеры. Урок 2. CodeVision и С... Предлагаю продолжить изучение микроконтроллеров… Второй урок будет посвящен по большей части...
 

Комментарии, вопросы, ответы, дополнения, отзывы

 

<
Читатель Датагора

Dust112

<
Читатель Датагора

emw

Добавить комментарий, вопрос, отзыв 💬

Камрады, будьте дружелюбны, соблюдайте правила!

  • Смайлы и люди
    Животные и природа
    Еда и напитки
    Активность
    Путешествия и места
    Предметы
    Символы
    Флаги
 
 
В начало | Зарегистрироваться | Заказать наши киты почтой