Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Ага, только работать не будет (int по адресу 0x40003002). Честное слово, не могу понять, что Вам нужно получить в результате - структуру меню с возможностью загрузки из EEPROM? Зачем эти фиксированные адреса и прочие извращения? Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ). Например писать: BaudRate = Read_Eprom(10); StopBit = Read_Eprom(11); и так сто раз весьма утомительно. Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива. Может есть какие-то отлаженные решения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
YuraFCZ 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Если уж все элементы однотипные, то чем тогда не подходит предложенное простое решение - объявите их как массив, а для индекса используйте перечисление с "говорящими" названиями. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ). Например писать: BaudRate = Read_Eprom(10); StopBit = Read_Eprom(11); и так сто раз весьма утомительно. Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива. Может есть какие-то отлаженные решения? как я понимаю, фактически Вы хотите кешировать в ОЗУ некий набор параметров, хранящийся в NVRAM. в таком случае если структура конфигурации сложная, то необходимо оформить ее в виде структуры, и читатьиз NVRAM блоком примерно как Вы и собирались (путем приведения типа указателя), только я бы оформил такое чтение отдельной функцией. если же параметры конфигурации однотипные, и Вы всего лишь желаете их поименовать по-разному, объявляйте массив и адресуйте его элементы через enum. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом.Вовсе нет. Смотрите: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() структуры, но в коде при доступе к членам появляется в общем-то ненужное имя структуры. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Вовсе нет. Смотрите: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, не подскажете ли конструкцию??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Вообще-то типы переменных разные, но для упрощения я их привел к одному типу, нехваткой памяти я не жалуюсь... Простите за серость, но адресацию элементов через 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]); ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
digital 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба 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=0; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Большое спасибо всем! Буду пробовать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
digital 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба по поводу enum: не хорошо, так как заставляет сами заниматься преобразование типов /* Читаем из flash все в память */ void ReadFlashToRam(void) { unsigned int i; unsigned char *data; data=(unsigned char *)&Flash; for(i=0;i<sizeof(Flash);i++) data=EEpromRead(i); }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость MALLOY2 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Господа, что-то не понимаю следующего: Даю описание структуры 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; // Записываем по адресу некое значение Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vet 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба memset(&LocalSetup, 0, sizeof(Setup)) тогда уж. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость MALLOY2 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба А если такая ситуация :) for (c=0; c<sizeof(Setup); c++) *sptr++ = get_eeprom(BASE_IMAGE+c); // Записываем по адресу некое значение P.S. А првельней мне кажеться Read_eeprom(BASE_IMAGE, sptr, sizeof(Setup)); //:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 18 декабря, 2007 Опубликовано 18 декабря, 2007 · Жалоба Итак, общими усилиями получилось следующее: имеется некая структура типа 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 ? Если это делать явно, то модуль установочного меню раздуется весьма ощутимо, и будет проблемка синхронизации при изменении самой структуры(при изменении количества или названия элементов). Можно, конечно, переписать всю структуру, но критично время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 18 декабря, 2007 Опубликовано 18 декабря, 2007 · Жалоба Итак, общими усилиями получилось следующее: [..] Работает отлично, заморочек с чтением/записью разных типов данных нет. Большое спасибо!! я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, Read_EEPROM((u8 *)&config, MEM_ADDR, sizeof(config)); Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент. Мне нужно узнать его адрес и размерность. для этого есть макросы sizeof() и offsetof() например: Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 18 декабря, 2007 Опубликовано 18 декабря, 2007 · Жалоба я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, 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)); Уже сделал, большое спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться