Єдина Країна!

Головне меню

Наша кнопка

Українські уроки про ІТ

Друзі

Підтримка української армії


Головна Програмування - Програмування мікроконтролерів Підключення асемблерних команд у проекти на C в середовищі IAR AVR 5.40

Підключення асемблерних команд у проекти на C в середовищі IAR AVR 5.40
Написав rostokus   
Четвер, 25 серпня 2011 23:20
Переглядів: 7367

В основному програмування мікроконтроллерів здійснюється мовами високого рівня, такими як С і С++. Але в деякі проекти потрібно додати частини коду на мові низького рівня, такий як assembler. Наприклад, для формування часових інтервалів. Скажімо, потрібно зробити затримку в 3 такти мікропроцесора. Для цього служить команда “nop”. Як її додати до С ф-ції зараз розглянемо.

 

Офіційна документація від IAR (AVR® IAR C/C++ Compiler) пропонує таких три способи:

  1. підключення цілих модулів, написаних на асемблері.
  2. вбудовані команди асемблера (inline assembler).
  3. використання внутрішніх функцій (intrinsic functions).

Почнемо з останнього.

І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.

  1. ldi R25,0x05; (x = 5); Далі виконав додавання:
  2. x += 0x30; (х = 0x35); І зайшов в режим асемблера:
  3. ldi R25, 0x05; (x = 5); Ми випадково змінили значення змінної  на 0х05, а замість 0х35!

Звідси висновок: при використанні цього способу потрібно перед тим, як виконаються команди асемблера зберегти значення усіх регістрів, які використовує компілятор. Після виконання блоку команд, перед виходом з асемблерного режиму, відновити значення регістрів.

Модулі, написані на асемблері. Якщо ви не знайшли підходящих intrinsic functions, цей спосіб якнайкраще вам підходить. Розглянемо його на прикладі створення програми керування світлофором.

Алгоритм програми:

  1. включити червоне світло;
  2. якщо натиснута кнопка “Перехід” чекаємо 5 с і вмикаємо жовте світло;
  3. через 1 с вмикаємо зелене світло і чекаємо 5 с;
  4. виключаємо зелене і знову вмикаємо червоне.

Отже нам потрібно: одну кнопку, три світлодіоди, а також сформувати дві часові затримки — на 5 та 1 с. Затримку в 1 с сформуємо в асемблерному модулі (ф-ція asm.asm), а 5с — за допомогою вбудованої ф-ції __delay_cycles() .

Принципова схема плати:

великий розмір

IAR рекомендує такий алгоритм створення модулів:

  1. Створюємо “скелет” майбутнього модуля на мові С. Опишемо ф-ції, які до нього входитимуть. Але не потрібно писати повністю функції. Достатньо її оголосити та виконати прості операції над змінними, які вони використовують. У майбутньому для кожного прототипу ф-ції потрібно буде робити свій “скелет”. Назвімо її Wait1sec.c.

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

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 Проголосувало )
Коментарі
Добавити новий
Залишити коментар
Ім`я:
e-mail:
 
Тема:
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Введіть цей настирливий код
Русская редакция: www.freedom-ru.net & www.joobb.ru

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 

Підписка

Хто онлайн?

Немає
На даний момент 16 гостей на сайті

Український рейтинг
TOP.TOPUA.NET