реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
Skaf
сообщение Jun 20 2009, 11:25
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 228
Регистрация: 4-06-09
Пользователь №: 49 940



Всем привет. Пишу на Си (WinAVR) для AVR. Есть у меня 32-х битная переменная

unsigned long int A;

Мне надо передать ее по SPI протоколу. Как это эффективнее всего сделать?
Что-то типа

spi_master_transmit(A);
spi_master_transmit(A>>8);
spi_master_transmit(A>>16);
spi_master_transmit(A>>24);

является ли это наиболее эффективным методом?

Сообщение отредактировал Skaf - Jun 20 2009, 11:26
Go to the top of the page
 
+Quote Post
Herz
сообщение Jun 20 2009, 11:36
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287



Смотря что является критерием эффективности. Можно оформить переменную А как union.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Jun 20 2009, 13:54
Сообщение #3


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Компилятор должен адекватно принимать сдвиги кратные восьми и сразу брать нужную часть. Без сдвигов, естественно.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 20 2009, 15:37
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Skaf @ Jun 20 2009, 14:25) *
является ли это наиболее эффективным методом?

Запихивание параметра, не соответствующего определению функции, меня лично напрягает. Типы переменных лучше преобразовывать явно.

union выглядит проще. Или через указатель:

char * a;
a=(char *) &A;
spi (*a); a++;
spi (*a); a++;
spi (*a); a++;
spi (*a);

Про эффективность сказали. Вот проверьте все варианты и нам расскажите, какой наиболее эффективныый smile.gif
А синхронизация слова как будет происходить?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 20 2009, 16:10
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 20 2009, 19:37) *
union выглядит проще. Или через указатель

Если забыть про эндианизм.

Цитата(Dog Pawlowa @ Jun 20 2009, 19:37) *
spi (*a); a++;

spi(*a++); мы все-таки на C пишем, а не на Бейсике.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 21 2009, 23:14
Сообщение #6


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



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

Код
spi_SendData( U8 *pData, int size)
{
    while (size--)
        spi_master_transmit( *pData++ );
}


Потом с помощью такой функции можно отправлять что угодно, long, struct и т.д. и будет всегда одинаково:

spi_SendData( &A, sizeof( A ));

Цитата
Мне надо передать ее по SPI протоколу.

SPI - это не протокол.
Go to the top of the page
 
+Quote Post
777777
сообщение Jun 22 2009, 06:48
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Skaf @ Jun 20 2009, 15:25) *
spi_master_transmit(A);
spi_master_transmit(A>>8);
spi_master_transmit(A>>16);
spi_master_transmit(A>>24);

является ли это наиболее эффективным методом?

Посмотри на ассемблерный код и все увидишь сам.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 22 2009, 07:31
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(defunct @ Jun 22 2009, 02:14) *
Код
spi_SendData( U8 *pData, int size)

Тогда - немного не актуальное на сегодня, но уточнение
spi_SendData( U8 *pData, size_t size)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 22 2009, 15:21
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



тогда и ещё немногоrolleyes.gif
Код
#define SPI_SEND(PX)  spi_SendData(PX, sizeof(*PX))


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Злодей
сообщение Jun 23 2009, 06:44
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Что есть size_t?

И зачем тут
Код
size_t fwrite (const void *data, size_t size, size_t count, FILE *stream);

раздельные size и count? На практике ведь их можно переставлять местами, главное чтоб не изменилось их произведение.

Сообщение отредактировал Злодей - Jun 23 2009, 06:47
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 23 2009, 09:52
Сообщение #11


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Злодей @ Jun 23 2009, 10:44) *
Что есть size_t?
Это хороший тон программированияsmile.gif
На самом деле этот тип возвращает оператор sizeof и, как правило, size_t эквивалентен int.
Поэтому, его применение на восьмибитных платформах должно быть обоснованным и только там, где действительно uint8_t мал в качестве размера или количества.
Как бонус, при использовании size_t происходит некое самодокументирование программы...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jun 23 2009, 10:09
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Так а в чем глубокий смысл использования size_t? Почему плохо писать просто int?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 23 2009, 13:42
Сообщение #13


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Глубокого смысла я не вижу и если заглянуть в stddef.h (gcc), то можно увидеть, что этот тип определён как
Код
typedef __SIZE_TYPE__ size_t;
а __SIZE_TYPE__ в свою очередь зависит от платформы VAX, BSD и т.д. и разрядности процессора.
Таким образом получается, что размерность типа size_t, как и типа int платформозависима.
И я исходя из этих соображений с осторожностью применяю size_t и не использую int в принципе.
До глубинного смысла НИКТО никогда не докопается, т.к. всё свёдётся к недавнему спору о типе bool для СИ.
В конечном итоге Ваше личное соглашение с самим собой должно быть достигнуто относительно этого и Вы должны будете ему следовать.
И ещё иногда size_t может быть мал для некоторых случаев. Так что панацеи не существует.
Больше на эту тему мне и сказать нечего...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
alexashko
сообщение Jun 29 2009, 08:31
Сообщение #14





Группа: Новичок
Сообщений: 13
Регистрация: 29-06-09
Пользователь №: 50 729



проще через указатели на байты, ну типа:

SPI_Send(*(char*)(unsigned long int)Data);
SPI_Send(*(char*)(unsigned long int)Data+1);
SPI_Send(*(char*)(unsigned long int)Data+2);
SPI_Send(*(char*)(unsigned long int)Data+3);
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th July 2025 - 19:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01391 секунд с 7
ELECTRONIX ©2004-2016