Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: И снова DS18B20
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Igor26
В описании на DS18B20 сказано, что значение положительной температуры - это один байт (нулевой).
Если его значение разделить на два, то получаем целое значение температуры в градусах Цельсия.
Если значение измеряемой температуры становится отрицательным, то первый байт становится 0xFF.
Измеряю комнатную температуру и вижу примерно следующие значения: нулевой байт=0xD7,
первый байт=0x01.(как видим, значение температуры - ДВА байта!!!) Значение измеряемой температуры получается 235 градусов! Вытащил датчик за окно. Значение начало добросовестно линейно уменьшаться и при переходе через ноль первый байт, опять же добросовестно,
становится 0xFF. CRC во всех случаях равна нулю. Второй датчик ведет себя точно так же.
Попробовал читать из DS1990. Правильно читает сто из ста.
Вопрос в следуещем. Так как же перевести то, что прочел из датчика в реальные градусы Цельсия или
Фаренгейта???
Сергей_
Если мне не изменяет память - значение температуры представляет собой 2 байта.
Правые четыре бита младшего байта это дробное значение температуры, левые четыре бита старшего байта это знак температуры (0-"+", 1-"-"), все что посередине целое значение температуры
Rst7
Цитата(Igor26 @ Feb 3 2006, 09:46) *
В описании на DS18B20 сказано, что значение положительной температуры - это один байт (нулевой).
Если его значение разделить на два, то получаем целое значение температуры в градусах Цельсия.
Если значение измеряемой температуры становится отрицательным, то первый байт становится 0xFF.
Измеряю комнатную температуру и вижу примерно следующие значения: нулевой байт=0xD7,
первый байт=0x01.(как видим, значение температуры - ДВА байта!!!) Значение измеряемой температуры получается 235 градусов! Вытащил датчик за окно. Значение начало добросовестно линейно уменьшаться и при переходе через ноль первый байт, опять же добросовестно,
становится 0xFF. CRC во всех случаях равна нулю. Второй датчик ведет себя точно так же.
Попробовал читать из DS1990. Правильно читает сто из ста.
Вопрос в следуещем. Так как же перевести то, что прочел из датчика в реальные градусы Цельсия или
Фаренгейта???


Берешь эти 2 байта как целое со знаком (int) и делишь на 16 (или двигаешь вправо на 4, например t>>=4).

Теперь Т у тебя температура в целых градусах Цельсия со знаком.
Георгий
Получилось 29 градусов. Жарковато однако в комнате!
Igor26
В датащите об этом ни строчки!!!
Rst7
Цитата(Igor26 @ Feb 3 2006, 12:29) *
В датащите об этом ни строчки!!!


Плохо смотрите. Там конечно не написано так же прямо, как я написал. Там есть табличка (пардон за форматирование):

Temperature/Data Relationships Table 2

MSb 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 LSB
MSb S S S S S 2^6 2^5 2^4 MSB

(unit = °C)

TEMPERATURE DIGITAL OUTPUT DIGITAL OUTPUT
(Binary) (Hex)
+125°C 0000 0111 1101 0000 07D0h
+85°C 0000 0101 0101 0000 0550h*
+25.0625°C 0000 0001 1001 0001 0191h
+10.125°C 0000 0000 1010 0010 00A2h
+0.5°C 0000 0000 0000 1000 0008h
0°C 0000 0000 0000 0000 0000h
-0.5°C 1111 1111 1111 1000 FFF8h
-10.125°C 1111 1111 0101 1110 FF5Eh
-25.0625°C 1111 1110 0110 1111 FF6Fh
-55°C 1111 1100 1001 0000 FC90h
*The power on reset register value is +85°C.
ALexx
Преобразование считанного из датчика значения выполняю так:

//-----------------------------------------------------
// Temperature Conversion to Degrees Subroutine
//
// Parameter: none
// Returns: Current temperature in degrees*10000(12 bit resolution)
// Bit 31 - Sign of temperature
//
//-----------------------------------------------------
unsigned long CurrentTemp(void)
{ unsigned long TV;
bit Sign;
if((TermoRAM.Temperature & 0xf800) == 0xf800){ //Negative temperature
TV=~TermoRAM.Temperature; TV&=0x0000ffff; TV++; Sign=1;}
else {TV=TermoRAM.Temperature; TV&=0x0000ffff; Sign=0;}

TV*=625; //(TV*10000/16)
if (Sign) TV|=0x80000000;
return(TV);
}

Структура TermoRAM периодически заполняется в основной программе. Формат ее следующий:

struct ScratchPad{
unsigned int Temperature;
unsigned char TLReg;
unsigned char THReg;
unsigned char Config;
unsigned char CRC;
};

struct ScratchPad TermoRAM;
Igor26
Цитата(Rst7 @ Feb 3 2006, 14:13) *
Цитата(Igor26 @ Feb 3 2006, 12:29) *

В датащите об этом ни строчки!!!


Плохо смотрите. Там конечно не написано так же прямо, как я написал. Там есть табличка (пардон за форматирование):

Temperature/Data Relationships Table 2

MSb 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 LSB
MSb S S S S S 2^6 2^5 2^4 MSB

(unit = °C)

TEMPERATURE DIGITAL OUTPUT DIGITAL OUTPUT
(Binary) (Hex)
+125°C 0000 0111 1101 0000 07D0h
+85°C 0000 0101 0101 0000 0550h*
+25.0625°C 0000 0001 1001 0001 0191h
+10.125°C 0000 0000 1010 0010 00A2h
+0.5°C 0000 0000 0000 1000 0008h
0°C 0000 0000 0000 0000 0000h
-0.5°C 1111 1111 1111 1000 FFF8h
-10.125°C 1111 1111 0101 1110 FF5Eh
-25.0625°C 1111 1110 0110 1111 FF6Fh
-55°C 1111 1100 1001 0000 FC90h
*The power on reset register value is +85°C.

Я даташите видел табличку типа:
85С =0xAA
25C =0x32
и т.д.
Пожалуйста, ткните носом на страницу даташита, где эта табличка.
Может быть у меня старый даташит.
ALexx спасибо за пример. Вечером попробую.

Спасибо всем ответившим cheers.gif
Igor26
Ещё раз всем спасибо!!! Действительно, делением на 16 значения ,считанного из датчика, проблему решило(Rst7 мой Вамa14.gif ), а c примером от ALess всё ясно, как работать с отрицательными значениями! a14.gif
Уважаемые модераторы, тему можно закрывать.
ROC
Цитата(Igor26 @ Feb 3 2006, 22:04) *
Ещё раз всем спасибо!!! Действительно, делением на 16 значения ,считанного из датчика, проблему решило(Rst7 мой Вамa14.gif ), а c примером от ALess всё ясно, как работать с отрицательными значениями! a14.gif
Уважаемые модераторы, тему можно закрывать.

Кгхм...
Не поторопились, уважаемый? Делением на 16 проблему не решить, Там реально сначала нужно умножить на 10, а вот потом уже делить на 16, а то Ваши результаты будут врать ровно в 10 раз.
SasaVitebsk
Давольно давно использовал, но смутно помню что в даташите (тогда ещё была просто 1820) была приведена методика как получить более точное значение температуры. Можно обеспечить точность 0.1 градуса. Я пробовал и в принципе получалось. Правда необходимости не было и я загрубил до 0.5. Но даташит действительно запутанный. Половину методом проб делал. smile.gif
Rst7
Цитата(ROC @ Feb 4 2006, 00:56) *
Кгхм...
Не поторопились, уважаемый? Делением на 16 проблему не решить, Там реально сначала нужно умножить на 10, а вот потом уже делить на 16, а то Ваши результаты будут врать ровно в 10 раз.


Обоснуй!

ЗЫ У меня это дело в измерителе уже года 4 работает, если бы оно в 10 раз врало - хрен бы я метрологию прошел wink.gif
Kovrov
че то я не врубаюсь
вам какая точность то нужна?
если измерение в цельсиях и до градуса то попросту
результат сдвигаем 1 раз вправо (деление на 2) и учитываем сдвинутую еденицу для округления
или для 0,5 град после запятой
с отрицательными температурами чуть сложней но тоже просто!
если более высокая точность используем непосредственный счетчик датчика и масштабируем онный под свои нужды....
ROC
Цитата(Rst7 @ Feb 4 2006, 10:36) *
Цитата(ROC @ Feb 4 2006, 00:56) *

Кгхм...
Не поторопились, уважаемый? Делением на 16 проблему не решить, Там реально сначала нужно умножить на 10, а вот потом уже делить на 16, а то Ваши результаты будут врать ровно в 10 раз.


Обоснуй!

ЗЫ У меня это дело в измерителе уже года 4 работает, если бы оно в 10 раз врало - хрен бы я метрологию прошел wink.gif

Упс...
Да, лажанулся sad.gif
В код посмотрел, а в комментарии - нет smile.gif

На самом деле в даташите на DS18B20 вполне прозрачно написано:
(код на Bascom AVR)
Код
R = &HFF
1wwrite &HCC                                                  'команда skip ROM
1wwrite &H44                                                  'команда "ConvertT"
Waitms 250                                                     ' ждем 250 ms
Waitms 250                                                     ' ждем 250 ms
1wreset                                                          
1wwrite &HCC                                                  'команда skip ROM
1wwrite &HBE                                                  'команда read

B1 = 1wread()                                                 'читаем 2 байта из термометра
B2 = 1wread()

1wrreset                                                          

If B2 >= 248 Then                                             'Т выше нуля? Нет?
B1 = R - B1                                                  
B2 = R - B2                                                  
Sign = "-"
Else                                                              'Т выше нуля? Да!
Sign = "+"
End If
T1 = B1 / 16                                                  
T2 = B2 * 16                                                  
T1 = T1 + T2
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.