CodeVision AVR в вопросах и ответах
удалить как пост ?
Последний раз редактировалось urry Сб мар 03, 2012 09:07:12, всего редактировалось 1 раз.
- Реклама
сделайте и структуру и массив в одном флаконе, используя union
Я плохо знаю кодевижин - вроде юнионы не работали в младших версиях - где-то с 2.3.4 надо версию
Код: Выделить всё
union{
struct {
int cnt_X ; //рабочий счетчик X
int cnt_Y ; //рабочий счетчик Y
int cnt_Z ; //рабочий счетчик Z
unsigned char cnt_c ; //размер основных врезок
unsigned char cnt_n ; //кол-во отрезов
unsigned char cnt_t ; //пауза стола
}wrk;
unsigned char arr[9];
}un;
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Работают и в младших.На 1.25.5 по крайней мере я их использовал.urry писал(а):Я плохо знаю кодевижин - вроде юнионы не работали в младших версиях - где-то с 2.3.4 надо версию
Последний раз редактировалось demiurg301 Сб мар 03, 2012 10:08:35, всего редактировалось 1 раз.
demiurg301 я ничего не говорю. лишь бы ляпнуть - мне откровенно влом искать 4-х летней давности проект, но я отчетливо помню глюк именно с битовыми полями в юнионах, который вылечился переходом на версию 2.3.4
Это была одна из причин, после чего я плюнул на кодевижин и перешел на винавр.
Это была одна из причин, после чего я плюнул на кодевижин и перешел на винавр.
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Код: Выделить всё
Вот и как поэлементно скопировать структуру в структуру, если непонятно как к элементу структуры обращаться по его порядковому номеру в структуре?typedef struct {
int cnt_X ; //рабочий счетчик X
int cnt_Y ; //рабочий счетчик Y
int cnt_Z ; //рабочий счетчик Z
unsigned char cnt_c ; //размер основных врезок
unsigned char cnt_n ; //кол-во отрезов
unsigned char cnt_t ; //пауза стола
}
wrk;
typedef eeprom struct {
int cnt_X ; //рабочий счетчик X
int cnt_Y ; //рабочий счетчик Y
int cnt_Z ; //рабочий счетчик Z
unsigned char cnt_c ; //размер основных врезок
unsigned char cnt_n ; //кол-во отрезов
unsigned char cnt_t ; //пауза стола
}
ee_wrk;
wrk X;
ee_wrk Y;
void copy(eeprom unsigned char *pE, unsigned char *pR)
{
unsigned char L=sizeof(*pE);
while (L--)
{
*pE++=*pR++;
};
};
гдето в программе
copy((eeprom unsigned char*)&Y,(unsigned char*)&X);
Но тут при переходе на другую платформу могут вылезти грабли.ПО идее...
- Реклама
А что это за действия? Не нравится компилятору эти строчки.demiurg301 писал(а):
wrk X;
ee_wrk Y;
это не действия это комментарий должен быть типа один юнион это х а второй это у.
там дальше где применение понятно становится.
Обновление блин что я пишу... Это объявление переменных свежеобъявленных типов (ee_wrk и wrk)
там дальше где применение понятно становится.
Обновление блин что я пишу... Это объявление переменных свежеобъявленных типов (ee_wrk и wrk)
Последний раз редактировалось vitalik_1984 Пн мар 05, 2012 22:19:42, всего редактировалось 1 раз.
В поисках истины человек развивается.
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Чо пишет?R_ura писал(а): А что это за действия? Не нравится компилятору эти строчки.
кстати у меня не на эти строчки ругается...
Warning: C:\Docs\Платы\Проекты AVR\1\1.c(18): 'eeprom' memory attribute ignored for type storage
атрибут памяти игнорирован для типа данных.
Проверил данные не помещаются в еепром
Warning: C:\Docs\Платы\Проекты AVR\1\1.c(35): suspicious pointer conversion
Подозрительная конверсия указателя.
Код: Выделить всё
}ee_wrk; атрибут памяти игнорирован для типа данных.
Проверил данные не помещаются в еепром
Код: Выделить всё
copy((eeprom unsigned char*)&Y,(unsigned char*)&X); Подозрительная конверсия указателя.
В поисках истины человек развивается.
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Не знаю, я так во внешнюю ПЗУшину пишу структуру из 15 массивов по 10 байт. Правда , насколько я понял, такая фишка возможна только в 8битках, потому как "выравнивает" по машинному слову.
wrk X;
eeprom ee_wrk Y;
Вот так запиши.А что это за действия? Не нравится компилятору эти строчки.
wrk X;
eeprom ee_wrk Y;
подозрительная ошибка исчезла 
Не нужно писать ЕЕпром при объявлении структуры.
А при объявлении переменной объявленного типа просто помещать в ее область вот так:
Не нужно писать ЕЕпром при объявлении структуры.
А при объявлении переменной объявленного типа просто помещать в ее область вот так:
Код: Выделить всё
typedef struct {
int cnt_X ; //рабочий счетчик X
int cnt_Y ; //рабочий счетчик Y
int cnt_Z ; //рабочий счетчик Z
unsigned char cnt_c ; //размер основных врезок
unsigned char cnt_n ; //кол-во отрезов
unsigned char cnt_t ; //пауза стола
}
type_wrk;
type_wrk X;
eeprom type_wrk Y; В поисках истины человек развивается.
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
В CV?
Видимо это фишка CVAVR - вот что в хелпе по этому поводу:
/* type definitions */
typedef eeprom struct {
int a;
char b[5];
} eeprom_struct_type;
/* variable declaration */
eeprom eeprom_struct_type struct1;
Видимо это фишка CVAVR - вот что в хелпе по этому поводу:
/* type definitions */
typedef eeprom struct {
int a;
char b[5];
} eeprom_struct_type;
/* variable declaration */
eeprom eeprom_struct_type struct1;
Именно тема ведь про него, но в таком виде как я написал все компилируется и помещается в ее сектор.
И вообще мне непонятно зачем создавать какие то лишние типы данных.
Что смысл меняется разве, если вы файл будете хранить на жестком диске или на внешнем флеш накопителе.Тип файла то от этого не поменяется.
Пример:
А когда добавляете typedef eeprom игнорируется.
Вот про typedef
И вообще мне непонятно зачем создавать какие то лишние типы данных.
Что смысл меняется разве, если вы файл будете хранить на жестком диске или на внешнем флеш накопителе.Тип файла то от этого не поменяется.
Странно у вас похоже какой то другой хелпdemiurg301 писал(а):В CV?
Видимо это фишка CVAVR - вот что в хелпе по этому поводу:
/* type definitions */
typedef eeprom struct {
int a;
char b[5];
} eeprom_struct_type;
/* variable declaration */
eeprom eeprom_struct_type struct1;
Код: Выделить всё
[<memory attribute>] struct [<structure tag-name>] {
[<type> <variable-name>[,<variable-name>, ...]];
[<type> [<bitfield-id>]:<width>[,[<bitfield-id>]:<width>, ...]];
...} [<structure variables>]; Пример:
Код: Выделить всё
/* Global structure located in EEPROM */
eeprom struct eeprom_structure {
char a;
int b;
char c[15];
} se; Вот про typedef
Код: Выделить всё
typedef <type definition> <identifier>; Код: Выделить всё
/* type definitions */
typedef unsigned char byte;
typedef struct {
int a;
char b[5];
} struct_type;
Код: Выделить всё
/* structure stored in EEPROM */
eeprom struct_type struct3;
В поисках истины человек развивается.
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
А что за версия? Я из 1.25.5 выложил.
Даёт error и говорит - область переменной должна соответствовать области описания.
Логика мне понятна - она не понятна компилятору 
Даёт error и говорит - область переменной должна соответствовать области описания.
Код: Выделить всё
Что смысл меняется разве, если вы файл будете хранить на жестком диске или на внешнем флеш накопителе.Тип файла то от этого не поменяется.ну намутили... Покажите, как сделать на юнионах и все - тем более, что еепром склонна к порче и необходимо считать контрольную сумму.
И, demiurg301,я что, один вижу подводный камень в этом выражении ??? Размер чего вернет ???
И, demiurg301,я что, один вижу подводный камень в этом выражении ??? Размер чего вернет ???
Код: Выделить всё
{
unsigned char L=sizeof(*pE); - Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Действительно. Туда надоurry писал(а): И, demiurg301,я что, один вижу подводный камень в этом выражении ??? Размер чего вернет ???![]()
sizeof(wrk);
А контрольную сумму можно хранить в этой же структуре.
PS А вот кстати - а если сделать на юнионах, то будет ли это работать везде, на любой платформе? У мну такая же хрень просто с преобразованием структуры в массив. При этом структура содержит ещё одну структуру
Это нормально,юнионы работают везде. Единственно, что при 16-32 битных компиляторах нельзя забывать о выравнивании по байту, иначе структура может занять неожиданное количество байт.
Например, так - для visual
Например, так - для visual
Код: Выделить всё
#pragma pack(push,1)
union bla bla bla
#pragma pack(pop)Версия 2.05.5а EVALdemiurg301 писал(а):А что за версия? Я из 1.25.5 выложил.
Ну вроде как в хелпе так и написано делать как я показал.Значит таким образом понятно.Тем более компилируется.demiurg301 писал(а):Логика мне понятна - она не понятна компилятору
И в ее сектор помещает убираешь eeprom из объявления переменной - не помещает.
visual что? studio?urry писал(а):Например, так - для visual
В поисках истины человек развивается.
ага
Всем спасибо за помощь. Разобрался вроде, хотя начинающему не так легко в особенности КВ вникнуть.)) Может еще кто будет над работой со структурами голову ломать, поэтому выложу то, что у меня получилось. Все функции работают правильно, без замечаний компилятора.
Неясны некоторые моменты.
При вызове функции
зачем перед &ee_wrk_1 определять тип данных (eeprom unsigned char*)&ee_wrk_1 и почему в скобках? Это такая особенность КВ или стандартная сишная вещь?
Что-то вообще непонятное возникло ... Вот скриншот отладчика. Дело в том, что функция чтения из еепром ( против нее стоит желтая стрелка), почему-то меняет значение ee_wrk_1.cnt_X, расположенного в ЕЕпром. Причем это изменение наблюдается только в окне Watch, а в окне памяти ЕЕпром не меняется.
К тому же обведенная красным строчка не меняет содержимое wrk.cnt_X, хотя в него должно скопироваться из ee_wrk_1.cnt_X то значение, которое он имеет в окне Watch. При этом та же строчка правильно копирует из еепром в рам значение, если его устновить в поле памяти ЕЕпром вручную.
Как это понимать, как глюк студии?
З.Ы. Где-то читал ,что из каких-то соображений ( не помню уже) рекомендовали не использовать начальные адреса еепром.

Да! нельзя ли где-то видеть, по какому адресу в еепром компилятор разместил ту или иную переменную?
Код: Выделить всё
#include <mega32.h>
//#include <stdlib.h>
//#include <string.h>
//#include <alcd.h>
//#include <delay.h>
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// определить тип данных
typedef struct {
int cnt_X ; //рабочий счетчик X
int cnt_Y ; //рабочий счетчик Y
int cnt_Z ; //рабочий счетчик Z
unsigned char cnt_c ; //размер основных врезок
unsigned char cnt_n ; //кол-во отрезов
unsigned char cnt_t ; //пауза стола
}
type_wrk;
type_wrk wrk, prg; // определить переменнse wrk, prg в рам типа type_wrk
eeprom type_wrk ee_wrk_1; // определить переменную ee_wrk_1 в eeprom типа type_wrk
eeprom type_wrk ee_wrk_2; // определить переменную ee_wrk_2 в eeprom типа type_wrk
//...................
//Ф-ция записывает данные в структуру *pE /EEprom/ из струтуры *pR /RAM/
void write_struct_to_eeprom (eeprom unsigned char *pE, unsigned char *pR, unsigned char size)
{
while (size--){*pE++=*pR++;};
};
//....................
//Ф-ция копирует данные в структуру *pR /RAM/ из струтуры *pE /EEprom/
void read_struct_from_eeprom (unsigned char *pR,eeprom unsigned char *pE, unsigned char size)
{
while (size--){*pR++=*pE++;};
};
//............
//Ф-ция копирует данные в структуру *pR /RAM/ из струтуры *pE /EEprom/
void copy_struct_to_struct_in_eeprom (eeprom unsigned char *pR,eeprom unsigned char *pE, unsigned char size)
{
while (size--){*pR++=*pE++;};
};
//....................
//Ф-ция копирует данные в структуру *p1 /RAM/ из струтуры *p2 /RAM/
void copy_struct_to_struct (unsigned char *p1, unsigned char *p2, unsigned char size)
{
while (size--){*p1++=*p2++;};
};
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void main(void)
{
while (1)
{
write_struct_to_eeprom ((eeprom unsigned char*)&ee_wrk_1,(unsigned char*)&wrk, sizeof(wrk));
read_struct_from_eeprom ((unsigned char*)&wrk,(eeprom unsigned char*)&ee_wrk_1,sizeof(prg));
copy_struct_to_struct ((unsigned char*) &wrk, (unsigned char*)&prg, sizeof(prg));
copy_struct_to_struct_in_eeprom ((eeprom unsigned char*)&ee_wrk_2,(eeprom unsigned char*)&ee_wrk_1,sizeof(ee_wrk_1));
}
}При вызове функции
Код: Выделить всё
write_struct_to_eeprom ((eeprom unsigned char*)&ee_wrk_1,(unsigned char*)&wrk, sizeof(wrk)); Что-то вообще непонятное возникло ... Вот скриншот отладчика. Дело в том, что функция чтения из еепром ( против нее стоит желтая стрелка), почему-то меняет значение ee_wrk_1.cnt_X, расположенного в ЕЕпром. Причем это изменение наблюдается только в окне Watch, а в окне памяти ЕЕпром не меняется.
К тому же обведенная красным строчка не меняет содержимое wrk.cnt_X, хотя в него должно скопироваться из ee_wrk_1.cnt_X то значение, которое он имеет в окне Watch. При этом та же строчка правильно копирует из еепром в рам значение, если его устновить в поле памяти ЕЕпром вручную.
Как это понимать, как глюк студии?
З.Ы. Где-то читал ,что из каких-то соображений ( не помню уже) рекомендовали не использовать начальные адреса еепром.
Да! нельзя ли где-то видеть, по какому адресу в еепром компилятор разместил ту или иную переменную?
Последний раз редактировалось R_ura Вт мар 06, 2012 23:12:35, всего редактировалось 4 раза.


