29 января 2014 г.

Структура ассемблерных программ для AVR

Ниже приведена типичная структура для порграмм AVR ассебмлера.
* Комментарии, заголовок где идёт описание, копирайты и прочая погань
* Заголовочная информация, определение констант, подлючение внешних файлов, определение макросов и др.
* Код начала программы
* Основная структура порграммы


Комментарии

Очень полезная вещь в программах на ассемблере - это комментарии. Если вам необходимо понять позже код который вы написали, особенно через несколько лет, вам будет приятно увидеть описание программы и кода в конкретных строках или блоках. Но если вы жудкий параноик и пытаетесь спрятать описание ваших мыслей от агентов ЦРУ, а особенно от себя, НИ В КОЕМ СЛУЧАЕ НЕ СТАВЬТЕ КОММЕНТАРИИ!
Для всех остальных. Комментарии начинаются со знака точка-с-запятой [ ; ]. Все что следует в строке за этим значком игнорируется компилятором. Если вам надо написать многострочный комментарий необходимо каждую строку начинать с точки с запятой. Например
;
; myfirst.asm  Программа управления андроидным колайдером
; Написано Виктором Буяковым в порыве безудержного оптимизма, последнее изменение 27.01.2011
;
Ставьте комментарии во всех частях программы, это позволит вам облегчить разработку, поиск ошибок и модернизацию программы в будующем. А на начальном этапе позволит вам быстрее разучить комманды ассемблера и понять физику и химию их работы. Ниже пример комментария кода
LDI R16,0x0A ; Загрузка числа в регистр 16
MOV R17,R16 ; Копировать содержимое регистра из 16  в 17 



Заголовочная информация

В заголовке мы указываем включаемые файлы, тип устройства, определения имён для регистров, определение констант.
Тип процессора, одна из самых главных частей заголовка. Программы не будут запускаться на других чипах без сщщответствующих изменений. Тип процессора определяется подключаемым файлом, в этом файле прописанны адреса регистров ввода вывода, прерываний, расположение встроенной памяти SRAM и EEPROM. Файлы называются по имени чипа, например для Atmega8535 - m8535def.inc, а для Attyny2313 - tn2313def.inc. По умолчанию файлы находятся в данной папке "C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes" Вот пример поключение библиотеки
.NOLIST ; Данная директива указывает, что генерация листфайла отключена
.INCLUDE "m8515def.inc" ; Импортировать заголовочный файл
.LIST ; Включить генерацию листинга
А что же внутри этого файла? Первой строкой идёт определение устройства
.DEVICE ATMEGA8515 ; Текущий тип устройства
Директива .DEVICE позволяет компилятору проверить соответсвие комманд процессора в программе текущему указанаму типу AVR. Так, что вам не следует указывать тип устройства в программе, она есть в ****def.inc файл.
В заголовочном файле также определены регистры XH, XL, YH, YL, ZH and ZL. Они нужны для определения частей 16-ти разрядныйх указателей X, Y or Z. Все порты так же определены в данном файле, например PORTA представлено его HEX значение. Имена портов соответствую описаниям в Datashet. Так же определены еденичные биты портов. Например для доступа 5 го бита порта C используется PINC5, и так же соответствует фирменному описанию. Вобще, если вы не подключите заголоввочный файл вы увидите огромадное количество ошибок :-)
Другие вещи которые должны быть включены в заголовке программы это определение регистров, например
.DEF  FLAJOK  = R16 ; Создание человечного имени для регистра R10
Вобще определение регистров полезная вещь, так видно какие регистры вы используете, а какие нет, это позволит рационально использовать регистры и избежать путаницы и конфликтов.
Там же, в заголовке программы определяются используемы константы Например частота тактового генератора, что позволит при изменении параметров тактового генератора не менять все части программы
.EQU fq = 4000000 ; частота тактового генератора



Код начала программы

Чтож, мы умеем определять заголовок программы, наконец ннастало время написать реальный код. В начале кода по адресу 0x0000 находиться вектор сброса, т.е. место куда перейдёт программа после включения питания или сигнала RESET. Сразу за этим адресом с адреса 0x0002 начинается таблица векторов прерываний. Выглядит это приблизительно так
.CSEG
.ORG $0000
 rjmp Main ; Вектор сброса
 reti ; Прерывание 1
 reti ; Прерывание 2
..... 
Дам небольшое пояснение. Директива .CSEG - указывает компилятору, что строки ниже пренадлежат памяти данных .ORG задаёт текущее смещение на определённый адрес, т.е. .ORG $0000 указывает, что следующая команда будет находится по адресу 0x0000. rjmp Main - данная команда находящаяся по 0000 адресу осуществляет безусловный переход к метке Main.
ВНИМАНИЕ!!!! Cледует учесть, что для чипов Mega с большим объёмом памяти следует использовать команду jmp вместо rjmp, случай редкий но примите на заметку!
Рекомендую вас скачать замечательную программку - генератор заголовочных файлов , по данной ссылке . Для процессора типа Tiny13 вы получите вот такой вот замечательный код
;
; ********************************************
; * [Add Project title here]                 *
; * [Add more info on software version here] *
; * (C)20xx by [Add Copyright Info here]     *
; ********************************************
;
; Included header file for target AVR type
.NOLIST
.INCLUDE "tn13def.inc" ; Header for ATTINY13
.LIST
;
; ============================================
;   H A R D W A R E   I N F O R M A T I O N   
; ============================================
;
; [Add all hardware information here]
;
; ============================================
;      P O R T S   A N D   P I N S 
; ============================================
;
; [Add names for hardware ports and pins here]
; Format: .EQU Controlportout = PORTA
;         .EQU Controlportin = PINA
;         .EQU LedOutputPin = PORTA2
;
; ============================================
;    C O N S T A N T S   T O   C H A N G E 
; ============================================
;
; [Add all constants here that can be subject
;  to change by the user]
; Format: .EQU const = $ABCD
;
; ============================================
;  F I X + D E R I V E D   C O N S T A N T S 
; ============================================
;
; [Add all constants here that are not subject
;  to change or calculated from constants]
; Format: .EQU const = $ABCD
;
; ============================================
;   R E G I S T E R   D E F I N I T I O N S
; ============================================
;
; [Add all register names here, include info on
;  all used registers without specific names]
; Format: .DEF rmp = R16
.DEF rmp = R16 ; Multipurpose register
;
; ============================================
;       S R A M   D E F I N I T I O N S
; ============================================
;
.DSEG
.ORG  0X0060
; Format: Label: .BYTE N ; reserve N Bytes from Label:
;
; ============================================
;   R E S E T   A N D   I N T   V E C T O R S
; ============================================
;
.CSEG
.ORG $0000
 rjmp Main ; Reset vector
 reti ; Int vector 1
 reti ; Int vector 2
 reti ; Int vector 3
 reti ; Int vector 4
 reti ; Int vector 5
 reti ; Int vector 6
 reti ; Int vector 7
 reti ; Int vector 8
 reti ; Int vector 9
;
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
;
; [Add all interrupt service routines here]
;
; ============================================
;     M A I N    P R O G R A M    I N I T
; ============================================
;
Main:
; Init stack
 ldi rmp, LOW(RAMEND) ; Init LSB stack
 out SPL,rmp
; Init Port B

ldi rmp,(1<<DDB2)|(1<<DDB1)|(1<<DDB0) ; Direction of Port B
out DDRB,rmp
; [Add all other init routines here]
 ldi rmp,1<<SE ; enable sleep
 out MCUCR,rmp
 sei
;
; ============================================
; P R O G R A M L O O P
; ============================================
;
Loop:
 sleep ; go to sleep
 nop ; dummy for wake up
 rjmp loop ; go back to loop
;
; End of source code
;


___
http://buyakov.com/assembler-dlya-avr-chast-1-nachalo/#more-93
 

Комментариев нет:

Отправить комментарий