AVR102: подпрограммы блочного копирования данных |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
В даташите AVR102 рассматривается реализация на языке ассемблера следующих базовых операций: • Копирование из памяти программ (FLASH) в оперативную память (SRAM) Подпрограммы копирования экстремально эффективны: операция FLASH -> SRAM занимает 6 слов (т. е. 12 байт), SRAM -> SRAM занимает 5 слов (10 байт). К подпрограммам прилагается запускаемый тест для проверки работы подпрограмм. Подпрограммы копирования работают с блоками до 256 байт, и могут копировать из любого исходного адреса по любому адресу назначения. [FLASH -> SRAM, подпрограмма flash2ram] Перед вызовом этой подпрограммы должны быть настроены следующие входные параметры: • flashsize – регистровая переменная, содержащая размер копируемого блока данных. Подпрограмма для копирования использует инструкцию 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 используется в подпрограмме для счетчика цикла. Рис. 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.
Таблица 2. Параметры эффективности подпрограммы flash2ram.
[SRAM -> SRAM, подпрограмма ram2ram] Перед вызовом этой подпрограммы должны быть настроены следующие входные параметры: • ramsize – регистровая переменная, в которой содержится размер блока данных. Из-за того, что используется автоинкремент указателей, эта подпрограмма получилась экстремально компактной и быстрой. Перемещение одного байта данных и инкремент обоих указателей требуют только 2 инструкций. Еще 2 инструкции нужны для декремента и проверки регистровой переменной ramsize, которая используется в качестве счетчика цикла в подпрограмме. Во время передачи данные временно хранятся в регистровой переменной ramtemp. Рис. 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.
Таблица 4. Параметры эффективности подпрограммы ram2ram.
[Программа для примера/тестирования] Программа апноута содержит файл, содержащий рабочий тест, который использует подпрограммы копирования 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. |