Підключення асемблерних команд у проекти на C в середовищі IAR AVR 5.40 |
Написав rostokus | |||||
Четвер, 25 серпня 2011 23:20 Переглядів: 7367
|
|||||
В основному програмування мікроконтроллерів здійснюється мовами високого рівня, такими як С і С++. Але в деякі проекти потрібно додати частини коду на мові низького рівня, такий як assembler. Наприклад, для формування часових інтервалів. Скажімо, потрібно зробити затримку в 3 такти мікропроцесора. Для цього служить команда “nop”. Як її додати до С ф-ції зараз розглянемо.
Офіційна документація від IAR (AVR® IAR C/C++ Compiler) пропонує таких три способи:
Почнемо з останнього. Іntrinsic functions — це функції, які використовують прямий доступ до низькорівневих команд процесора, без використання команд асемблера. Хороша річ, має переваги над вбудованим асемблером. Але є одне “але”. Цих ф-цій не так вже й багато. Серед них є такі важливі ф-цї, як __delay_cycles(unsigned long delay), яка створює затримку у delay тактів, __load_program_memory(const unsigned char __flash *pointer), яка завантажує один байт з пам’яті програм, адреса якого міститься у змінній pointer та інші. Повний список знайдете у файлі intrinsics.h. Тому, якщо ви знайшли там потрібну ф-цію, можете сміливо її використовувати, а як ні, то читайте далі. Іnline assembler — додавання коду прямо у С файл з використанням інструкції asm чи __asm. Виглядає це так: void main(void) { unsigned char x = 0x5; x += 0x30; __asm ("ldi R25, 0x05\n" " nop"); } Команди виділені курсивом. Вони поміщаються в лапки і, якщо потрібно написати більше однієї команди, вкінці ставиться \n. На жаль, не усі команди можна підключити таким способом. І взагалі з вбудованими командами асемблера потрібно бути дуже обережними. Наприклад, на етапі компіляції компілятор відвів для змінної x регістр R25.
Звідси висновок: при використанні цього способу потрібно перед тим, як виконаються команди асемблера зберегти значення усіх регістрів, які використовує компілятор. Після виконання блоку команд, перед виходом з асемблерного режиму, відновити значення регістрів. Модулі, написані на асемблері. Якщо ви не знайшли підходящих intrinsic functions, цей спосіб якнайкраще вам підходить. Розглянемо його на прикладі створення програми керування світлофором. Алгоритм програми:
Отже нам потрібно: одну кнопку, три світлодіоди, а також сформувати дві часові затримки — на 5 та 1 с. Затримку в 1 с сформуємо в асемблерному модулі (ф-ція asm.asm), а 5с — за допомогою вбудованої ф-ції __delay_cycles() . Принципова схема плати: IAR рекомендує такий алгоритм створення модулів:
void Wait1sec(char one, char two, char three) { one = 0x00; two = 0xD4; three = 0x30; } 2. Додати файл до проекту і скомпілювати його. (ледь не забув: перед тим потрібно зайти в Project-Options-C/C++ Compiler-List і поставити галочку на пункті Output assembler file та Include source та забрати з Output list file). 3. У папці \Debug\List\ знайдете файл Wait1sec.s90. У ньому знаходиться скомпільований код файлу Wait1sec.c. Видаляємо коментарі, додаємо код ф-ції: NAME Wait1sec // назва модулю RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) PUBLIC Wait1sec // ф-ція Wait1sec загальнодоступна
PUBWEAK __?EEARH PUBWEAK __?EEARL PUBWEAK __?EECR PUBWEAK __?EEDR RSEG CODE:CODE:NOROOT(1)
Wait1sec: // початок ф-ції LDI R16, 0 LDI R17, 212 LDI R18, 48
Loop: subi R16, 1 span>sbci R17, 0 sbci R18, 0 brcc Loop RET // кінець ф-ції
ASEGN ABSOLUTE:DATA:NOROOT,01cH __?EECR: ASEGN ABSOLUTE:DATA:NOROOT,01dH __?EEDR: ASEGN ABSOLUTE:DATA:NOROOT,01eH __?EEARL: ASEGN ABSOLUTE:DATA:NOROOT,01fH __?EEARH: END // кінець модуля 4. Зберігаємо його під назвою asm.asm і додаємо до проекту. Файл Wait1sec.с можна видалити з проекту. Опис ф-ції main() знайдете в самому проекті, тому зараз зупинятись на ньому не буду. Там є оголошення і виклик ф-ції void Wait1sec(char one, char two, char three), яка і буде формувати потрібну затримку тривалістю 1 сек. Про те, яким чином розраховувати аргументи ф-ції можна подивитись у книжці Джона Мортона “Микроконтроллеры AVR. Вводный курс” на 69 ст. Варто зауважити, що аргументи, подані тут, справедливі для частоти кварцу 16 Mhz. Якщо використовується інша частота, аргументи потрібно перерахувати, бо тривалість затримки зміниться. Якщо комусь цікаво, можете запитати мене або почитати у книзі. 5. Проект готовий.
Щасти!
Посилання на файл з проектом
ключові слова: C, assembler (асемблер), IAR, AVR, microcontroller (мікроконтроллер), intrinsic functions, inline assembler, програма світлофор, часові затримки.
( 13 Проголосувало ) Новіші матеріали:
Старіші матеріали:
3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |