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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> struct - непонятка с косвенной адресацией
Andrei_S
сообщение Dec 17 2007, 09:51
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Господа, что-то не понимаю следующего:

Даю описание структуры

typedef struct SettingMenu
{
unsigned int
P1,
P2,
...
...
P100;
} Setup;

Где-то в модуле(да неважно где) создаем новую структуру типа Setup

Setup LocalSetup;

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

Setup LocalSetup;// Создаем структуру типа Setup
Setup *sptr;// Указатель
...
...

sptr = & LocalSetup;// Определяем адрес структуры

for (c=0; c<100; c++)
{
*sptr = c; // Записываем по адресу некое значение
sptr++; // Увеличиваем адрес
}

Это классический пример С, значения пишутся во все поля без проблем

В Keil-е номер не проходит - ругается на разные типы данных строки *sptr = c, хотя теоретически я получил в качестве адреса структуры адрес первого поля этой структуры.
Как бы это правильно разрулить???
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 17 2007, 10:05
Сообщение #2


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 17 2007, 12:51) *
Setup *sptr;// Указатель
for (c=0; c<100; c++)
{
*sptr = c; // Записываем по адресу некое значение
sptr++; // Увеличиваем адрес
}
[/b]
Это классический пример С, значения пишутся во все поля без проблем

насчет классики не уверен, особенно в том месте, где Вы указываете имя структуры сперва в стандарте С++ (после struct), а потом еще и в classic - после закрывающей скобки, но в принципе любой уважающий себя современный компилятор не должен разрешать подобные вольности.
1. переменная sptr имеет тип Setup *, соответственно, *sptr - типа Setup, а Вы пытаетесь инициализировать ее с помощью переменной типа (предположительно) int
2. даже если приведенную Вами конструкцию скомпилировать путем явного приведения типа (то есть, написав
Код
*(( int *)sptr) = c;

все равно инструкция sptr++ выполнится неправильно (Вы, очевидно, ожидаете инкремента на размер int, а получите - на размер Setup)
Не могу сказать, что это пример хорошего кода, но очевидно Вы в классическом примере упустили тот факт, что там, думаю, было написано так:
Код
int *sptr = (*int)&LocalSetup; // Указатель
...

в этом случае программа соберется и будет работать примерно так, как Вы рассчитываете

Сообщение отредактировал sergik_vrn - Dec 17 2007, 10:08
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Dec 17 2007, 10:18
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Хотите массив - используйте!!!
typedef struct SettingMenu
{
unsigned int P[100];
} Setup;
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 10:35
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Спасибо sergik_vrn , попробую...
А насчет массива:
имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище...
Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив.

Спасибо за ответы...
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 17 2007, 10:52
Сообщение #5


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 17 2007, 13:35) *
Спасибо sergik_vrn , попробую...
А насчет массива:
имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище...
Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив.

Спасибо за ответы...

1. тот вариант, что я привел - вовсе не оптимальный, просто в нем исправлены Ваши ошибки
2. адрес элемента массива это <имя_массива>+<номер элемента>
3. также настоятельно рекомендую воспользоваться массивом и не заниматься ерундой. судя из того, что я понял по приведенному исходнику, Вам массив и нужен, причем даже без всякой обрамляющей структуры

пассаж насчет указания адресов "лежания" для переменных до моего понимания не дошел
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 17 2007, 11:25
Сообщение #6


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

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Цитата(sergik_vrn @ Dec 17 2007, 13:52) *
...
2. адрес элемента массива это <имя_массива>+<номер элемента>
...


Я так понял, что Andrei_S говорит о том, что в структуре каждой переменной он может задать осмысленное имя, в то время как для массива потребуется некий список на "бумажке", чтоб знать какой элемент что означает.
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 11:35
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(sergik_vrn @ Dec 17 2007, 13:52) *
1. тот вариант, что я привел - вовсе не оптимальный, просто в нем исправлены Ваши ошибки
2. адрес элемента массива это <имя_массива>+<номер элемента>
3. также настоятельно рекомендую воспользоваться массивом и не заниматься ерундой. судя из того, что я понял по приведенному исходнику, Вам массив и нужен, причем даже без всякой обрамляющей структуры

пассаж насчет указания адресов "лежания" для переменных до моего понимания не дошел


Пояснение по адресам "лежания":
имеется установочное меню, включающее в себя несколько десятков пунктов. Каждому пункту меню соответствует своя переменная. В процессе работы используются значения этих переменных.
Если будет сделан массив, как Вы предлагаете, то мне придется помнить, какой из элементов массива за что отвечает.
Да, будет очень удобно в этот массив переписывать данные, например, из ПЗУ в одном единственном цикле
Код
for(a=0;a<Lengh;a++){Array[a]=Read_Eprom(a);}
,
но в программе помнить о том, какая ячейка чему соответствует - весьма тяжело, и не исключены ошибки.
Используя прямую адресацию в RAM, типа

Код
unsigned int P1x __at(0x00000000000000000)
unsigned int P2x __at(0x00000000000000001)


я смогу в одном цикле выполнить действия аналогичные примеры выше, но только с косвенной адресацией

Код
unsigned int *sptr;

sptr = & P1x;
for(a=0;a<Lengh;a++;sptr++){*sptr=Read_Eprom(a);}


Значения из Eprom автоматом перепишутся по нужным адресам.
Только для этого я предполагаю явное указание адреса.
А в теле программы читать и писать, например, пункт меню Baud_Rate гораздо понятнее и приятнее чем, например, Array[64]
Go to the top of the page
 
+Quote Post
zhevak
сообщение Dec 17 2007, 11:41
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



присоединяюсь к sergik_vrn

Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом. Тем более, автор сам использует цикл для перебора элементов.

Сложно запомнить? Хорошо. А для чего тогда используются комментарии?

Комирование структуртоже никто не отменял

Код
__eeprom Setup eeSetup;
...
Setup LocalSetup;// Создаем структуру типа Setup
Setup *sptr;// Указатель

LocalSetup = eeSetup;
...
*sptr = eeSetup;


Сообщение отредактировал zhevak - Dec 17 2007, 11:52


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 17 2007, 11:48
Сообщение #9


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

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Цитата(Andrei_S @ Dec 17 2007, 14:35) *
...
Используя прямую адресацию в RAM, типа

Код
unsigned int P1x __at(0x00000000000000000)
unsigned int P2x __at(0x00000000000000001)


я смогу в одном цикле выполнить действия аналогичные примеры выше, но только с косвенной адресацией

Код
unsigned int *sptr;

sptr = & P1x;
for(a=0;a<Lengh;a++;sptr++){*sptr=Read_Eprom(a);}


Интересно, ну и что Вы хотели этим пояснить:
Код
unsigned int P1x __at(0x00000000000000000)
unsigned int P2x __at(0x00000000000000001)

07.gif

Это не скомпилиться без явного приведения типа в нормальном компиляторе:
Код
sptr = & P1x;

если P1x - структура.
Go to the top of the page
 
+Quote Post
vmp
сообщение Dec 17 2007, 11:53
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Почитайте про перечислимый тип (enum).
Именно он напрашивается в качестве индекса массива. Вы получите и массив, допускающий последовательный перебор, и мнемонические имена элементов этого массива.
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 17 2007, 12:01
Сообщение #11


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

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Цитата(zhevak @ Dec 17 2007, 14:41) *
...
Сложно запомнить? Хорошо. А для чего тогда используются комментарии?
...


Согласитесь, что работать всеже удобнее, когда имя переменной сразу дает полное представление о ней без необходимости плодить пачками комментарии возле строк типа:
Код
array[12] = 9600; // здесь я установил BaudRate


К тому же в случае необходимости есть возможность легко ввести в структуру данные других типов.
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 12:01
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(Юрий Санвальд @ Dec 17 2007, 14:48) *
Интересно, ну и что Вы хотели этим пояснить:
Код
unsigned int P1x __at(0x00000000000000000)
unsigned int P2x __at(0x00000000000000001)

07.gif

Это не скомпилиться без явного приведения типа в нормальном компиляторе:
Код
sptr = & P1x;

если P1x - структура.



Код
unsigned int  P111 __at (0x40003000);
unsigned int  P112 __at (0x40003002);


int main(void){

unsigned int *aptr;

aptr = & P111;
for(hhh=0;hhh<10;hhh++)
{
  *aptr=hhh;
  aptr++;
}



}


Пардон, скомпилилось без вопросов...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 17 2007, 12:12
Сообщение #13


Гуру
******

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



Цитата(Andrei_S @ Dec 17 2007, 15:01) *
Пардон, скомпилилось без вопросов...

Ага, только работать не будет (int по адресу 0x40003002).
Честное слово, не могу понять, что Вам нужно получить в результате - структуру меню с возможностью загрузки из EEPROM? Зачем эти фиксированные адреса и прочие извращения?
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 17 2007, 12:18
Сообщение #14


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

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Цитата(Andrei_S @ Dec 17 2007, 15:01) *
Пардон, скомпилилось без вопросов...


Пардон, почему то решил что P1x ранее объявлена как некая структура. Но не понял зачем Вы так делаете, что мешает просто объявить
Код
STRUCT_TYPE P1x;


и работать с указателем на нее, чем укладывать все в определенном месте RAM, а потом все арвно придется создавать указатель типа структуры на этот адрес wacko.gif
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 17 2007, 12:20
Сообщение #15


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 17 2007, 14:35) *
...
А в теле программы читать и писать, например, пункт меню Baud_Rate гораздо понятнее и приятнее чем, например, Array[64]

убедился, что все понял правильно, просто формулировка про адреса меня смутила.
посмотрите в треде Вам кто-то уже советовал использовать enum, присоединяюсь. наиболее правильно собирать однотипные элементы в массив, а для адресации на уровне идентификатора использовать enum
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 12:26
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(aaarrr @ Dec 17 2007, 15:12) *
Ага, только работать не будет (int по адресу 0x40003002).
Честное слово, не могу понять, что Вам нужно получить в результате - структуру меню с возможностью загрузки из EEPROM? Зачем эти фиксированные адреса и прочие извращения?



Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ).

Например писать:
BaudRate = Read_Eprom(10);
StopBit = Read_Eprom(11); и так сто раз весьма утомительно.

Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива.
Может есть какие-то отлаженные решения?
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 17 2007, 12:34
Сообщение #17


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

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Если уж все элементы однотипные, то чем тогда не подходит предложенное простое решение - объявите их как массив, а для индекса используйте перечисление с "говорящими" названиями. smile.gif
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 17 2007, 12:34
Сообщение #18


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 17 2007, 15:26) *
Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ).

Например писать:
BaudRate = Read_Eprom(10);
StopBit = Read_Eprom(11); и так сто раз весьма утомительно.

Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива.
Может есть какие-то отлаженные решения?

как я понимаю, фактически Вы хотите кешировать в ОЗУ некий набор параметров, хранящийся в NVRAM.
в таком случае если структура конфигурации сложная, то необходимо оформить ее в виде структуры, и читатьиз NVRAM блоком примерно как Вы и собирались (путем приведения типа указателя), только я бы оформил такое чтение отдельной функцией. если же параметры конфигурации однотипные, и Вы всего лишь желаете их поименовать по-разному, объявляйте массив и адресуйте его элементы через enum.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 17 2007, 12:36
Сообщение #19


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zhevak @ Dec 17 2007, 13:41) *
Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом.
Вовсе нет. Смотрите:
Код
typedef struct
{
    uint8_t Size_X;
    uint8_t Size_Y;
    uint8_t Bitmap[];
}  bmp_font_t;
Здесь Size_X и Size_Y имеют такой же тип, что и члены следующего за ними массива, но включать их в этот массив было бы очень ненаглядно.
Как я понял, автор вопроса хранит в структуре данные, которые хоть и имеют один и тот же интегральный тип, но логически не эквивалентны. Если я не прав, то красивым и верным будет решение, предложенное vmp, если же я прав, то подход автора в осмысленным именовании каждого члена безусловно правильный, а для удобства на каких-то операциях работать со структурой как с массивом можно использовать union:
Код
typedef union
{
    struct
    {
        uint8_t member1;
        uint8_t member2;
        uint8_t member3;
    };
    uint8_t   Array[1];
} setup_t
использование здесь массива размером 1 является некоторым хаком чтобы не именовать структуру. При проверке индекса массива нужно использовать sizeof() от union. Если структуре дать имя, тогда можно в качестве размера массива задать sizeof() структуры, но в коде при доступе к членам появляется в общем-то ненужное имя структуры.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 12:52
Сообщение #20


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(Сергей Борщ @ Dec 17 2007, 15:36) *
Вовсе нет. Смотрите:
Код
typedef struct
{
    uint8_t Size_X;
    uint8_t Size_Y;
    uint8_t Bitmap[];
}  bmp_font_t;
Здесь Size_X и Size_Y имеют такой же тип, что и члены следующего за ними массива, но включать их в этот массив было бы очень ненаглядно.
Как я понял, автор вопроса хранит в структуре данные, которые хоть и имеют один и тот же интегральный тип, но логически не эквивалентны. Если я не прав, то красивым и верным будет решение, предложенное vmp, если же я прав, то подход автора в осмысленным именовании каждого члена безусловно правильный, а для удобства на каких-то операциях работать со структурой как с массивом можно использовать union:
Код
typedef union
{
    struct
    {
        uint8_t member1;
        uint8_t member2;
        uint8_t member3;
    };
    uint8_t   Array[1];
} setup_t
использование здесь массива размером 1 является некоторым хаком чтобы не именовать структуру. При проверке индекса массива нужно использовать sizeof() от union. Если структуре дать имя, тогда можно в качестве размера массива задать sizeof() структуры, но в коде при доступе к членам появляется в общем-то ненужное имя структуры.


Вообще-то типы переменных разные, но для упрощения я их привел к одному типу, нехваткой памяти я не жалуюсь...

Простите за серость, но адресацию элементов через enum я еще не делал...
Pls, не подскажете ли конструкцию???
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 17 2007, 13:27
Сообщение #21


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 17 2007, 15:52) *
Вообще-то типы переменных разные, но для упрощения я их привел к одному типу, нехваткой памяти я не жалуюсь...

Простите за серость, но адресацию элементов через enum я еще не делал...
Pls, не подскажете ли конструкцию???

если разные, делайте как делали, это правильно
по поводу enum:
Код
const u8 CONFIG_SIZE = 3;
enum Config_Items { baud_rate = 0, parity, stop_bits }; // и т.д. - по необходимости
typedef u8 Configuration[CONFIG_SIZE];
Configuration my_config;

for (int i = 0; i < CONFIG_SIZE; ++i)
    my_config[i] = Read_EEEPROM(i);

...

Set_UART(my_config[baud_rate], my_config[parity], my_config[stop_bits]);
...
Go to the top of the page
 
+Quote Post
digital
сообщение Dec 17 2007, 13:28
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 229
Регистрация: 3-02-06
Из: Санкт-Петербург
Пользователь №: 13 974



union {
unsigned char mass[10];
struct
{
unsigned char Num;
unsigned char Rate;
unsigned char Baud;
unsigned char Led;
unsigned char P4;
unsigned char P5;
unsigned char P6;
unsigned char P7;
unsigned char P8;
struct {
unsigned char bit0:1;
unsigned char bit1:2;
unsigned char bit2:3;
} bits;
} rec;
} eeprom;

eeprom.rec.Num=0;
for(u=0;u<sizeof(eeprom);u++)
eeprom.mass[u]=0;
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 17 2007, 13:33
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Большое спасибо всем!
Буду пробовать...
Go to the top of the page
 
+Quote Post
digital
сообщение Dec 17 2007, 13:47
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 229
Регистрация: 3-02-06
Из: Санкт-Петербург
Пользователь №: 13 974



по поводу enum:

не хорошо, так как заставляет сами заниматься преобразование типов



/* Читаем из flash все в память */
void ReadFlashToRam(void)
{
unsigned int i;
unsigned char *data;

data=(unsigned char *)&Flash;
for(i=0;i<sizeof(Flash);i++)
data[i]=EEpromRead(i);
};
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Dec 17 2007, 14:40
Сообщение #25


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Господа, что-то не понимаю следующего:

Даю описание структуры

typedef struct SettingMenu
{
unsigned int
P1,
P2,
...
...
P100;
} Setup;

Где-то в модуле(да неважно где) создаем новую структуру типа Setup

Setup LocalSetup;

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

Setup LocalSetup;// Создаем структуру типа Setup
Setup *sptr;// Указатель
...
...

sptr = & LocalSetup;// Определяем адрес структуры

for (c=0; c<100; c++)
{
*sptr = c; // Записываем по адресу некое значение
sptr++; // Увеличиваем адрес
}

Это классический пример С, значения пишутся во все поля без проблем

В Keil-е номер не проходит - ругается на разные типы данных строки *sptr = c, хотя теоретически я получил в качестве адреса структуры адрес первого поля этой структуры.
Как бы это правильно разрулить???


Я всегда делал так.
Код
Setup LocalSetup;     // Создаем структуру типа Setup
char  *sptr;// Указатель на char (Если структра выровнена по памяти можно и другие типы использовать для более быстрого доступа все зависит от типа CPU и его команд)

sptr = (char*)&LocalSetup;// Определяем адрес структуры
for (c=0; c<sizeof(Setup); c++)  *sptr++ = 0x00; // Записываем по адресу некое значение
Go to the top of the page
 
+Quote Post
vet
сообщение Dec 17 2007, 14:47
Сообщение #26


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



memset(&LocalSetup, 0, sizeof(Setup)) тогда уж.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Dec 17 2007, 16:29
Сообщение #27


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



А если такая ситуация smile.gif
Код
for (c=0; c<sizeof(Setup); c++)  *sptr++ = get_eeprom(BASE_IMAGE+c); // Записываем по адресу некое значение


P.S. А првельней мне кажеться
Код
Read_eeprom(BASE_IMAGE, sptr, sizeof(Setup)); //:)
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 18 2007, 08:34
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Итак, общими усилиями получилось следующее:
имеется некая структура типа setup (все-таки структура а не массив, т.к. типы данных разные )

Код
typedef struct SettingMenu
{
   char Parametr1;
   char Parametr2;
   int    Parametr3;
   char Array[10];
   float Parametr5;
   ..........

};Setup
..........
..........
Setup LocalSetup;// Структура
char  *sptr; // Указатель


sptr = (char*)&LocalSetup;// Получили адрес
a=sizeof(Setup);// и размер

for (c=0; c<a; c++)
{
    *sptr++ = ReadEprom(StartSetupAdress+c);
}



Работает отлично, заморочек с чтением/записью разных типов данных нет. Большое спасибо!!

Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент.
Мне нужно узнать его адрес и размерность.

Указано явно:
Код
sptr = (char*)&LocalSetup.Parametr5;
a = sizeof(LocalSetup.Parametr5);// Получили размерность, например, он float - 4 байта
for (c=0; c<a; c++)
{
    *sptr++ = ReadEprom(StartSetupAdress+N+c);// где N-адрес в ПЗУ Параметра 5
}


Такой вопрос: как это сделать не с явным указанием, а по номеру элемента структуры
например, ReadSinglePar(LocalSetup,5), где 5 - пятый элемент структуры, т.е. Parametr5 ?

Если это делать явно, то модуль установочного меню раздуется весьма ощутимо, и будет проблемка синхронизации при изменении самой структуры(при изменении количества или названия элементов).
Можно, конечно, переписать всю структуру, но критично время.
Go to the top of the page
 
+Quote Post
sergik_vrn
сообщение Dec 18 2007, 09:00
Сообщение #29


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

Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491



Цитата(Andrei_S @ Dec 18 2007, 11:34) *
Итак, общими усилиями получилось следующее:
[..]
Работает отлично, заморочек с чтением/записью разных типов данных нет. Большое спасибо!!

я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, Read_EEPROM((u8 *)&config, MEM_ADDR, sizeof(config));

Цитата(Andrei_S @ Dec 18 2007, 11:34) *
Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент.
Мне нужно узнать его адрес и размерность.

для этого есть макросы sizeof() и offsetof()
например:
Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1));
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 18 2007, 10:26
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(sergik_vrn @ Dec 18 2007, 12:00) *
я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, Read_EEPROM((u8 *)&config, MEM_ADDR, sizeof(config));
для этого есть макросы sizeof() и offsetof()
например:
Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1));


Уже сделал, большое спасибо!
Go to the top of the page
 
+Quote Post
tag
сообщение Dec 18 2007, 10:45
Сообщение #31


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

Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561



Цитата(sergik_vrn @ Dec 17 2007, 15:20) *
убедился, что все понял правильно, просто формулировка про адреса меня смутила.
посмотрите в треде Вам кто-то уже советовал использовать enum, присоединяюсь. наиболее правильно собирать однотипные элементы в массив, а для адресации на уровне идентификатора использовать enum




...как вариант

#define BAUD_RATE 2


unsigned int Settings[64];


....


Settings[BAUD_RATE] = 9600;
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 18 2007, 11:48
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Цитата(tag @ Dec 18 2007, 13:45) *
...как вариант
#define BAUD_RATE 2
unsigned int Settings[64];
....
Settings[BAUD_RATE] = 9600;

В принципе, ничего, и ремарки не нужны... Но годится в случае одного типа переменных.
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 18 2007, 12:31
Сообщение #33


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970




Цитата
..как вариант#define BAUD_RATE 2

и до этого доходили аж 3 страницы smile.gif
Go to the top of the page
 
+Quote Post
Andrei_S
сообщение Dec 18 2007, 13:01
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535



Код
Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1));

Но а все-таки, а как уйти от названия элементов структуры к порядковому номеру элемента этой структуры?

Хотелось бы вместо названия поля info_1 писать номер этого поля, например 1

Например, я последовательно вывожу на индикацию эти 100 параметров структуры:
N1 120
N2 300
....
и т.д.

При нажатии кнопок я могу изменять значения и перезаписывать их в ПЗУ
Если я, например, изменил один из параметров, то для записи в ПЗУ я должен сначала сопоставить значение переменной N и название соответствующего поля типа:
Код
switsh(N)
{
  case 0: Addr = offsetof(Config_Type, info_1); break;
  case 1: Addr = offsetof(Config_Type, info_2); break;
....
и так все 100 параметров


Можно ли это модифицировать?
Go to the top of the page
 
+Quote Post
vmp
сообщение Dec 18 2007, 13:10
Сообщение #35


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Цитата(Andrei_S @ Dec 18 2007, 11:34) *
Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент.
Мне нужно узнать его адрес и размерность.

Код
//-------------------------------------------------------------
// Вычисление смещения до поля в структуре
//-------------------------------------------------------------
#define OFFSET(type,field) ((char *)&(((type *)0)->field) - (char *)0)


Как пользоваться - OFFSET(тип_структуры, имя_элемента) выдаст смещение от начала структуры до указанного элемента. Размер элемента можно получить по sizeof(type.field).

Цитата(Andrei_S @ Dec 18 2007, 16:01) *
Но а все-таки, а как уйти от названия элементов структуры к порядковому номеру элемента этой структуры?

Хотелось бы вместо названия поля info_1 писать номер этого поля, например 1


Тогда я бы сделал еще одну табличку с дескрипторами полей. Например, массив структур с описателями параметров. В него заносил бы тип поля, смещение от начала, размер, формат вывода, строку с именем, минимальное и максимальное значения и т.д. А индекс этого массива для читабельности описал как enum. smile.gif
Go to the top of the page
 
+Quote Post
_dem
сообщение Dec 18 2007, 14:07
Сообщение #36


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Если типов данных сравнительно немного, сделайте отдельные массивы на отдельные типы, а потом адресуйтесь по define по смещениям
Go to the top of the page
 
+Quote Post

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

 


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


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