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

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

📆24 декабря 2011   ✒️galrad   🔎21.616   💬8  

Для того чтобы писать более сложные программы, нужно хорошо представлять структуру и взаимодействие разных узлов микроконтроллера между собой, но основные принципы сохраняются независимо от модели контроллера. В принципе человек, который изучил микроконтроллеры PIC, достаточно быстро осваивает AVR или ARM.
Управление микроконтроллером осуществляется изменением логического уровня ячеек (битов) в регистрах, расположенных в оперативной памяти. Конкретному устройству соответствует конкретный регистр, как правило 8-битный (1 байтный), состоящий из 8 ячеек памяти. В любую ячейку можно записать 0 или 1.
Создадим произвольную таблицу, где каждая строка состоит из 8 ячеек и имеет свой порядковый номер, соответствующий одному регистру. Пусть наша таблица состоит из 128 ячеек или из 16 восьмибитных регистров.

В микроконтроллере есть разные функциональные устройства – это порты, таймеры, АЦП, устройства ШИМ, устройства последовательного приема и передачи данных, и много еще чего. Кроме этого функции конкретного устройства могут меняться, например, сначала принять информацию, а затем переключиться на передачу. Как же они работают? Все проще, чем кажется! Функции определенного устройства жестко привязывается к конкретным ячейкам памяти. Например, если нам нужно на какую-то ножку подать напряжение, мы устанавливаем конкретную ячейку в 1.

Пусть, к примеру, за вывод положительного напряжения на 4 ножку отвечает ячейка 9h:3h. Значит, если мы пропишем в ячейку 9h:3h единицу, то на 4- ой ножке получим положительное напряжение. А как мы узнаем, что эта ячейка отвечает за эту функцию? Ячеек много и запомнить номер каждой ячейки очень сложно.

Чтобы было легко работать, производители присвоили каждой строке с определенным порядковым номером, называемым адресом, свое имя, соответствующее устройству. Пусть у нас строка 9h, будет называться регистром PortB, строка 8h регистром PinB, а строка 7h регистром DdrB. Таким образом 7h, 8h, 9h – это адреса регистров с названиями PortB, PinB, DdrB.
Соответствующие регистры указываются в специальном файле с расширением .inc, в самом начале программы. Этот файл становится доступным с помощью директивы .include
Например для attiny2313:
.include "at2313def.inc"


Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.

В Ассемблере версии 2.1.9 директивы начинаются с точки, также как и директивы AVRASM.
Директивы не транслируются непосредственно в машинный код. Они используются для указания компилятору положения кода в программной памяти, для инициализации памяти и для других целей.

.CSEGSIZE – размер памяти программ
Устройства AT94K имеют раздел памяти, которую пользователь может присоединить к памяти программ AVR или памяти данных. Программа и данные SRAM подразделены на три блока: 10K x 16 память программ, 4K x 8 память данных и 6K x 16 или 12K x 8 перестраиваемой SRAM, которые могут быть распределены между программной памятью (до 4-х разделов по 2K x 16) и памятью данных (до 8-ми разделов по 4Kx8).
Эта директива используется, чтобы определять размер программного блока памяти.
Синтаксис:
.CSEGSIZE = 10 | 12 | 14 | 16

Пример:
.CSEGSIZE = 12      ; Определить размер памяти программ как 12K x 16. 


.DD – определяет двойное слово(а) в памяти программ и EEPROM.
.DQ – определяет четверное слово(а) в памяти программ и EEPROM.
Эти директивы подобно директиве .DW определяют нужное количест-во слов 32-битных (двойные слова) и 64-битных (четверные слова) соот-ветственно.

Синтаксис:
МЕТКА: .DD список  выражений
МЕТКА: .DQ список  выражений

Пример:
.CSEG 
varlist:  .DD 0, 0xfadebabe, -2147483648,  1 << 30
.ESEG 
eevarlst: .DQ 0,0xfadebabedeadbeef, 1 << 62 


#define – определить макрос препроцессора
Синтаксис:
1) #define имя [value]
2) #define имя(arg.,...) [value]

Описание:
Определяет макрос препроцессора. Есть две формы макроса: (1) – объект, который в основном определяет константу, и (2) – функция, в которую делают подстановку параметра.
Value – величина (значение) может быть любой строкой, она не определена, пока макрос не будет распакован (расширен). Если величина не определена, она = 1.
Форма (1) макроса может быть определена из командной строки использованием опции -D.
Когда использована форма (2), макрос должен вызываться с тем же количеством аргументов, с которыми он определен. Любые arg. и value будут заменены соответствующими аргументами и значениями, когда макрос расширяется. Отметьте, что левые скобки должны идти сразу после имени (никаких пробелов между ними), в противном случае это будет интерпретировано как часть величины макроса формы (1).
Примеры:
Обратите внимание на размещение первой скобки '(' в примерах, приведенных ниже.
#define EIGHT (1 << 3)
#define SQR(X) ((X)*(X))

.UNDEF – отменить определение символьного имени регистра
Описание:
Отмена определения имени, которое прежде определялось директивой .DEF или #define. Это позволит избежать сообщений об ошибке при многократном использовании регистра. Если имя прежде не определено, директива .undef будет проигнорирована, это в соответствии со стандартом ANSI C. То же можно сделать из командной строки, используя опцию -U.
Синтаксис:
.UNDEF символ
Пример:
.DEF var1 = R16 
ldi var1, 0x20
...; сделает что-то с использованием var1.
.UNDEF var1
.DEF var2 = R16; теперь использование R16 не будет вызывать предупреж-дения.


#ifdef или .IFDEF – директива условной компиляции
Синтаксис:
#ifdef имя
Описание:
Сокращение от #if defined. Все следующие строки до соответствующего #endif, #else или #elif условно ассемблируются, если имя определено прежде.
Пример:
#ifdef FOO
……….. // делает что-то.
#endif

#ifndef – директива условной компиляции
Синтаксис:
#ifndef имя
Описание:
Сокращенная запись от #if not defined. Противоположность #ifdef. Все следующее строки до соответствующих #endif, #else или #elif условно ассемблируются, если имя не определено.

#if
#elif – директивы условной компиляции
Синтаксис:
#if условие
#elif 

Описание:
Все следующие строки до соответствующего #endif, #else или #elif условно ассемблируются, если условие является истиной (не равно 0). Условие – любое целое выражение, включая макросы препроцессора, которые расширены (распакованы). Препроцессор распознает оператор defined(name), который возвращает 1, если имя определено, и 0 – в противном случае. Любые не определенные символы, использованные в условии по умолчанию, = 0.
Условие может быть вложенным на произвольную глубину.
#elif оценивает условие так же, как #if, за исключением того, что только что оценено, и если никакой предшествующей ветвлению командой #if … #elif данное условие не было оценено как истина.
Примеры:
#if 0
………..     // Здесь код никогда не компилируется.
#endif
#if defined(__ATmega48__) || defined(__ATmega88__)
………….   // код специфичный для этих устройств.
#elif defined (__ATmega169__)
…………   // код специфичный для ATmega169.
#endif

Препроцессор AVRASM2 не делает отдельный проход до вызова Ассемблера, он встроенная часть Ассемблера. Это может вызвать некоторую неразбериху, если препроцессор и Ассемблер создают аналогичные разнотипные объекты (например, #if и .if условия). Это также вызывает сбои препроцессора при использовании условий в макросах Ассемблера, которые нужно оценивать, когда макрос распакован, а не когда он определен. Условные выражения не могут распределять начало или конец макроопределения (но могут распределить целое макроопределение, включая начало и окончание).

.ENDIF – директива условного ассемблирования
Завершает условный блок кода после директив .IF, .IFDEF или .IFNDEF. Условные блоки (.IF...ELIF... .ELSE...ENDIF) могут быть вложенными, но все они должны быть выполнены до конца файла (условные блоки не могут работать в нескольких файлах).
Синтаксис:
.ENDIF
.IFDEF  |.IFNDEF 


.ELIF, .ELSE– директивы условного ассемблирования
.ELIF включит в процесс ассемблирования код, следующий за ELIF, до соответствующего ENDIF или следующего ELIF, если expression явля-ется истиной. В противном случае этот код будет пропущен.
.ELSE включит код до .ENDIF, если условия в директиве .IF и условия во всех .ELIF были ложными.
Синтаксис:
.ELIF
.ELSE
.IFDEF |.IFNDEF
...
.ELSE | .ELIF
...
.ENDIF
Пример:
.IFDEF DEBUG
.MESSAGE "Debugging.."
.ELSE
.MESSAGE "Release.."
.ENDIF

#else – директива условной компиляции
Синтаксис:
#else
Описание:
Все следующие строки до соответствующего #endif условно ассемблируются, если никакая предшествующая ветка в составе последовательности #if... #elif... не оценена как истина.
Пример:
#if defined(__ATmega48__) || defined(__ATmega88__)
………….    // код специфичный для этих МК
#elif defined (__ATmega169__)
…………..    // код специфичный для ATmega169
#else
#error "Unsupported part:" __PART_NAME__   // сообщение об ошибке.
#endif 

.IF, .IFDEF, .IFNDEF – директивы условного ассемблирования
Условное ассемблирование включает команды из исходного кода в процесс ассемблирования выборочно. Директива IFDEF включит код до соответствующей директивы ELSE, если определен. Символ должен быть определен директивами EQU или SET (не будет работать с директивой DEF). Директива IF, если отлично от 0, включит код до соответствующей директивы ELSE или ENDIF. Возможны до пяти уровней вложенности.
Синтаксис:
.IFDEF
.IFNDEF
.IF
.IFDEF |.IFNDEF
...
.ELSE | .ELIF
...
.ENDIF

Пример:
.MACRO SET_BAT
.IF @0>0x3F
.MESSAGE "Адрес больше, чем 0x3f"
lds @2, @0
sbr @2, (1<<@1)
sts @0, @2
.ELSE
.MESSAGE " Адрес меньше или равен 0x3f"
.ENDIF
.ENDMACRO

.ERROR – вывод строки с сообщением об ошибке.
.WARNING – вывод строки с предупреждением.
.MESSAGE – вывод строки с сообщением.
Синтаксис:
.ERROR “строка”
.WARNING “строка”
.MESSAGE “строка”
Описание:
.ERROR – (ошибка) выдает сообщение об ошибке, останавливает компиляцию и увеличивает счетчик ошибок Ассемблера, тем самым помогает успешному ассемблированию программы. #error определена в стандарте ANSI C.

Пример:
.IFDEF TOBEDONE
.ERROR "Still stuff to be done.."
.ENDIF


.WARNING – (предупреждение) выдает предупреждающее сообщение и увеличивает счетчик предупреждений Ассемблера. В отличие от error не останавливает компиляцию. Директива .warning не определена в стандарте ANSI C, но обычно реализована в препроцессорах, как, например, в препроцессоре GNU C.
Пример:
.IFDEF EXPERIMENTAL_FEATURE
.WARNING "This is not properly tested, use at own risk."

.ENDIF
.MESSAGE – (сообщение) выдает сообщение и не влияет на счетчики ошибок и предупреждений Ассемблера. .message не определено в стандарте ANSI C.

Пример:
.IFDEF DEBUG
.MESSAGE "Debug mode"
.ENDIF

Для всех директив сообщения включают файловое имя и номер строки, подобно нормальным сообщениям об ошибках и предупреждениях.
Макросы препроцессора распаковываются, кроме заключенного внутри двойных кавычек (").
Пример:
.error "Неподдерживаемый МК:" __PART_NAME__

#include или .INCLUDE – включение другого файла
Синтаксис:
1) " file "
2) #include
Описание:
Включение файла. Две формы отличаются тем, что (1) ищет сначала текущий рабочий директорий и функционально эквивалентна директиве .include Ассемблера. (2) ищет в установленном месте – обычно в директории C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes. Обе формы ищут включаемые файлы в известном месте установленным Ассемблером.
Лучше использовать абсолютные имена пути к файлу в директивах #include, так как поиск файлов затрудняется при перемещении проектов между другими директориями/компьютерами. Используйте опцию -I командной строки, чтобы определять путь, или установите его в AVR Studio - Project - Assembler Options, в окошке Additional include path.
Примеры:
#include; Ищет в каталоге Appnotes.
#include "mydefs.inc"  ; Ищет в рабочем каталоге.
; iodefs.asm: 
.EQU sreg   = 0x3f      ; Status register. 
.EQU sphigh = 0x3e    ; Stack pointer high. 
.EQU splow  = 0x3d    ; Stack pointer low. 
; incdemo.asm 
.INCLUDE iodefs.asm  ; Include I/O definitions. 
        in r0,sreg    ; Read status register.

.OVERLAP – перекрытие
.NOOVERLAP – неперекрытие
Эти директивы нужны для проектов со специфическими особенностями и не должны использоваться в обычных случаях. Они к настоящему времени влияют только на активный сегмент (cseg/dseg/eseg).
Директивы .overlap/nooverlap выделяют секцию кода/данных, которой будет позволено перекрываться с кодом/данными, определенными где-нибудь еще, без генерации сообщения об ошибке или предупреждения. Это полностью независимо от того, что установлено с использованием директивы перекрытия #pragma. Атрибут допустимого перекрытия останется эффективным по директиве .org, но не последует по директивам .cseg/.eseg/.dseg (каждый сегмент выделяется отдельно).

Синтаксис:
.OVERLAP
.NOOVERLAP
Пример:
.overlap 
.org 0                      ; Секция #1.
    rjmp    default
.nooverlap.org 0        ; Секция #2.
    rjmp    RESET      ; Здесь нет ошибки.
.org 0                        ; Секция #3.
    rjmp    RESET      ; Ошибка, так как есть перекрытие с секцией #2.

Типичное использование этого – устанавливать некоторую форму кода или данных по умолчанию, которые позже могут модифицироваться перекрытием с другими кодом или данными без необходимости вывода сообщения о перекрытии.

#pragma общего назначения
Синтаксис:
1) #pragma warning range byte option – предупреждение о байтовом диапазоне;
2) #pragma overlap option – перекрытие;
3) #pragma error instruction – ошибки инструкций;
4) #pragma warning instruction – предупреждения по поводу инструкций.
Описание:
1. Ассемблер оценивает постоянные целые выражения как 64 - битные знаковые целые. Когда такие выражения использованы как непосредственные операнды, они должны быть включены в количество битов, требующихся команде. Для большинства операндов выход из диапазона вызовет сообщение ошибки "операнд из диапазона". Тем не менее непосредственные байтовые операнды для команд ldi, cpi, ori, andi, subi, sbci имеют несколько возможных интерпретаций, в зависимости от опции (option):
option = integer: операнд непосредственно оценен как целое, и если его значение за пределами диапазона (-128 ... 255), будет дано предупреждение. Ассемблер не знает, что предполагает пользователь: операнд целым, со знаком или без знака, следовательно, он допускает любое значение со знаком или без знака, которое умещается в байт.
option = overflow (умолчание): операнд оценивается как байт без знака, и любые биты знака будут проигнорированы. Эта опция пригодна при работе с битовыми масками, когда интерпретация целого должна вызывать массу предупреждений, подобно ldi r16, ~ ((1 << 7) | (1 << 3)).
option = none: не выводится никаких предупреждений о диапазоне для байтовых операндов. Не рекомендуется.
2. Если две секции кода, размещенные в памяти директивой .org, перекрываются, передается сообщение об ошибке. Опции модифицируют это поведение следующим образом:
option = ignore: игнорирует условия перекрытия и не выдаются никакие ошибки, никакие предупреждения. Не рекомендуется.
option = warning: при обнаружении перекрытия выдается предупреждение.
option = error: считает перекрытие как ошибку, это рекомендовано устанавливать по умолчанию.
3. Использование инструкций, которые не поддерживаются на выбранном устройстве, вызывает ошибку Ассемблера (поведение по умолчанию).
4. Использование инструкций, которые не поддерживаются на выбранном устройстве, вызывает предупреждение Ассемблера.
Исключён фрагмент. Полный вариант доступен меценатам и полноправным членам сообщества.


Продолжение следует!
Дальше разберем выражения и функции ассемблера AVRASM2 и
определимся с инициализацией программ.

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

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

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




 

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

Нравится

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

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

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

 

 

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

 

Схема на Датагоре. Новая статья Программирование микроконтроллеров в AtmelStudio 6. Часть 2. Одна программа на разных языках.... Для радиолюбителей, которые до определенного времени не использовали микроконтроллеры в своих...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 2... Пишем первую программу!Большинство начинают с мигания светодиодов, и мы не исключение. Если...
Схема на Датагоре. Новая статья TDA7442D+ATmega8. Микропроцессорный регулятор громкости... Привет ВСЕМ!!! Интересно, кому бы не хотелось, чтобы его усь обладал сервисом промышленных...
Схема на Датагоре. Новая статья Электронные устройства для дома. Евсеев А. Н.... Евсеев Андрей Николаевич Электронные устройства для дома. — М.: Радио и связь, 1994г. — 144 с: ил....
Схема на Датагоре. Новая статья Несколько функций для програмной реализации протокола I2C на AVR... Добрый день, дорогие друзья! Решил поделиться с вами несколькими функция для работы по протоколу...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 3... Мы научились включать и выключать светодиоды, а как сделать, чтобы они сами заморгали? Понятно,...
Схема на Датагоре. Новая статья Фото-реле на микроконтроллере ATTiny13... Привет датагорцам! Я затеял ремонтные работы дома, и мне понадобилась система автоматического...
Схема на Датагоре. Новая статья Программная реализация протокола SPI на AVR в CodeVisionAVR... Всем коллегам и согражданам привет! Увлёкся я изучением протоколов. Про реализацию протокола I2C у...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 8... Перейдем к изучению встроенных таймеров. Изучение прерываний и особенно таймеров в...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 4... Сегодня рассмотрим программу “бегущих огней” и “бегущих теней”. Примеры “бегущих огней” можно...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 6... Продолжим разбор теоретических основ, без которых невозможно полноценное создание программ....
Схема на Датагоре. Новая статья Часы с GPS-синхронизацией времени и винтажными индикаторами ИН-12. Наш вариант Nixie Tube Clock... Не думал, что спустя много лет я вернусь к часам на газоразрядных индикаторах. В конце 70-х я...
 

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

 

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

makc

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

ALEXIN88

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

emw

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

Ryan

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

faers

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

AudioKiller

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

galrad

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

AudioKiller

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

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

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