Программирование AVR AVR102: подпрограммы блочного копирования данных Mon, September 25 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


AVR102: подпрограммы блочного копирования данных Печать
Добавил(а) microsin   

В даташите AVR102 рассматривается реализация на языке ассемблера следующих базовых операций:

• Копирование из памяти программ (FLASH) в оперативную память (SRAM)
• Копирование в пределах оперативной памяти (из SRAM в SRAM)

Подпрограммы копирования экстремально эффективны: операция FLASH -> SRAM занимает 6 слов (т. е. 12 байт), SRAM -> SRAM занимает 5 слов (10 байт). К подпрограммам прилагается запускаемый тест для проверки работы подпрограмм.

Подпрограммы копирования работают с блоками до 256 байт, и могут копировать из любого исходного адреса по любому адресу назначения.

[FLASH -> SRAM, подпрограмма flash2ram]

Перед вызовом этой подпрограммы должны быть настроены следующие входные параметры:

• flashsize – регистровая переменная, содержащая размер копируемого блока данных.
• Z-pointer – указатель, равный двухбайтовому исходному адресу первого байта копируемого блока в памяти FLASH.
• Y-pointer – указатель, адрес назначения первого байта из копируемого блока в памяти SRAM.

Подпрограмма для копирования использует инструкцию LPM, которая предназначена для передачи данных из FLASH в регистровый файл. Инструкция выбирает слово из памяти FLASH (2 байта, 16 бит) которое указано 15 старшими битами из указателя Z-pointer. Если младший бит Z-pointer равен 0, то будет возвращен младший байт слова из FLASH, иначе будет возвращен старший байт слова из FLASH. Возвращенный байт всегда будет находиться в регистре R0. Чтобы получить 15 старших битов для Z, соответствующих корректному значению слова, программист должен внимательно загрузить Z дважды адресом первого двойного байта в таблице. Листинг программы показывает, как обработать это условие.

Во время передачи данных используется автоинкремент указателей. Запись в SRAM выполняется с использованием инструкции ST Y+,Rs. Инструкция LPM не поддерживает автоинкремент или автодекремент, поэтому для инкремента 16-битного указателя используется инструкция ADIW.

Регистровая переменная flashsize используется в подпрограмме для счетчика цикла.

AVR102-flash2ram

Рис. 1. Алгоритм flash2ram.

;***************************************************************************
;* flash2ram
;***************************************************************************
;***** регистровые переменные подпрограммы 
.def  flashsize=r16  ;размер копируемого блока
 
flash2ram:
   lpm               ;получить константу
   st    Y+,r0       ;сохранить её в SRAM и инкрементировать Y-pointer
   adiw  ZL,1        ;инкремент Z-pointer
   dec   flashsize
   brne  flash2ram   ;продолжим, если счетчик не равен 0
   ret

Таблица 1. Использование регистров подпрограммой flash2ram.

Регистр Вход Внутреннее использование
R0 Временное хранилище данных
R16 flashsize - размер копируемого блока данных
R28 YL- младший байт адреса назначения (начало блока SRAM)
R29 YH - старший байт адреса назначения (начало блока SRAM)
R30 ZL - младший байт адреса источника (начало блока FLASH)
R31 ZH - старший байт адреса источника (начало блока FLASH)

Таблица 2. Параметры эффективности подпрограммы flash2ram.

Параметр Значение
Размер кода (в словах) 5 + возврат
Время выполнения (10 * размер_блока) + возврат
Использование регистров 6 (из них 4 регистра приходится на указатели Z и Y)
Прерывания не используются
Периферийные устройства не используются

[SRAM -> SRAM, подпрограмма ram2ram]

Перед вызовом этой подпрограммы должны быть настроены следующие входные параметры:

• ramsize – регистровая переменная, в которой содержится размер блока данных.
• Z-pointer – адрес первого байта в блоке источника данных.
• Y-pointer – адрес первого байта в блоке места назначения данных.

Из-за того, что используется автоинкремент указателей, эта подпрограмма получилась экстремально компактной и быстрой. Перемещение одного байта данных и инкремент обоих указателей требуют только 2 инструкций. Еще 2 инструкции нужны для декремента и проверки регистровой переменной ramsize, которая используется в качестве счетчика цикла в подпрограмме. Во время передачи данные временно хранятся в регистровой переменной ramtemp.

AVR102-ram2ram

Рис. 2. Алгоритм ram2ram.

;***************************************************************************
;* ram2ram
;***************************************************************************
;***** регистровые переменные подпрограммы 
.def  ramtemp  =r1      ;регистр для временного хранения байта данных
.def  ramsize  =r16     ;размер копируемого блока
 
ram2ram:
   ld    ramtemp,Z+     ;получение данных из BLOCK1
   st    Y+,ramtemp     ;сохранение данных в BLOCK2
   dec   ramsize
   brne  ram2ram        ;продолжим, если счетчик не равен 0
   ret

Таблица 3. Использование регистров подпрограммой ram2ram.

Регистр Вход Внутреннее использование
R1 ramtemp - временное хранилище данных
R16 ramsize - размер копируемого блока данных
R28 YL- младший байт адреса назначения (начало блока SRAM)
R29 YH - старший байт адреса назначения (начало блока SRAM)
R30 ZL - младший байт адреса источника (начало блока SRAM)
R31 ZH - старший байт адреса источника (начало блока SRAM)

Таблица 4. Параметры эффективности подпрограммы ram2ram.

Параметр Значение
Размер кода (в словах) 4 + возврат 
Время выполнения (6 * размер_блока) + возврат
Использование регистров 6 (из них 4 регистра приходится на указатели Z и Y)
Прерывания не используются
Периферийные устройства не используются

[Программа для примера/тестирования]

Программа апноута содержит файл, содержащий рабочий тест, который использует подпрограммы копирования 2 байт данных из FLASH в SRAM, затем делают 2 копию данных в другой области SRAM. Тест-программа была сделана для микроконтроллера AT90S8515. Путем смены подключаемого файла *def.inc на другой программа может быть использована с любым другим микроконтроллером AVR, у которого есть память SRAM.

;****************************************************************************
;* Тест-программа
;*
;* Эта программа копирует 20 байт данных из памяти программ (FLASH) в SRAM,
;* начиная с адреса BLOCK1. Затем она делает вторую копию этих данных
;* начиная с адреса BLOCK2.
;****************************************************************************
.equ  BLOCK1   =$60        ;start address of SRAM array #1
.equ  BLOCK2   =$80        ;start address of SRAM array #2
 
.def  temp     =r16        ;временная переменная для хранения данных
 
RESET:
   ldi   temp,low(RAMEND)
   out   SPL,temp          ;инициализация стека
   ldi   temp,high(RAMEND)
   out   SPH,temp

;***** копирование 20 байт FLASH -> RAM
   ldi   ZH,high(F_TABLE*2)
   ldi   ZL,low(F_TABLE*2) ;инициализация Z-pointer
   ldi   YH,high(BLOCK1)
   ldi   YL,low(BLOCK1)    ;инициализация Y-pointer
   ldi   flashsize,20
   rcall flash2ram

;***** копирование 20 байт RAM -> RAM
   ldi   ZH,high(BLOCK1)
   ldi   ZL,low(BLOCK1)    ;инициализация Z-pointer
   ldi   YH,high(BLOCK2)   ;(хотя это и необязательно для нашего случая)
   ldi   YL,low(BLOCK2)    ;инициализация Y-pointer
   ldi   ramsize,20
   rcall ram2ram
 
forever:
   rjmp  forever           ;бесконечный цикл
 
F_TABLE:
   .db   0,1               ;начало таблицы из 20 байт
   .db   2,3
   .db   4,5
   .db   6,7
   .db   8,9
   .db   10,11
   .db   12,13
   .db   14,15
   .db   16,17
   .db   18,19

[Ссылки]

1. AVR102: Block Copy Routines site:atmel.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page