Перейти к содержанию
    

Преобразовать данные с DS18B20 в строку printf

Здравствуйте.

Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же.

Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) .

Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры.

Младшая тетрада temp2 имеет дробную часть температуры.

Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4

Голову сломал не знаю как сделать :(

Помогите пожалуйста. Понятно что вопрос дилетанта.

Работаю в CodeVisionAVR. МК atmega8.

Спасибо.

Изменено пользователем Pilot134

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

все домой ушли, так что если вечер свободен то можете этот кусок подправить для вывода дробной части

 

#ifdef DS18B20
    #define DS18X20_SHIFT 4
#endif


lsb = OneWireReadByte( mask );
msb = OneWireReadByte( mask ); 
s16 curr_temper_cels = (msb << 8) + lsb;
if( curr_temper_cels & (1 << 15) )
{
curr_temper_cels = -curr_temper_cels;
curr_temper_cels = (curr_temper_cels * 10) >> DS18X20_SHIFT;
curr_temper_cels = -curr_temper_cels; //  Restore sign.
}
else
{
curr_temper_cels = (curr_temper_cels * 10) >> DS18X20_SHIFT;
}

printf( "temper=%d", curr_temper_cels  );

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте.

Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же.

Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) .

Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры.

Младшая тетрада temp2 имеет дробную часть температуры.

Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4

Голову сломал не знаю как сделать :(

Помогите пожалуйста. Понятно что вопрос дилетанта.

Работаю в CodeVisionAVR. МК atmega8.

Спасибо.

printf("temp=%2x.%d", temp1, temp2);

 

Но что делать с отрицательной температурой?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

printf("temp=%2x.%d", temp1, temp2);

До отрицательной ещё не добрался.

Вставил Ваш вариант и не заработало :(

 

все домой ушли, так что если вечер свободен то можете этот кусок подправить для вывода дробной части

 

#ifdef DS18B20
    #define DS18X20_SHIFT 4
#endif


lsb = OneWireReadByte( mask );
msb = OneWireReadByte( mask ); 
s16 curr_temper_cels = (msb << 8) + lsb;
if( curr_temper_cels & (1 << 15) )
{
curr_temper_cels = -curr_temper_cels;
curr_temper_cels = (curr_temper_cels * 10) >> DS18X20_SHIFT;
curr_temper_cels = -curr_temper_cels; //  Restore sign.
}
else
{
curr_temper_cels = (curr_temper_cels * 10) >> DS18X20_SHIFT;
}

printf( "temper=%d", curr_temper_cels  );

 

Посмотрел код и у меня вопрос.

Строчка:

s16 curr_temper_cels = (msb << 8) + lsb; - переменная формата sig int curr_temper_cels.

Мы в неё записываем старший байт (temp1) сдвинутый 8 раз влево и прибавляем младший байт.

___

Строчка:

curr_temper_cels = (curr_temper_cels * 10) >> DS18X20_SHIFT; - берёт переменную curr_temper_cels и умножает её на 10, сдвигает 4-е раза вправо и вновь вписывает в переменную curr_temper_cels

Правильно я понимаю? Спасибо.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

До отрицательной ещё не добрался.

Вставил Ваш вариант и не заработало :(

А тут работает http://codepad.org/eTaPDzDX

А в чем неработоспособность заключается?

printf("Hello World") работает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

printf("Hello World") работает?

Это работает :)

Вопрос в том чтобы преобразовать значение с термометра DS18B20 в строчку printf("...") и чтобы температура выводилась в виде 25.6

Я считал температуру с датчика DS18B20 и она содержится в 2-х байтах. В старшем (temp1) и младшем (temp2).

Я уже научился выводить целую часть температуры:

temperatura = ((temp1)<<4)|(temp2>>4);
printf("temp = %d C\r\n",temperatura);

и вижу на компе текст (комп с микроконтроллером общаются по усарту)

temp = 26 С

А вот с дробной частью пока проблема :(

Отрицательные температуры ещё не делал :)

 

А тут работает http://codepad.org/eTaPDzDX

:)

там то работает.

Дело в том что у термометра DS18B20 температура считывается определённым образом.

Как видно из скрина старший байт только в младшей тетраде содержит значения целой части температуры.

А младший - старшая тетрада содержит также целую часть, а младшая тетрада младшего байта содержит только лишь дробную часть.

Спасибо что отозвались!

post-34227-1380729632_thumb.jpg

Изменено пользователем Pilot134

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело в том что у термометра DS18B20 температура считывается определённым образом.

Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные.

Попробуйте так: http://codepad.org/oKLnmEul

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные.

Виноват :(

Попробуйте так: http://codepad.org/oKLnmEul

Спасибо! То что нужно :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень сильно извиняюсь!

Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное.

Причём двоично-десятичное содержит 3 значящих тетрады.

Т.е. число типа int 0000 0011 0100 0101 (2dec) нужно преоборазовать в int 0000 0001 0101 1001 (Bin)

где 0000 0011 0100 0101 - число 0345 двоично-десятичное

а 0000 0001 0101 1001 - двоичное число 345.

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное.

Причём двоично-десятичное содержит 3 значящих тетрады.

Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну почему у всех мода такая - побайтно интерпретировать температуру DS18x20?! ведь в описании вполне доступно написано, что 2 первых байта представляют температуру в дополнительном двоичном коде в долях градуса! то есть вам надо 2 байта рассматривать как обычный int (16-битный, естественно!) - и будет вам температура со знаком! только поделить на разрешающую способность предварительно, т.е. если режим датчика для 9-битной температуры, то разрешающая способность 0,5 градуса, т.е. двухбайтное число типа int надо поделить на 2.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой...

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только пожалуйста не ругайтесь. Но что-то немного не понял :(

У устройства есть вывод значений температуры (порог) на дисплей.

Кнопками я могу редактировать это значение и вписываю (например) цифры 26,5. Всего 3 цифры.

Мне нужно чтобы при достижении этой температуры включалось реле и сигнализировало (т.е. сравнивать значения на дисплее с показаниями с термометра).

Соответственно у меня есть переменные zifr_1 = 0x02, zifr_2 = 0x06, zifr_3 = 0x05 (двоично-десятичный код)

У термометра DS18B20 этой температуре соответствует код 0000 0001 1010 1000 (двоичный код)

Как я могу перейти в одинаковую систему единиц для их сравнения?

Я сначала думал что нужно:

0x02(hex) * 100(dec) = 0b1100 1000

+

0x06(hex) * 10(dec) = 0b0011 1100

+

0b00000101

= 1 0000 1001

Что ни как не равно показаниям термометра (0000 0001 1010 1000).

Зашёл в тупик :smile3046:

Помогите пожалуйста.

Изменено пользователем Pilot134

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

приведите результаты к одному 16битному BCD

типо так

0000 AAAA BBBB CCCC где температора AB,C и

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зашёл в тупик :smile3046:

Помогите пожалуйста.

1. Пусть у нас есть три цифры: А - десятки единиц, В - единицы, С - десятые доли

2. Следует получить двоичное число, где запятая стоит перед четвертым разрядом (т.е. умноженное на 16 = 2 в степени 4) - см. документацию на м/с.

3. Из А,В и С получаем число АВС, выраженное в десятых долях (т.е. 10 раз большее чем есть на самом деле):

А*100 + В*10 + С

4. Вспоминаем (см.п2), что нам нужно число, умноженное на 16

(А*100 + В*10 + С) * 16

5. У нас же было число увеличенное в 10 раз (см.п3), поэтому делим на 10:

(А*100 + В*10 + С) * 16 / 10

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...