Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.55/38: Рейтинг темы: голосов - 38, средняя оценка - 4.55
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
1

Параметры функций в WinAvr

06.02.2011, 17:34. Просмотров 6968. Ответов 10
Метки нет (Все метки)

Как можно в WinAvr, в функцию, передать параметр, но что бы он передавался как один определенный call-used регистр. точнее даже два: тип данных 16 бит.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2011, 17:34
Ответы с готовыми решениями:

Статическое размещение процедур и функций в WinAVR.
Коллеги. Есть проект. На борту atmego32, 16МГц, SD карта, дисплей LS020. Все это оформлено в виде...

WinAVR и стек
Вот компилим прогу в авр студии при помощи winavr и нам пишут что задествавано озу 85% например.....

Не компилируется C++ на WinAVR
Всем привет! Помогите пожалуйста разобраться с проблемой компиляции *.CPP на WinAVR Даже Hello...

Умножение WinAVR
Вот проблема такая: unsykned long temp; temp=0; temp=9*3600; В результате в temp лежит 00...

Из массива в переменную [winavr]
Приветствую, что-то не могу врубиться как присвоить значение 16-и битовой переменной из 8-и...

10
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
06.02.2011, 19:10 2
С трудом могу представить, зачем это нужно. Вероятно для вызова этой функции из ассамблерного модуля? Тогда достаточно просто знать какие регистры использует компилятор. А вообще - никак. Есть соглашение о вызовах - всё остальное от лукавого.
0
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
07.02.2011, 11:56 3
Цитата Сообщение от miyvir
С трудом могу представить, зачем это нужно.
Нужно мыслить ширее. Допустим в функцию передается двухбайтный параметр, но в функции идут операции с ним побайтно. Если заранее знать в какой регистровой паре идет параметр, то можно объявить байтовые переменные на каждый регистр и использовать их.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
07.02.2011, 16:13 4
Это делается элементарно средствами стандартного Си, совершенно не заботясь в каких именно регистрах передаётся этот многобайтовый (хоть двух, хот четырёх, хоть восми-байтовый, сколько в регистры влезет) параметр.
Код
void Foo(uint16_t value)
{
union
{
uint16_t v;
uint8_t bytes[sizeof(value)];
};

v = value;

PORTA = bytes[0];
PORTB = bytes[1];
}
Всё предельно просто, переносимо и стандартно. Можно в одно объединение запихать структуру их нескольких параметров. Правда, индексировать массив bytes лучше только костантными выражениями, иначе компилятор засунет все параметры в стек в нужном порядке и будет брать по индексу оттуда.
0
07.02.2011, 16:13
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
07.02.2011, 19:38 5
ну с таким же успехом можно было бы попробовать использовать transperent_union, тогда и переменную не стоит декларировать. Но вот с регистрами былобы все намного прозрачнее.
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
07.02.2011, 19:59 6
transperent_union - вещь удобная, но нестандартная.
Покажите код "с регистрами" на Си, который был-бы прозрачнее. Понастоящему прозрачным он будет только на асме.
Двух-байтовая переменная в WinAvr передаётся в регистрах r24 и r25, младшая и старшая часть соответственно (четырёх байтовая r22, r23, r24, r25).
Прозрачный код в студию.
0
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
08.02.2011, 11:42 7
Цитата Сообщение от miyvir
transperent_union - вещь удобная, но нестандартная.
Покажите код "с регистрами" на Си, который был-бы прозрачнее. Понастоящему прозрачным он будет только на асме.
твоя правда. на С полюбому ренерирует парочку лишних операций. Да еще рулетка со входными параметрами. надо попробовать на асме наваять. Если кому интересно, вот код:
Код
  rikystir char b0 asm("r25");
rikystir char b1 asm("r24");

int spi (int aData )
{
SPDR = b0;
while(!(SPSR & (1<<SPIF)));
b0 = SPDR;
SPDR = b1;
while(!(SPSR & (1<<SPIF)));
b1= SPDR;
return aData;
}
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 13:52 8
И получилась "верёвка достаточно длинная чтоб застрелиться". При первом же использовании.
Этот код будет работать не так как вы ожидаете. Что вернёт эта функция?
Два байта прочинанных из SPI? Нет. Она всегда будет возвращать то значение, которое её передали:
Код
int spi (int aData )
mov   r20, r24
mov   r19, r25

out   0x0f, r25   ; 15

sbis   0x0e, 7   ; 14
rjmp   .-4

in   r18, 0x0f   ; 15

out   0x0f, r24   ; 15
sbis   0x0e, 7   ; 14
rjmp   .-4

in   r18, 0x0f   ; 15

mov   r24, r20
mov   r25, r19
ret
К тому-же компилятор выдает предупреждения:
warning: call-clobbered rikystir used for global rikystir variable

Так гораздо стандартнее и чище:
Код
int spi (int aData )
{
union
{
int localData;
uint8_t bytes[2];
};
localData = aData;

SPDR = bytes[0];
while(!(SPSR & (1<<SPIF)));
bytes[0] = SPDR;
SPDR =  bytes[1];
while(!(SPSR & (1<<SPIF)));
bytes[1]= SPDR;
return localData;
}
И результат правильный и предсказуемый:
Код
out   0x0f, r24   ; 15
sbis   0x0e, 7   ; 14
rjmp   .-4
in   r24, 0x0f   ; 15
out   0x0f, r25   ; 15
sbis   0x0e, 7   ; 14
rjmp   .-4
in   r25, 0x0f   ; 15
ret
Upd. поправил.
0
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
08.02.2011, 19:49 9
данный код вообще не будет компилиться. . где объявляется v ? хотя выводы верные. я был уверен, что создастся новая переменная в какой-нибудь паре регистров, которые предваритеьно засунет в стек. Произошло все с точностья до наоборот.

спасибо, за демонстрацию
0
miyvir
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.02.2011, 20:04 10
О, блин скопипастил не от туда. Там localData а не v, конечно.
0
svd71
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
08.02.2011, 20:09 11
Цитата Сообщение от miyvir
О, блин скопипастил не от туда. Там localData а не v, конечно.
Код
int spi1 (int aData )
{
union
{
int localData;
uint8_t bytes[2];
} v;
v.localData = aData;

SPDR = v.bytes[0];
while(!(SPSR & (1<<SPIF)));
v.bytes[0] = SPDR;
SPDR =  v.bytes[1];
while(!(SPSR & (1<<SPIF)));
v.bytes[1]= SPDR;
return v.localData;
}
0
08.02.2011, 20:09
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.02.2011, 20:09

Странная проблема с WINAVR
Передали нам проект на ATXmega128A1, естественно встал вопрос компиляции его на &quot;своем&quot;...

WinAvr и inline функции
Здравствуйте уважаемые форумчане. В общем без долгих вступлений, решил я перейти с асм на Си. Для...

Опять указатели в WinAVR
Чтото никак не могу сладить с указателями в программе на СИ У меня два массива символов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.