Pilot134 0 2 октября, 2013 Опубликовано 2 октября, 2013 (изменено) · Жалоба Здравствуйте. Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же. Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) . Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры. Младшая тетрада temp2 имеет дробную часть температуры. Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4 Голову сломал не знаю как сделать :( Помогите пожалуйста. Понятно что вопрос дилетанта. Работаю в CodeVisionAVR. МК atmega8. Спасибо. Изменено 2 октября, 2013 пользователем Pilot134 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 2 октября, 2013 Опубликовано 2 октября, 2013 · Жалоба все домой ушли, так что если вечер свободен то можете этот кусок подправить для вывода дробной части #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 ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 2 октября, 2013 Опубликовано 2 октября, 2013 · Жалоба Здравствуйте. Сразу хочу извиниться что для многих мой вопрос покажется примитивным, но всё же. Считал я температуру с термометра DS18B20 в 2 регистра temp1 (char) и temp2 (char) . Младшая тетрада temp1 и старшая тетрада temp2 имеют значение целой части температуры. Младшая тетрада temp2 имеет дробную часть температуры. Я хочу строчкой printf("...") вывести в уарт МК данные чтобы у меня показывало температуру в формате 25.4 Голову сломал не знаю как сделать :( Помогите пожалуйста. Понятно что вопрос дилетанта. Работаю в CodeVisionAVR. МК atmega8. Спасибо. printf("temp=%2x.%d", temp1, temp2); Но что делать с отрицательной температурой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 2 октября, 2013 Опубликовано 2 октября, 2013 · Жалоба 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 Правильно я понимаю? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 2 октября, 2013 Опубликовано 2 октября, 2013 · Жалоба До отрицательной ещё не добрался. Вставил Ваш вариант и не заработало :( А тут работает http://codepad.org/eTaPDzDX А в чем неработоспособность заключается? printf("Hello World") работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 2 октября, 2013 Опубликовано 2 октября, 2013 (изменено) · Жалоба 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 температура считывается определённым образом. Как видно из скрина старший байт только в младшей тетраде содержит значения целой части температуры. А младший - старшая тетрада содержит также целую часть, а младшая тетрада младшего байта содержит только лишь дробную часть. Спасибо что отозвались! Изменено 2 октября, 2013 пользователем Pilot134 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 2 октября, 2013 Опубликовано 2 октября, 2013 · Жалоба Дело в том что у термометра DS18B20 температура считывается определённым образом. Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные. Попробуйте так: http://codepad.org/oKLnmEul Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 3 октября, 2013 Опубликовано 3 октября, 2013 · Жалоба Как температура выдается DS18B20 и то, как описали Вы в первом посте вещи, мягко говоря, не эквивалентные. Виноват :( Попробуйте так: http://codepad.org/oKLnmEul Спасибо! То что нужно :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Очень сильно извиняюсь! Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное. Причём двоично-десятичное содержит 3 значящих тетрады. Т.е. число типа int 0000 0011 0100 0101 (2dec) нужно преоборазовать в int 0000 0001 0101 1001 (Bin) где 0000 0011 0100 0101 - число 0345 двоично-десятичное а 0000 0001 0101 1001 - двоичное число 345. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Но появился ещё один вопрос - как можно перевести двоично-десятичное число в двоичное. Причём двоично-десятичное содержит 3 значящих тетрады. Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба ну почему у всех мода такая - побайтно интерпретировать температуру DS18x20?! ведь в описании вполне доступно написано, что 2 первых байта представляют температуру в дополнительном двоичном коде в долях градуса! то есть вам надо 2 байта рассматривать как обычный int (16-битный, естественно!) - и будет вам температура со знаком! только поделить на разрешающую способность предварительно, т.е. если режим датчика для 9-битной температуры, то разрешающая способность 0,5 градуса, т.е. двухбайтное число типа int надо поделить на 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 5 октября, 2013 Опубликовано 5 октября, 2013 · Жалоба Так - как этому учат в школе: первую тетраду умножаем на 100, складываем со второй тетрадой умноженной на 10, и всё это складываем с третьей тетрадой... Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pilot134 0 7 октября, 2013 Опубликовано 7 октября, 2013 (изменено) · Жалоба Только пожалуйста не ругайтесь. Но что-то немного не понял :( У устройства есть вывод значений температуры (порог) на дисплей. Кнопками я могу редактировать это значение и вписываю (например) цифры 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: Помогите пожалуйста. Изменено 7 октября, 2013 пользователем Pilot134 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 7 октября, 2013 Опубликовано 7 октября, 2013 · Жалоба приведите результаты к одному 16битному BCD типо так 0000 AAAA BBBB CCCC где температора AB,C и Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 7 октября, 2013 Опубликовано 7 октября, 2013 · Жалоба Зашёл в тупик :smile3046: Помогите пожалуйста. 1. Пусть у нас есть три цифры: А - десятки единиц, В - единицы, С - десятые доли 2. Следует получить двоичное число, где запятая стоит перед четвертым разрядом (т.е. умноженное на 16 = 2 в степени 4) - см. документацию на м/с. 3. Из А,В и С получаем число АВС, выраженное в десятых долях (т.е. 10 раз большее чем есть на самом деле): А*100 + В*10 + С 4. Вспоминаем (см.п2), что нам нужно число, умноженное на 16 (А*100 + В*10 + С) * 16 5. У нас же было число увеличенное в 10 раз (см.п3), поэтому делим на 10: (А*100 + В*10 + С) * 16 / 10 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться