реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Преобразовать данные с DS18B20 в строку printf
Pilot134
сообщение Oct 2 2013, 14:52
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Здравствуйте.
Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же.
Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) .
Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры.
Младшая тетрада temp2 имеет дробную часть температуры.
Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4
Голову сломал не знаю как сделать sad.gif
Помогите пожалуйста. Понятно что вопрос дилетанта.
Работаю в CodeVisionAVR. МК atmega8.
Спасибо.

Сообщение отредактировал Pilot134 - Oct 2 2013, 14:54
Go to the top of the page
 
+Quote Post
megajohn
сообщение Oct 2 2013, 15:18
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



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

Код
#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  );


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
adnega
сообщение Oct 2 2013, 15:24
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Pilot134 @ Oct 2 2013, 18:52) *
Здравствуйте.
Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же.
Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) .
Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры.
Младшая тетрада temp2 имеет дробную часть температуры.
Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4
Голову сломал не знаю как сделать sad.gif
Помогите пожалуйста. Понятно что вопрос дилетанта.
Работаю в CodeVisionAVR. МК atmega8.
Спасибо.

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

Но что делать с отрицательной температурой?
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 2 2013, 15:36
Сообщение #4





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Цитата(adnega @ Oct 2 2013, 21:24) *
printf("temp=%2x.%d", temp1, temp2);

До отрицательной ещё не добрался.
Вставил Ваш вариант и не заработало sad.gif

Цитата(megajohn @ Oct 2 2013, 21:18) *
все домой ушли, так что если вечер свободен то можете этот кусок подправить для вывода дробной части

Код
#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
Правильно я понимаю? Спасибо.
Go to the top of the page
 
+Quote Post
adnega
сообщение Oct 2 2013, 15:43
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Pilot134 @ Oct 2 2013, 19:36) *
До отрицательной ещё не добрался.
Вставил Ваш вариант и не заработало sad.gif

А тут работает http://codepad.org/eTaPDzDX
А в чем неработоспособность заключается?
printf("Hello World") работает?
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 2 2013, 16:00
Сообщение #6





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Цитата(adnega @ Oct 2 2013, 21:43) *
printf("Hello World") работает?

Это работает sm.gif
Вопрос в том чтобы преобразовать значение с термометра DS18B20 в строчку printf("...") и чтобы температура выводилась в виде 25.6
Я считал температуру с датчика DS18B20 и она содержится в 2-х байтах. В старшем (temp1) и младшем (temp2).
Я уже научился выводить целую часть температуры:
Код
temperatura = ((temp1)<<4)|(temp2>>4);
printf("temp = %d C\r\n",temperatura);

и вижу на компе текст (комп с микроконтроллером общаются по усарту)
temp = 26 С
А вот с дробной частью пока проблема sad.gif
Отрицательные температуры ещё не делал sm.gif

Цитата(adnega @ Oct 2 2013, 21:43) *
А тут работает http://codepad.org/eTaPDzDX

sm.gif
там то работает.
Дело в том что у термометра DS18B20 температура считывается определённым образом.
Как видно из скрина старший байт только в младшей тетраде содержит значения целой части температуры.
А младший - старшая тетрада содержит также целую часть, а младшая тетрада младшего байта содержит только лишь дробную часть.
Спасибо что отозвались!

Сообщение отредактировал Pilot134 - Oct 2 2013, 16:03
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
adnega
сообщение Oct 2 2013, 16:39
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Pilot134 @ Oct 2 2013, 20:00) *
Дело в том что у термометра DS18B20 температура считывается определённым образом.

Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные.
Попробуйте так: http://codepad.org/oKLnmEul
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 3 2013, 04:14
Сообщение #8





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Цитата(adnega @ Oct 2 2013, 22:39) *
Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные.

Виноват sad.gif
Цитата(adnega @ Oct 2 2013, 22:39) *
Попробуйте так: http://codepad.org/oKLnmEul

Спасибо! То что нужно rolleyes.gif
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 4 2013, 16:16
Сообщение #9





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Очень сильно извиняюсь!
Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное.
Причём двоично-десятичное содержит 3 значящих тетрады.
Т.е. число типа int 0000 0011 0100 0101 (2dec) нужно преоборазовать в int 0000 0001 0101 1001 (Bin)
где 0000 0011 0100 0101 - число 0345 двоично-десятичное
а 0000 0001 0101 1001 - двоичное число 345.
Спасибо.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 4 2013, 16:33
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Pilot134 @ Oct 4 2013, 20:16) *
Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное.
Причём двоично-десятичное содержит 3 значящих тетрады.

Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой...
Go to the top of the page
 
+Quote Post
ARV
сообщение Oct 4 2013, 17:10
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 5 2013, 14:40
Сообщение #12





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Цитата(Палыч @ Oct 4 2013, 22:33) *
Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой...

Спасибо!
Go to the top of the page
 
+Quote Post
Pilot134
сообщение Oct 7 2013, 07:10
Сообщение #13





Группа: Участник
Сообщений: 14
Регистрация: 19-01-08
Пользователь №: 34 227



Только пожалуйста не ругайтесь. Но что-то немного не понял sad.gif
У устройства есть вывод значений температуры (порог) на дисплей.
Кнопками я могу редактировать это значение и вписываю (например) цифры 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.gif
Помогите пожалуйста.

Сообщение отредактировал Pilot134 - Oct 7 2013, 07:32
Go to the top of the page
 
+Quote Post
megajohn
сообщение Oct 7 2013, 07:43
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



приведите результаты к одному 16битному BCD
типо так
0000 AAAA BBBB CCCC где температора AB,C и



--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 7 2013, 07:57
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Pilot134 @ Oct 7 2013, 11:10) *
Зашёл в тупик smile3046.gif
Помогите пожалуйста.

1. Пусть у нас есть три цифры: А - десятки единиц, В - единицы, С - десятые доли
2. Следует получить двоичное число, где запятая стоит перед четвертым разрядом (т.е. умноженное на 16 = 2 в степени 4) - см. документацию на м/с.
3. Из А,В и С получаем число АВС, выраженное в десятых долях (т.е. 10 раз большее чем есть на самом деле):
А*100 + В*10 + С
4. Вспоминаем (см.п2), что нам нужно число, умноженное на 16
(А*100 + В*10 + С) * 16
5. У нас же было число увеличенное в 10 раз (см.п3), поэтому делим на 10:
(А*100 + В*10 + С) * 16 / 10
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th July 2025 - 09:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01486 секунд с 7
ELECTRONIX ©2004-2016