Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как разбить 2 байта по байту))
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Xenom0rph
Вообщем задача такая, у меня есть число типа unsigned int;
Мне надо записать его в ячейку eeprom. Ячейка это один байт, значит для хранения типа unsigned int требуется две ячейки. Так вот как мне разбить это число по байту и записать в ячейки, а когда мне потребуется это число я его обратно склеил?
Знаю, что как то делается это просто, там страший и младший разряд... и т.д. но вот что то немогу никак вьехать в эти разряды.
Палыч
Например:
unsigned int A;
unsigned char b, c;
b= A&0xFF;
c= A>>8;
A=(c<<8)|b;

или через union...
Xenom0rph
Цитата(Палыч @ Oct 17 2008, 15:29) *
Например:
unsigned int A;
unsigned char b, c;
b= A&0xFF;
c= A>>8;
A=(c<<8)|b;

или через union...


У меня A становится просто b и все.
Допустим A = 2008
после выполнения этого кода
b = 216
c = 7
A = 216
Огурцов
На чем пишем ?

В WinAVR/GCC можно сделать так

#define Vxl_obtain_eeprom_word(aValue, aDefault) (aValue != 0xFFFF ? aValue: aDefault)

static uint16 mTasks_target_temp;
EEMEM static uint16 eTasks_target_temp;

mTasks_target_temp = Vxl_obtain_eeprom_word (eeprom_read_word(&eTasks_target_temp), 700);
eeprom_write_word(&eTasks_target_temp, mTasks_target_temp);
Палыч
Цитата(Xenom0rph @ Oct 17 2008, 14:59) *
У меня A становится просто b и все.
Ошибочка вышла...

A=((unsigned int)c<<8) | b;
Demeny
Цитата(Xenom0rph @ Oct 17 2008, 15:24) *
Вообщем задача такая, у меня есть число типа unsigned int;
Мне надо записать его в ячейку eeprom. Ячейка это один байт, значит для хранения типа unsigned int требуется две ячейки. Так вот как мне разбить это число по байту и записать в ячейки, а когда мне потребуется это число я его обратно склеил?
Знаю, что как то делается это просто, там страший и младший разряд... и т.д. но вот что то немогу никак вьехать в эти разряды.

Не нужно усложнять. eeprom с логической точки зрения ничем не отличается от "обычной" памяти. Поэтому и хранить там данные можно байтами, словами и целыми структурами. А о правильном расположении байтов пусть заботится компилятор.
Код
unsigned int __eeprom MyArray[10];
unsigned int A, B;
...
MyArray[0] = A;  // тут компилятор сам разложит переменную A побайтно и вставит инструкции побайтного сохранения в eeprom
...
B = MyArray[0]; // тут будет проделана обратная работа.

Примечание: в разных компиляторах квалификатор __eeprom может называться по-разному, но смысл тот же - указать компилятору, что память выделяется в зоне eeprom.
Палыч
Цитата(Demeny @ Oct 17 2008, 15:09) *
Не нужно усложнять. eeprom с логической точки зрения ничем не отличается от "обычной" памяти. Поэтому и хранить там данные можно байтами, словами и целыми структурами. А о правильном расположении байтов пусть заботится компилятор.
Не все трансляторы понимают квалификатор __eeprom. Там, где этого квалификатора - нет, поможет изучение файла eeprom.h
Xenom0rph
Цитата(Палыч @ Oct 17 2008, 16:07) *
Ошибочка вышла...

A=((unsigned int)c<<8) | b;

2Пылыч Спасибо.

А по поводу прямо назначить область eeprom, что то не очень у меня это получаеться, компилятор CVAVR, там есть типо unsigned char eeprom a[10] только вот что то не заносит он туда ничего(( а пишет в data stack.
DiMomite
В CVAVR надо писать так: eeprom unsigned char a[10];
Xenom0rph
Цитата(DiMomite @ Oct 18 2008, 02:52) *
В CVAVR надо писать так: eeprom unsigned char a[10];

Вот спасибо, "Век живи, век учись"
smalcom
вроде небыло варианта

unsigned int uiA = 0xABCD
unsigned char ucB = ((unsigned char*)&uiA)[0]
unsigned char ucC = ((unsigned char*)&uiA)[1]

или
unsigned int uiA = 0xABCD
unsigned char ucpT = (unsigned char*)&uiA
unsigned char ucB = *ucpT
unsigned char ucC = *(++ucpT)
zltigo
Цитата(smalcom @ Oct 19 2008, 04:00) *
вроде небыло варианта

Очень жаль, что теперь "eсть" sad.gif. Зачем создавать уродство на ровном месте без всякой на то надобности? Кроме общего уродства дополнительные проблемы на не 8bit платформах....
smalcom
Цитата
Очень жаль, что теперь "eсть" sad.gif. Зачем создавать уродство на ровном месте без всякой на то надобности? Кроме общего уродства дополнительные проблемы на не 8bit платформах....

прочитай топик сверху, а не снизу. и мнение свое держи при себе тем более, что оно не верное.
zltigo
Цитата(smalcom @ Oct 19 2008, 13:49) *
...и мнение свое держи при себе...

В некоторых случаях молчать просто нельзя.
lks
Цитата(Палыч @ Oct 17 2008, 15:29) *
или через union...


Ну да.

union LOG { unsigned char aa[2], unsigned int dd; }ff;
unsigned char bb, сс;
unsigned int big;

dd.ff = big;
bb = ff.aa[0];
cc = ff.aa[1];

Вроде бы так должно быть? smile.gif
zltigo
Цитата(lks @ Oct 19 2008, 15:29) *
Вроде бы так должно быть? smile.gif

Отнюдь sad.gif
Цитата
union LOG { unsigned char aa[2], unsigned int dd; }ff;

int штука коварная и непереносимая в некоторых случаях. В Вашем случае 'unsigned short'
И зачем делать union c обезличенным массивом sad.gif
union my_short {
unsigned short dd;
unsigned char lo;
unsigned char hi;
} ff;
И вообще, если не описывать union каждый раз, то
typedef union my_short {
unsigned short dd;
unsigned char lo;
unsigned char hi;
} my_short_t;

my_short_t ff;

Цитата
unsigned int big;

unsigned short big;
Цитата
dd.ff = big;

ff.dd = big;
С точностью до наоборот. И вообще промежуточная переменная big просто лишняя - надо сразу использовать ff.dd
Цитата
bb = ff.aa[0];
cc = ff.aa[1];

bb = ff.lo;
cc = ff.hi;
Сергей Борщ
Цитата(zltigo @ Oct 19 2008, 18:16) *
union my_short {
unsigned short dd;
unsigned char lo;
unsigned char hi;
} ff;
Код
union   my_short {
    unsigned short dd;
    struct
    {
        unsigned char lo;
        unsigned char hi;
    };
} ff;
zltigo
Цитата(Сергей Борщ @ Oct 20 2008, 09:08) *
Код
union   my_short {
    unsigned short dd;
    struct
    {
        unsigned char lo;
        unsigned char hi;
    };
} ff;

Да, конечно! ерунду написал sad.gif.Вдогонку - для переносимости на не 8bit платформы надо структуру еще паковать....
g-gabber
__asm{
mov ax,[value]
movzx ecx,al
movzx edx,ah
}
zltigo
Цитата(g-gabber @ Oct 22 2008, 10:07) *
__asm{
mov ax,[value]
movzx ecx,al
movzx edx,ah
}

К чему этот ASM i386 экзерсис, тем более, что разбивкой на БАЙТЫ тут и не пахнет?
g-gabber
Цитата(zltigo @ Oct 22 2008, 10:25) *
К чему этот ASM i386 экзерсис, тем более, что разбивкой на БАЙТЫ тут и не пахнет?

Упс, то что он под AVR пишет я не увидел,
А вобще, под x86 это самый быстый способ разбрать 2 байтовый int по байтам.
zltigo
Цитата(g-gabber @ Oct 22 2008, 10:49) *
А вобще, под x86 это самый быстый способ разбрать 2 байтовый int по байтам.

1) в ASM ничего бить вообще не надо - все и так доступно, ибо система адресации
позволяет произвольный доступ.
2)написанная ASM вставка есть вещь в себе и использовать ее из С вообще нельзя.
3) Это не для x86 а для 386, как минимум
4) int вообще-то на 386 не двухбайтовый
5) разбили не по байтам а по 32bit
6)movzx не эффективная по производительности команда, посему и насчет быстрый это не так.
g-gabber
Цитата(zltigo @ Oct 22 2008, 20:18) *
1) в ASM ничего бить вообще не надо - все и так доступно, ибо система адресации
позволяет произвольный доступ.
2)написанная ASM вставка есть вещь в себе и использовать ее из С вообще нельзя.
3) Это не для x86 а для 386, как минимум
4) int вообще-то на 386 не двухбайтовый
5) разбили не по байтам а по 32bit
6)movzx не эффективная по производительности команда, посему и насчет быстрый это не так.


1) То что ASM тут не любят я уже понял,
2) В теме нигде не написанно какой компилятор используется.
3) x86 для меня линейка процессоров, про < 386 я даже и не вспоминал,
4) Какого размера int зависит от компилятора и того как её задекларировать,
Например VS C++ иногда использует int для храния 2 байт(16 бит), а long для 4 байт(32 бит),
5) Я тоже разбивал по 32 битным регистрам (ecx, edx).
6) А с этим я могу поспорить,,,
movzx занимает 3 такта, значит
Код
movzx ecx,al
movzx edx,ah

займёт 6 тактов,

Возьмём код который предложил Палыч.
Код
b= A&0xFF;
c= A>>8;

теперь переведём его в asm, получается следующее:
Код
mov ecx,eax; 1 такт
and  ecx.0xff; 1 такт
mov edx,eax; 1 такт
shl   edx,8 ; 3 такт


По сути получается одно и тоже, но у меня 2 команды, а тут 4, и не нужно забывать что процессору нужно на 2 команды больше обработать,

Инофрмацию я брал от сюда http://www3.itu.edu.tr/~kesgin/mul06/intel/index.html
За базу я брал 486,

p.s. А вообще, давайте жить дружно!
zltigo
Цитата(g-gabber @ Oct 23 2008, 14:20) *
1) То что ASM тут не любят я уже понял,

Совершенно не верно. Я люблю, и судя по Вашему экзерсизу, простите, знаю его много лучше. Не любю применение ASM ни к селу ни к городу особенно ввиде инлайновых вставок часто сносящих крышу оптимизатору.
Цитата
2) В теме нигде не написанно какой компилятор используется.

Достаточно того, что используется КОМПИЛЯТОР
Цитата
3) x86 для меня линейка процессоров, про < 386 я даже и не вспоминал,

Ну, ну...
Цитата
4) Какого размера int зависит от компилятора и того как её задекларировать,
Например VS C++ иногда использует int для храния 2 байт(16 бит), а long для 4 байт(32 бит),

Глупости не надо говорить, поскольку "про < 386 я даже и не вспоминал".
Цитата
6) А с этим я могу поспорить,,,
movzx занимает 3 такта, значит
Код
movzx ecx,al
movzx edx,ah

займёт 6 тактов,

А чего тут спорить, если
xor edx,edx
mov dl,ah
короче на любезных Вашему сердцу пентиумах, не говоря уже о 386 с его 6 тактами на каждый movzx.
Причем mov и xor на пентиумах конверизируются, а movzx - нет. Короче полный облом с попыткой писать на ASM sad.gif
Цитата
p.s. А вообще, давайте жить дружно!

Легко smile.gif, если будете более обдуманно писать.
g-gabber
Цитата(zltigo @ Oct 23 2008, 22:31) *
Совершенно не верно. Я люблю, и судя по Вашему экзерсизу, простите, знаю его много лучше. Не любю применение ASM ни к селу ни к городу особенно ввиде инлайновых вставок часто сносящих крышу оптимизатору.

Достаточно того, что используется КОМПИЛЯТОР

Ну, ну...

Глупости не надо говорить, поскольку "про < 386 я даже и не вспоминал".

А чего тут спорить, если
xor edx,edx
mov dl,ah
короче на любезных Вашему сердцу пентиумах, не говоря уже о 386 с его 6 тактами на каждый movzx.
Причем mov и xor на пентиумах конверизируются, а movzx - нет. Короче полный облом с попыткой писать на ASM sad.gif

Легко smile.gif, если будете более обдуманно писать.



CPUID без инлайна не вывозишь.
А вообще не хочу спорить ... уверен стажа у меня больше ...
Лучше помогите мне настроить xds560 и OMAP ...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.