WinAVR продолжение :)

Sep 28, 2005 64 Replies

Hi All !



Вот написал прогу по сьему информации с датчика DALLAS 1822(термометр) и индикации на МЕЛТе. И уперся вот во что: есть переменная типа uint16_t, необходимо выкусить из нее первые 8бит (в остальных "0") и засунуть в переменую типа uint8_t (что бы потом разложить это число на сотни, десятки и единицы для вывода десятичными числами на индикатор).



Может кто знает как это сделать?



▌·▐·│▌·│··│ Среда, Сентябрь 28 2005 23:29 2·461▌32·23 Всего хорошего. Alexander.


Привет, Alexander !

28 Sep 05 , 22:29 Alexander Panasovsky писал к All:

AP> Вот написал прогу по сьему информации с датчика DALLAS 1822(термометр) AP> и индикации на МЕЛТе. И уперся вот во что: есть переменная типа AP> uint16_t, необходимо выкусить из нее первые 8бит (в остальных "0") и AP> засунуть в переменую типа uint8_t (что бы потом разложить это число на AP> сотни, десятки и единицы для вывода десятичными числами на индикатор).

AP> Может кто знает как это сделать?

гм. не понял вопроса. длялитлэндиана - b=uint8_t(a>>8);

. С уважением, Hикита. icq:240059686, lj-user:nicka_startcev ... Didn't I meet You in some other halluci-nation?

Привет, *Alexander*!

/среда, 28 сентября 2005/ *Alexander Panasovsky* писал(а) к *All* по поводу *WinAVR продолжение :):*

[кусь] AP> есть переменная типа uint16_t, необходимо выкусить из нее первые 8бит AP> (в остальных "0") и засунуть в переменую типа uint8_t (что бы потом AP> разложить это число на сотни, десятки и единицы для вывода десятичными AP> числами на индикатор).

Можно попробовать: UInt16_t raw; UInt8_t data;

data = *(((*UInt8_t)(&raw)) + 1); // или data = ((*UInt8_t)(&raw))[1];

Правда вариант с объединением наверное будет эффективнее.

Hello, Alexander Panasovsky! You wrote in conference fido7.ru.embedded to All on Wed, 28 Sep 2005 21:29:04 +0400:

AP> Вот написал прогу по сьему информации с датчика DALLAS AP> 1822(термометр) и индикации на МЕЛТе. И уперся вот во что: AP> есть переменная типа uint16_t, необходимо выкусить из нее AP> первые 8бит (в остальных "0") и засунуть в переменую типа AP> uint8_t (что бы потом разложить это число на сотни, десятки и AP> единицы для вывода десятичными числами на индикатор).

AP> Может кто знает как это сделать?

Разделить на 256.

dima

formatting link

Hello, Dennis Opanasenko! You wrote in conference fido7.ru.embedded to All on Thu, 29 Sep 2005 09:48:32 +0400:

DO> Вариант 1.

DO> uint16_t foo; DO> uint8_t bar; DO> bar = (uint8_t) var >> 8;

DO> Вариант 2.

DO> typedef union unionBW { DO> struct structBYTE { uint8_t LO; uint8_t HI; } BYTE; DO> uint16_t WORD; DO> } BW;

DO> BW foo; DO> uint8_t bar;

DO> foo.WORD = foobar; DO> bar = var.BYTE.HI;

DO> Как-нибудь так. Вариант 2 на WinAVR эффективнее.

а вариант

bar = var/256;

не эфективен? PICC просто подставляет старший байт.

dima

formatting link

"Alexander Panasovsky" <Alexander snipped-for-privacy@p23.f.n461.z2.fidonet.org> сообщил/сообщила в новостях следующее: news:MSGID_2=3A461=2F32.23 snipped-for-privacy@fidonet.org...

Вариант 1.

uint16_t foo; uint8_t bar; bar = (uint8_t) var >> 8;

Вариант 2.

typedef union unionBW { struct structBYTE { uint8_t LO; uint8_t HI; } BYTE; uint16_t WORD; } BW;

BW foo; uint8_t bar;

foo.WORD = foobar; bar = var.BYTE.HI;

Как-нибудь так. Вариант 2 на WinAVR эффективнее.

Денис.

Привет Alexander!

28 Sep 05 22:29, Alexander Panasovsky писал All:

uint16_t a; uint8_t b;

b = *(uint8_t*)&a;

Всего наилучшего, [Team PCAD 2000] Алексей М. ... В главной роли - Сильвестр с талоном.

Привет Dennis!

29 Sep 05 10:48, Dennis Opanasenko писал All:

DO> Вариант 1.

DO> uint16_t foo; DO> uint8_t bar; DO> bar = (uint8_t) var >> 8;

Ты хотел сказать bar = (uint8_t) foo >> 8; ?

Это выражение даст 0. :)

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Дареному письму в клуджи не смотрят.

Thu Sep 29 2005 12:22, Alex Mogilnikov wrote to Alexander Panasovsky:

AM> uint16_t a; AM> uint8_t b;

AM> b = *(uint8_t*)&a;

И имеем проблемыу имени больших и маленьких индейцев.

Thu Sep 29 2005 13:05, Alex Mogilnikov wrote to Dmitry Orlov:

AP>>> есть переменная типа uint16_t, необходимо выкусить из нее AP>>> первые 8бит

AP>>> Может кто знает как это сделать?

DO>> Разделить на 256.

AM> Это даст 8 _старших_, а не 8 _первых_ бит.

если для uint16_t 8 старших и 8 первых бит не одно и то же, то можно услышать определение 8 первых бит?

Привет Andrey!

29 Sep 05 08:03, Andrey Solomatov писал Alexander Panasovsky:

AS> Можно попробовать:

Лучше не надо. :)

AS> data = *(((*UInt8_t)(&raw)) + 1); AS> // или AS> data = ((*UInt8_t)(&raw))[1];

Оба выражения синтаксически некорректны.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Программисты и программистки! Выше флаг промежуточного переноса!

Привет Dmitry!

29 Sep 05 08:56, Dmitry Orlov писал Alexander Panasovsky:

AP>> есть переменная типа uint16_t, необходимо выкусить из нее AP>> первые 8бит

AP>> Может кто знает как это сделать?

DO> Разделить на 256.

Это даст 8 _старших_, а не 8 _первых_ бит.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Слепой Пью, Глухой Ем...

Привет, *Alex*!

/четверг, 29 сентября 2005/ *Alex Mogilnikov* писал(а) к *Andrey Solomatov* по поводу *WinAVR продолжение :):*

[кусь]

AS>> data = *(((*UInt8_t)(&raw)) + 1); AS>> // или AS>> data = ((*UInt8_t)(&raw))[1];

AM> Оба выражения синтаксически некорректны.

Ага. СинтАксис у Си такой, что провоцирует ошибки.

AS>> data = *(((UInt8_t*)(&raw)) + 1); AS>> // или AS>> data = ((UInt8_t*)(&raw))[1];

Кстати, предложенное Вами:

uint16_t a; uint8_t b; b = (uint8_t)&a;

некорректно *семантически*. Если компилер вообще пропустит такую бяку.

Привет, *Andy*!

/четверг, 29 сентября 2005/ *Andy Mozzhevilov* писал(а) к *Alex Mogilnikov* по поводу *WinAVR продолжение :):*

[кусь] AM> если для uint16_t 8 старших и 8 первых бит не одно и то же, то AM> можно услышать определение 8 первых бит?

Кстати, возможно я тупой. Но я тоже подумал вначале, что первые - это *младшие*. Поэтому, ИМО, безопаснее говорить "старший" и "младший" байт. ;)

Hello, Alex Mogilnikov! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Thu, 29 Sep 2005 12:05:13

+0400:

AM> Привет Dmitry!

AM> 29 Sep 05 08:56, Dmitry Orlov писал Alexander Panasovsky:

AP>>> есть переменная типа uint16_t, необходимо выкусить из нее AP>>> первые 8бит

AP>>> Может кто знает как это сделать?

DO>> Разделить на 256.

AM> Это даст 8 _старших_, а не 8 _первых_ бит.

Это не одно и тоже? Первый байт еще зависит от LE/BE, но первый бит, вроде как всегда старший.

dima

formatting link

Привет Andy!

29 Sep 05 12:33, Andy Mozzhevilov писал Alex Mogilnikov:

AM>> b = *(uint8_t*)&a;

AM> И имеем проблемыу имени больших и маленьких индейцев.

Это не ко мне. Уже сама задача получения _первого_ байта содержит эту проблему.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Старый глюк лучше новых двух...

Привет Andy!

29 Sep 05 12:35, Andy Mozzhevilov писал Alex Mogilnikov:

AM>> Это даст 8 _старших_, а не 8 _первых_ бит.

AM> если для uint16_t 8 старших и 8 первых бит не одно и то же, то AM> можно услышать определение 8 первых бит?

Я понимаю это как октет с меньшим адресом. Hапример, если переменная разположена по вдресу 0x1234, то первые 8 бит - это октет по адресу 0x1234, а вторые - октет по адресу 0x1235. А будут эти биты в числе младшими или старшими

- другой вопрос, действительно зависящий от роста индейцев.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Мы не можем ждать почты от аплинка. Взять ее у него - наша задача.

Hello Andrey.

Thu Sep 29 2005 08:03, Andrey Solomatov wrote to Alexander Panasovsky:

AS> data = *(((*UInt8_t)(&raw)) + 1); AS> // или AS> data = ((*UInt8_t)(&raw))[1];

Жуть какая. Вот из-за таких конструкций у меня и сложилось предубеждение против C. :)

Кстати, нормальный оптимизирующий компилятор, вроде IAR-овского, правильно воспринимает сдвиги на 8. Hапример, для MSP430:

// unsigned int UI; // unsigned char UC;

// UI = P1IN+300; MOV.B &0x20, R10 ADD.W #0x12c, R10

// UC = UI >> 8; SWPB R10 AND.B #0xff, R10

AS> Правда вариант с объединением наверное будет эффективнее.

Вряд ли, там ведь лишнее присваивание... Хотя, от оптимизации зависит.

Hо корректнее и понятнее будет написать что-то вроде

typedef unsigned int word; typedef unsigned char byte;

#define HIGH_BYTE(xw) (byte)((word)(xw) >> 8) #define LOW_BYTE(xw) (byte)((word)(xw) & 0xFF)

Конечно, это для случая 16-битного int.

Dimmy.

Hello Andrey.

Thu Sep 29 2005 13:37, Andrey Solomatov wrote to Alex Mogilnikov:

AM>> Оба выражения синтаксически некорректны.

AS> Ага. СинтАксис у Си такой, что провоцирует ошибки.

Так не надо на провокации поддаваться. Hе в смысле "не делать ошибок" :), а не использовать write-only фичи и криптографический стиль.

Dimmy.

Thu Sep 29 2005 19:29, Dennis Opanasenko wrote to All:

DO> Hе, WinAVR тупит, подставляет лишнюю загрузку и очистку старшего байта: DO> b = a/256; DO> a2c: 89 81 ldd r24, Y+1 ; 0x01 DO> a2e: 9a 81 ldd r25, Y+2 ; 0x02 DO> a30: 89 2f mov r24, r25 DO> a32: 99 27 eor r25, r25 DO> a34: 8b 83 std Y+3, r24 ; 0x03

Ну дык тип данных по-умолчанию в языке Си - int. Если нужен другой тип, нужно указать это явно.

С уважением, Денис

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required