Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Указатель на структуру
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
otrog
Здравствуйте.
Подскажите пожалуйста допустимо-ли так делать на C(CodeVision)?
Объявлена структура:
Код
struct TParameters
{
  unsigned int ADC_Value;
  unsigned int temperature[2];
  unsigned long suit;

  unsigned int CRC16;
};                  

struct TParameters Parameters;

В main-е есть вот что:
Код
// передача данных в комп
ptr = &Parameters;
Parameters.CRC16 = CRC16(ptr, sizeof(Parameters) - 2);
for (i=0;i<sizeof(Parameters);i++) { USART_Transmit(*ptr++); } // передать результаты измерений в УАРТ

Интересует применимость работы со структурами через указатели.

И еще CodeVision выдает warning"(358): suspicious pointer conversion" на строку "ptr = &Parameters;".
Что это может означать?
Спасибо.
_Bill
Цитата(otrog @ Jul 7 2006, 14:52) *
Здравствуйте.
Подскажите пожалуйста допустимо-ли так делать на C(CodeVision)?
Объявлена структура:
Код
struct TParameters
{
  unsigned int ADC_Value;
  unsigned int temperature[2];
  unsigned long suit;

  unsigned int CRC16;
};                  

struct TParameters Parameters;

В main-е есть вот что:
Код
// передача данных в комп
ptr = &Parameters;
Parameters.CRC16 = CRC16(ptr, sizeof(Parameters) - 2);
for (i=0;i<sizeof(Parameters);i++) { USART_Transmit(*ptr++); } // передать результаты измерений в УАРТ

Интересует применимость работы со структурами через указатели.

И еще CodeVision выдает warning"(358): suspicious pointer conversion" на строку "ptr = &Parameters;".
Что это может означать?
Спасибо.

Нет, неправильно. Вы должны объявить ptr как указатель на char и явно задать преобразование типа:
Код
   ptr = (char *)&Parameters;
otrog
Цитата(_Bill @ Jul 7 2006, 15:59) *
Нет, неправильно. Вы должны объявить ptr как указатель на char и явно задать преобразование типа:
Код
   ptr = (char *)&Parameters;

Спасибо
Код
   ptr = (char *)&Parameters;

помогло cheers.gif .
указатель объявлен так:
Код
  unsigned char *ptr;

И всеже при обращении к структуре через указатель не будет-ли нарушаться порядок передачи байтов?
beer_warrior
Цитата
И всеже при обращении к структуре через указатель не будет-ли нарушаться порядок передачи байтов?

Нет не будет. Но надо учитывать, что при разнотипных данных, они могут быть выровнены по длине наибольшего. Т.е. если между двумя int16 затешеться int8 компилятор дополнит его до 16 бит нулями.
Обычно это некритично, но при обмене по последовательному каналу может неожиданно измениться длина посылки и смещение от начала. Следите за настройками компилятора.


И вопрос от себя:
Кто бы напомнил финт - читаю из внешней EEPROM, задавая адрес начала чтения. Хотелось бы описать содержимое EEPROM структурой и получать адрес чтения (смещение) из ее объявления.
IgorKossak
Цитата(beer_warrior @ Jul 7 2006, 15:42) *
Но надо учитывать, что при разнотипных данных, они могут быть выровнены по длине наибольшего. Т.е. если между двумя int16 затешеться int8 компилятор дополнит его до 16 бит нулями.
Обычно это некритично, но при обмене по последовательному каналу может неожиданно измениться длина посылки и смещение от начала. Следите за настройками компилятора.

Только не с AVR. Это семейство 8-битное и выравнивания данных в структурах не осуществляется.
Вот с ARM - другое дело.
unichorn
Цитата(beer_warrior @ Jul 7 2006, 16:42) *
И вопрос от себя:
Кто бы напомнил финт - читаю из внешней EEPROM, задавая адрес начала чтения. Хотелось бы описать содержимое EEPROM структурой и получать адрес чтения (смещение) из ее объявления.


Насчёт такого финта незнаю blink.gif , для этих целей я использую макросы.
GetSmart
Я не очень понял, что надо beer_warrior, но может это:

x = offsetof(__struct__, __field__);

__struct__ => структура типа
__field__ => поле внутри этой структуры
beer_warrior
Цитата
Только не с AVR. Это семейство 8-битное и выравнивания данных в структурах не осуществляется.
Вот с ARM - другое дело.

Не знаю как где, а gcc запросто - накалывался.
Есть и второй момент - приведенная структура явно описывает данные для обмена, и скорее всего с писюком, для которого это актуально.
Цитата
x = offsetof(__struct__, __field__);

Совершенно верно, только как это ручками написать? Когда-то, где-то подсмотрел, но уже забыл sad.gif
GetSmart
Ничё не знаю. Я прямо так и пишу в ИАРе под АРМ.

А вот как это описано в файле stddef.h
Код
#ifndef offsetof
  #define offsetof(T, member)     (__INTADDR__((&((T *)0)->member)))
#endif /* offsetof */

Тока не пойму зачем там лишняя пара скобок? Вторая, если считать снаружи.
beer_warrior
Именно то спасибо. А скобки... Это же весьма навороченный макрос, при вставке в текст приоритет операций может поменяться.
Макрос скобками не испортишь smile.gif
GetSmart
А вот и нет. Не внешние скобки. А сразу за внешними стоят двое подряд скобок. В этом какой-то смысл есть?
defunct
Цитата
Тока не пойму зачем там лишняя пара скобок? Вторая, если считать снаружи.

При беглом просмотре вроде нет в ней никакого смысла.
Попробуйте убрать ;>
otrog
Спасибо всем ответившим.
Но сомнения остались:
Цитата
Но надо учитывать, что при разнотипных данных, они могут быть выровнены по длине наибольшего. Т.е. если между двумя int16 затешеться int8 компилятор дополнит его до 16 бит нулями.
Обычно это некритично, но при обмене по последовательному каналу может неожиданно измениться длина посылки и смещение от начала. Следите за настройками компилятора.

Кстати в моей структуре смешаны unsigned int и unsigned long
Код
struct TParameters
{
  unsigned int ADC_Value;
  unsigned int temperature[2];
  unsigned long suit;

  unsigned int CRC16;
};                  

struct TParameters Parameters;

Это вызовет выравнивание до unsigned long?
Цитата
Только не с AVR. Это семейство 8-битное и выравнивания данных в структурах не осуществляется.
Вот с ARM - другое дело.

Т.е. если я одинаковую структуру подсуну разным компиляторам(для разного железа, напр. AVR и IBM PC), то при обмене структурами через UART посредством указателя, я получу несовместимые друг с другом системы?
Как же тогда быть?
unichorn
Неиспользовать для этих целей тип int и unsigned int. smile.gif
Заменить их на другой тип.
vet
Прочитать хелп по #pragma pack и использовать любые типы, какие заблагорассудится.
beer_warrior
Можно прагмой, в gcc для этих целей есть атрибут. Можно также задать соответсвующую настройку компилятора сразу для всего кода. Ничего страшного нет, нужно просто помнить об этом.
Сергей Борщ
Цитата(otrog @ Jul 11 2006, 09:31) *
Кстати в моей структуре смешаны unsigned int и unsigned long
Это вызовет выравнивание до unsigned long?

Это вызовет выравнивание по длине машинного слова. Для IBM PC, ARM это будет 4 байта, для MSP430 2 байта, для AVR - 1 байт.
Цитата(otrog @ Jul 11 2006, 09:31) *
Т.е. если я одинаковую структуру подсуну разным компиляторам(для разного железа, напр. AVR и IBM PC), то при обмене структурами через UART посредством указателя, я получу несовместимые друг с другом системы?
Как же тогда быть?
заводить для обмена временные переменные для которых тип структуры объявлен с #pragma pack
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.