Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сложная обработка битов 
:(
    Опции темы
=Женек=
Дата 16.4.2006, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Измеритель температуры Возвращает структуру:

extern struct __ds18b20_scratch_pad_struct
       {
       unsigned char temp_lsb,temp_msb,
                temp_high,temp_low,
                conf_register,
                res1,
                res2,
                res3,
                crc;
       } __ds18b20_scratch_pad;

Нужно сделать следующее: первые 4 бита младшего байта temp_lsb - это 

дробные доли градуса, причем один бит равен это 0.0625. 3-8 биты 

старшего байта temp_msb - это сигнатура - + или -. Все что между ними - температура.

Я сделал все, кроме программы перевода температуры в понятное число. Нужна подпрограмма, делающая из этих двух байтов число типа float.У меня ну никаких мыслей..

Только операторы попроще, без всяких навороченных библиотек - я пишу 

под AVR C, в нем только stdio.h

Заранее спасибо! 
PM MAIL   Вверх
DigitalDummy
Дата 16.4.2006, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 7.4.2006
Где: В подвале шоколад ной фабрики.

Репутация: нет
Всего: 2



Я понял что Вам нужно и сделать это очень даже не сложно, но нельзя ли более понятно объяснить порядок бит?

Чтобы такие вещи объяснять правильно, по-моему, нужно указывать кол-во бит и к чему они относятся строго по порядку...

Например, если у меня есть 16 битное значение типа unsigned short (WORD) в котором храниться цвет, то я объясняю так:

unsigned short Color, в котором:
  5 бит - значение цвета R (красный)
  6 бит - значение цвета G (зелёный)
  5 бит - значение цвета B (синий).

Жду отчёта от Вас! А то гадать что у Вас в структуре и где в невыспавшемся состоянии мне трудно...  smile  
PM WWW   Вверх
Hiehachi
Дата 17.4.2006, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 27.12.2005
Где: Ukraine->Odess a

Репутация: нет
Всего: нет



Разачаровываю.
Датчик DS18B20  фирмы Dallas Semi. Имеет точность 0.5 градуса. Диапазон -40 до +125. 
Вам еще со знаковыми числами парится прийдется.

Добавлено @ 01:44 
Еще нет.
Самое сложное по сравнению с переводом градусов  это мудренный алгоритм CRC по полиному.
Я с примеров с DALLAS на x51 процессор перевел этот алгоритм на AVR CPU . Если найду исходник на CRC скину, или напишите на email. [email protected] чтоб напомнить.
Он самый сложный по сравнению с переводом структуры. А проверять его надо! 
PM MAIL WWW ICQ   Вверх
=Женек=
Дата 17.4.2006, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Не понял в чем вы разочаровываете?
Знаки - это последние 5 бит числа. ИХ определение входит в саму задачу.

А поподробне о битах - пожалуйста:


имеется 16 бит. Слева направо:

5 бит- либо все 1, либо все 0 - соответственно  минус или плюс
следующие 7 бит - температура в градусах.
следующие 4 бита - дробная часть градусов. Один бит равен 1/16 или 0,0625 градуса.

Hiehachi, а поподробней про полиномы... 
PM MAIL   Вверх
=Женек=
Дата 17.4.2006, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Что, неужели никто не знает?

Вот вам функция, как она есть в примере Codevision:
Код


static flash int conv_delay[4]={100,200,400,800};
// valid temp. bit mask depending on the resolution
static flash unsigned bit_mask[4]={0xFFF8,0xFFFC,0xFFFE,0xFFFF};

//////////////////////////////////////////////////////////////////////////

float ds18b20_temperature(unsigned char *addr)
{
unsigned char resolution;
if (ds18b20_read_spd(addr)==0) return -9999;
resolution=(__ds18b20_scratch_pad.conf_register>>5) & 3;
if (ds18b20_select(addr)==0) return -9999;
w1_write(0x44);
delay_ms(conv_delay[resolution]);
if (ds18b20_read_spd(addr)==0) return -9999;
w1_init();
return (*((int *) &__ds18b20_scratch_pad.temp_lsb) & bit_mask[resolution])*0.0625;
}


вся обработка в строке return. Только по-моему она  обрабатывает только младший байт... 
PM MAIL   Вверх
Hose
Дата 18.4.2006, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 11.4.2006

Репутация: 1
Всего: 1



Не буду писать решения(нет времени проверять), но подскажу принцип работы.
Все сводится к 2ум бинарным операциям: битовый сдвиг(>>) и побитовое "И"(&). У тебя число MyChislo 2 байта, тобишь 16 бит. Тебе нужно достать, например, температуру(6 - 12 биты).
xxxxtttttttxxxxx   делаешь битовый сдвиг вправо на 5 бит(temp = MyChislo >>5). получаешь
00000xxxxttttttt   А потом вырезаешь правые 7 бит с помощью битового "И"
temp = temp & 0x7F. 0x7F - это шестнадцатиричное число, в двоичном виде представляется как 7 единиц. В результате получаешь 
0000000ttttttt 
PM MAIL   Вверх
Earnest
Дата 18.4.2006, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Специально для программистов "обожающих" работу с битами, придуманы битовые структуры:
Что-то в таком роде:
Код

// union, чтобы можно было присваивать значения "целиком"
union CMyValue
{
    DWORD m_dwValue;
    struct   // общее число битов не должно превышать DWORD
    {
        unsigned m_One: 3;
        signed    m_Two: 5;
        // ... и т.д.
        unsigned m_Nine: 4;
    };
};

void foo()
{
    CMyValue Val;
    Val.m_dwValue = 0xffffffff;
    size_t One = Val.m_One;
    int    Two = Val.m_Two;
}

В результате получается все то же самое, что написал Hose, только сдвиги и отсечения берет на себя компилятор.  


--------------------
...
PM   Вверх
=Женек=
Дата 19.4.2006, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Hose, я сделал так:

Код

temperature=((((msb<<8)|lsb) & 0x07F0)>>4) +(lsb & 0x000F)*0.0625;

if (((msb<<8)|lsb)>>11 !=0) temperature=-temperature;



что в принципе отражает алгоритм, предложенный вами


правда сейчас не могу вывести это на экран...

Посмотрите, нет ли элементарной ошибки в коде:
Код

float t;
t=0.2;
sprintf(s,"%f",t);


почему-то не работает 
PM MAIL   Вверх
SergeCpp
Дата 19.4.2006, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 15
Всего: 124



  • double t;
  • s куда указывает?
 

Это сообщение отредактировал(а) SergeCpp - 19.4.2006, 10:14
PM MAIL WWW ICQ   Вверх
=Женек=
Дата 19.4.2006, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



В смысле? Кто сказал, что это указатель?
Впрочем, дело было в настройках CodeVision. КОд теперь работает. Есть только одна маленгькая проблема, может быть опишу ее позже. 
PM MAIL   Вверх
=Женек=
Дата 19.4.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: нет
Всего: 1



Ура! Получилось!

Код

temperature=(int)((((__ds18b20_scratch_pad.temp_msb<<8)| __ds18b20_scratch_pad.temp_lsb) & 0x07F0)>>4)+__ds18b20_scratch_pad.temp_lsb & 0x000F)*0.0625;

/////////////////////

        temp=ds18b20_temperature(&rom_code[i,0]);
        sprintf(s,"%+.2f", temp);

 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0747 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.