Страница 2 из 3

Добавлено: Пт янв 09, 2009 23:49:10
ARV
получать надо не 2 байта, а все 8. как это делать - написано в даташите, который вы, судя по всему, читали...

Добавлено: Сб янв 10, 2009 06:53:29
CCCP
Зачем 8, когда температура в 2х?
Я понимаю, что всё написано в даташите и нескольких учебниках по СИ...

Добавлено: Вт фев 03, 2009 19:22:03
QZ_
Здравтсвтуйте, мучители DS'ок))
вот недавно замутил часы с термометром (7 семисегментных индикаторов + DS18B20 ). Пишу в Code Vision.
Проблема вот в чем:
Сначала у меня вывод на индикатор на прерывании от таймера был, все было хорошо, кроме измерения температуры (или ваще не мерилась или через раз).
Потом кое как выдрал вывод в главный цикл, избавился от обозначенной CCCP паузы, но всеравно дисп помигивает. это сильно достает. как бы мне избавиться от такой проблемы?
PS: ах вот, забыл, глав железка - M16 + часы DS1307

Добавлено: Вт фев 03, 2009 19:59:52
diehard
1. Исходник покажи.
2. Вывод на семисегментник из прерывания по таймеру делай, а считывание температуры из main.

Добавлено: Вт фев 03, 2009 20:42:12
ARV
CCCP писал(а):Зачем 8, когда температура в 2х?
Я понимаю, что всё написано в даташите и нескольких учебниках по СИ...
если бы понимали - не говорили бы такой ерунды. пакет из 8-и байт позволяет при помощи CRC определить - верные данные пришли, или из-за помехи или иных причин они исказились. читая только первые 2 байта вы никогда не узнаете, что датчик у вас пургу несет...

Добавлено: Вт фев 03, 2009 20:44:55
ARV
QZ_ писал(а):Потом кое как выдрал вывод в главный цикл, избавился от обозначенной CCCP паузы, но всеравно дисп помигивает. это сильно достает. как бы мне избавиться от такой проблемы?
верните индикацию в прерывания! откорректируйте (или напишите сами) функции обмена по 1-wire так, чтобы прерывания запрещались не на целую функцию, а только на момент передачи-приема одного бита. в конце-концов, поищите в интернете - библиотек для 1-wire с исходниками множество!

Добавлено: Вт фев 03, 2009 22:18:02
QZ_
diehard писал:
Исходник покажи.
к сожалению не осталось той версии исходника :?
щас чета жестокое замутил (вроде дисп почти не дергается, но и термометр не робит пока). исходник прилагается. щас работаю над ним.
Вывод на семисегментник из прерывания по таймеру делай, а считывание температуры из main.
вот ща если толку не выйдет, завтра все назад верну (индикацию в прерывание)

ARV на насчет запрета прерываний, так, в code vision'ской реализации 1-wire вообще все идет без запрета, наверно потому и через раз работал датчик.

Добавлено: Вт фев 03, 2009 23:25:06
diehard
QZ_ писал(а):diehard писал:
Исходник покажи.
к сожалению не осталось той версии исходника :?
щас чета жестокое замутил (вроде дисп почти не дергается, но и термометр не робит пока). исходник прилагается. щас работаю над ним.
Вывод на семисегментник из прерывания по таймеру делай, а считывание температуры из main.
вот ща если толку не выйдет, завтра все назад верну (индикацию в прерывание)
Пока не вернешь динамическую индикацию в прерывание, у тебя так и будет изображение на семисегментнике дергаться!

Добавлено: Ср фев 04, 2009 10:47:51
QZ_
Вернул индикацию на прерывание. Вроде стало лучше, щас температуру норм меряет, но из-за запрета прерываний, дисп всетаки слегка помигивает (почти незаметно).

Добавлено: Ср фев 04, 2009 11:17:07
ARV
запрещайте прерывания только на время приема/передачи БИТА, а не байта

Добавлено: Ср фев 04, 2009 12:44:05
diehard
+1
ARV прав на 100%. Общее правило при работе с прерываниями такое: если используются прерывания, то запрещать их нужно на _МИНИМАЛЬНОЕ_ время. Еще лучше оптимизировать или разбить код так, что бы действия не мешали прерываниям. Например можно разбить код на части и выполнять эти части между прерываниями.

ЗЫ: Посмотрел твой исходник и сразу бросилась в глаза задержка в таймере0.
1. Задержек в побработчиках рерываниях быть не должно!
2. Таймер для обновления семисегментника заведен на 1150 Гц. Не лучше ли завести его примерно на 200Гц???
3. В таймере зажигай разряд семисегментика, а при следующем входе в таймер гаси его и зажигай следующий и т.д.
4. Зачем перезагружаешь счетчик таймера в конце обработчика прерывания TCNT0 = T0_VAL;??? Наверное потому, что если будешь перезагружвать в начале, то из таймера вообще не выскочишь! Перезагружай счетчик в самом начале, это поможет тебе сделать функцию прерывания короче! Так ты поймешь, что выходить из таймера не успеваешь и твой обработчик прерывания _ОЧЕНЬ_ДЛИННЫЙ_.
Итого:
Исправив процедуру обработчика прерывания по таймеру0 IMHO снимется большинство проблем!

Добавлено: Ср фев 04, 2009 15:22:42
QZ_
пасиба за советы, ща попробую все поправить.
а насчет TCNT0 = T0_VAL; в конце прерывания, то я его туда сунул в самый последний момент (всегда в начале было)
.
.
.
во, щас все путем :))
теперь вот еще вопрос: если DS18B20 повесть на паразитное питание, то когда запускаю преобразование (0х44) надо включить подтяжку на ногу, так?

Добавлено: Ср фев 04, 2009 18:40:29
diehard
Пришлось скачать даташит и смотреть. Чего и тебе советую.
Даташит страница 4. Тебе туда. Написано и нарисовано очень хорошо.

Добавлено: Ср фев 04, 2009 19:01:01
QZ_
я видел. как я понял, надо просто ногу МК включать, когда отдал команду 0x44 или 0х48 на нужное время. щас это опробую.

хмм, чета странно... не хочет на паразитном питании работать..

ухх, разобрался.., все работает.

Добавлено: Чт фев 05, 2009 19:02:09
CCCP
ARV писал(а):
CCCP писал(а):Зачем 8, когда температура в 2х?
Я понимаю, что всё написано в даташите и нескольких учебниках по СИ...
если бы понимали - не говорили бы такой ерунды. пакет из 8-и байт позволяет при помощи CRC определить - верные данные пришли, или из-за помехи или иных причин они исказились. читая только первые 2 байта вы никогда не узнаете, что датчик у вас пургу несет...
Несколько грубовато и высокомерно. Вопрос был именно о чтении температуры, а не о CRC. Понять достоверные данные или нет, труда то не составит, показания, скорее всего, будут напоминать генератор случайных чисел. Когда речь идёт о работе датчиков на значительном удалении, при сильном уровне помех, да, нужно убеждаться в верности данных, но когда разбираешься в принципе работы, об этом можно и не думать. А вообще, я уже давно во всём разобрался, в том числе и с CRC.
ARV рекомендую научиться для начала правильно понимать вопросы, и вести себя посдерженее.

Добавлено: Чт фев 05, 2009 19:52:21
Тарас
У меня вопросик по теме как получить данные с датчика с точностью 0.1 градус?
Можно посмотреть исходник такой реализации? :)

Добавлено: Чт фев 05, 2009 20:45:05
CCCP
Тарас писал(а):У меня вопросик по теме как получить данные с датчика с точностью 0.1 градус?
Можно посмотреть исходник такой реализации? :)
Точность и разрешение это разные вещи. 12bit и разрешающая способность 1/16 градуса, ну а исходник есть в CV.
Из даташита:
ОПИСАНИЕ
DS18B20 цифровой термометр с программируемым разрешением, от 9 до 12–bit, которое может сохраняться в EEPROM памяти прибора. Диапазон измерений от –55°C до +125°C и точностью 0.5°C в диапазоне от –10°C до +85°C. Основные функциональные возможности DS18B20 - его температурный преобразователь. Разрешающая способность температурного преобразователя может быть изменена пользователем и составляет 9, 10, 11, или 12 битов, соответствуя приращениям (дискретности измерения температуры) 0.5 °C, 0.25°C, 0.125°C, и 0.0625°C, соответственно. Разрешающая способность по умолчанию установлена 12-бит.
Даташит около 1MB, и я не знаю как его прицепить.

Добавлено: Чт фев 05, 2009 22:25:21
ARV
CCCP писал(а):ARV рекомендую научиться для начала правильно понимать вопросы, и вести себя посдерженее.
научитесь задавать вопросы, если уж на то пошло.
для начала.
а потом будете мне давать рекомендации. когда я вас об этом попрошу. договорились?

Добавлено: Вт июн 09, 2009 12:00:55
clawham
Ребятки, не ссорьтесь!
Лучше подскажите как мне попроще сделать преобразование двух байтного слова температуры ДС-ки с разрещением в 12 бит в простой флоат
я делаю пока что так

Код: Выделить всё

// обработаем старший байт - если он отрицателен то все биты надо инвертировать
                  temp = ds_scratch_pad.temp_msb;
                  if((temp>>6)&1)
                    {
                        below=1;
                        temp = temp^0b11111111;
                    }
                  else
                    below=0;
                  
                  ds_temp = (float)((temp&1)*16+((temp>>1)&1)*32+((temp>>2)&1)*64);             
                  
                  // теперь младший
                  temp = ds_scratch_pad.temp_lsb;
                  // если число отрицательно - инвертируем
                  if(below)
                    temp=temp^0b11111111;
                              
                  ds_temp = ds_temp + (float)((temp&1)*0.0625+((temp>>1)&1)*0.125+((temp>>2)&1)*0.25+((temp>>3)&1)*0.5+((temp>>4)&1)+((temp>>5)&1)*2+((temp>>6)&1)*4+((temp>>7)&1)*8);
                                    
                  if(below)
                    ds_temp = (float)(0-ds_temp);             
                  
но это ж примитивно :) знаю что можно просто разделить на 0.0625 но откуда возьмётся знак и куда прилепить старший байт?

Добавлено: Вс авг 16, 2009 14:22:10
atlantix_xp
clawham писал(а):Ребятки, не ссорьтесь!
Лучше подскажите как мне попроще сделать преобразование двух байтного слова температуры ДС-ки с разрещением в 12 бит в простой флоат
я делаю пока что так

Код: Выделить всё

// обработаем старший байт - если он отрицателен то все биты надо инвертировать
                  temp = ds_scratch_pad.temp_msb;
                  if((temp>>6)&1)
                    {
                        below=1;
                        temp = temp^0b11111111;
                    }
                  else
                    below=0;
                  
                  ds_temp = (float)((temp&1)*16+((temp>>1)&1)*32+((temp>>2)&1)*64);             
                  
                  // теперь младший
                  temp = ds_scratch_pad.temp_lsb;
                  // если число отрицательно - инвертируем
                  if(below)
                    temp=temp^0b11111111;
                              
                  ds_temp = ds_temp + (float)((temp&1)*0.0625+((temp>>1)&1)*0.125+((temp>>2)&1)*0.25+((temp>>3)&1)*0.5+((temp>>4)&1)+((temp>>5)&1)*2+((temp>>6)&1)*4+((temp>>7)&1)*8);
                                    
                  if(below)
                    ds_temp = (float)(0-ds_temp);             
                  
но это ж примитивно :) знаю что можно просто разделить на 0.0625 но откуда возьмётся знак и куда прилепить старший байт?
Это ты определенно перемудрил :)
1. все данные приходят в нормальном формате, их только нужно преобразовать то есть отделить знаковые биты от цифровых десятки единицы и дробную часть
(например число +25,5 приходит к нам в виде 0000 0001 1001 1000
из этого всего первые пять нулей знак 0000 0 ** 001 1001 ** 1000
потом 7 бит число 25 в двоичной форме (1 1001) и затем 0,5 в виде какого то значения соответствующего таблице и все и ничего нигде не нужно умножать)
2. при отрицательном значении проверяеться бит наличия минуса и потом инвертируться данные.
3. на 0,0625 ничего делить не нужно!!!!!!!!!!!!!!!!!
пишеться массив
static signed char x[16] = {0,06,12,18,25,31,37,43,50,56,62,68,75,81,87,93};
указателем в котором будут являться последние 4 бита дробных долей градуса.
короче вот текст пробуйте кому интересно пишите постараюсь обьяснить 147038414
тексты взяты из даташита на сайте MAXIM схема Микроконтроллерное управление звуком 2
****************************
Изменил и несколько обновил программу теперь обрабатываеться два датчика в принципе можнои 4 сколько хватит экрана
выводить можно куда угодно сообветственно переработав функцию вывода :)
все функции независимы есть несколько дополнительных функций, таких как вывод ID кода на экран и так далее, думаю будет полезно и удобно :)