Всё по DS18(B/S)20.

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

ARV писал(а):датчик всегда выдает 85, если не принял команду старта измерения. так что либо с процессом обмена что-то не то (адрес, например, не тот), либо вообще не начинается измерение
Тестовая плата с одной 3-контактной колодкой. Прошивка неизменна. По очереди вставляю "на горячую" две 1820 и две 18В20. Из этих четырех датчиков один и только один показывает 85. Программа не может работать избирательно только для одного датчика, отсутствие датчика также индицируется.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

значит, кирдык датчику

P.S. я бы не советовал на горячую перетыкивать датчики... мало того, что можно попутать питание, так датчики обычно не очень любят, когда GND не подключен, а другие 2 пина подключены... в моей практике после такого включения на некоторое время датчик выходил из строя.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ещё не факт, что кирдык. Всё-таки, проблема может быть во временах тайм-слотов - где-то на грани находятся. Одни датчики работают, другие нет.
Zhuk72, а не могли бы Вы привести нам фрагменты кода обслуживания протокола ? Авось что-нибудь и увидим.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

Аlex писал(а):Ещё не факт, что кирдык. Всё-таки, проблема может быть во временах тайм-слотов - где-то на грани находятся
Скорее всего.
С год назад у наших местных производителей всяких типа терморегуляторов для инкубаторов на DS18B20 возникла похожая проблема - у продавцов DS пошли датчики которые не работали, у некоторых вообще. По утверждению одного из производителей - при увеличении тактовой частоты с помощью калибровочной константы (микроконтроллер PIC16) начинало работать. Не знаю, насчет показывали ли они 85С, но у тех которые теперь у нас продаются, по умолчанию включен 9-битный режим,а в документации должно быть 12 бит. Лично наблюдал сей эффект при смене старого типа датчика на "новый" выборочно из большой упаковки. Причем местный разработчик инкубаторов утверждал, что если записать в еепром датчика 12 бит, со временем еепром сбивается и возвращает режим 9 бит, это я не проверял. Своим заказчикам-производителям пришлось переделать прошивку, с проверкой в каком режиме находится датчик.
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 15595
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Надо б на сайтец максим-даллас заглянуть...
Может действительно чего нового "доупростили"...?
:dont_know:

И не стоит забывать, что было выпущено и несколько разновидностей датчиков с весьма различными структурами блокнота, плюс "паразитные"... (ds1820, ds18b20, ds18s20, ds18b20-par...)
что конкретно в лапы попало - вряд-ли кито точно скажет... :dont_know:
Сейчас также чегось про ds18b20s указано... читаньки надо...
самое последнее:
DS18B20.pdf
(484.15 КБ) 217 скачиваний
энто там же "паразит-подвох о трех лапках" (тоже из последнего):
DS18B20-PAR.pdf
(221.6 КБ) 195 скачиваний
ну и старо-дремучее по DS18S20
DS18S20.pdf
(183.27 КБ) 164 скачивания
есть еще и по "просто ds1820"... ежли когда понадобится...
страничка с "факами" от максим-даллас:
https://www.maximintegrated.com/en/supp ... 0-faq.html
:roll:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

Это общение с датчиком.
Спойлер

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

#define DQ (PORTB & 1)
#define DQ0 (PORTB &= 0xFE)
#define DQ1 (PORTB &= 0xFF)
#define DQ_OUT (TRISB &= 0xFE)
#define DQ_IN (TRISB |= 1)

bit init_ds()
{

    if (DQ)
    {
        DQ0;
        DQ_OUT;
        __delay_us(490);
        DQ_IN;
        DQ1;
        __delay_us(60);
        if (DQ)
        {
            ds_type = 0;
            return 0;
        }
            else 
            {
                t1over = 1;
                t1set(0xFF00);  // time-out timer, 512us to overflow
                while (DQ ^ t1over);
                return DQ;
            }
    }
        else
        {
            ds_type = 0;
            return 0;
        }
}

void send_ds(unsigned char ds_tx)
{
    GIE = 0;
    bit_cnt = 8;
    while (bit_cnt > 0)
    {
        DQ0;
        DQ_OUT;
        if ((ds_tx & 1) == 0)
        {
            __delay_us(60);
            DQ_IN;
            DQ1;
        } 
            else 
            {
                __delay_us(10);
                DQ_IN;
                DQ1;
                __delay_us(60);
            }
        ds_tx >>= 1;
        bit_cnt--;
        _nop();
    }
    GIE = 1;
}

void read_ds(unsigned char rx_bytes)
{
    GIE = 0;
    // rx содержит количество байт (2, 5 или все 9), которые нужно принять.
    for (byte_cnt = 0; byte_cnt < rx_bytes; byte_cnt++)
    {
        bit_cnt = 8;
        while (bit_cnt > 0)
        {
            ds_rx[byte_cnt] >>= 1;
            DQ0;
            DQ_OUT;
            __delay_us(10);
            DQ_IN;
            DQ1;
            __delay_us(10);
            if (DQ == 0) ds_rx[byte_cnt] &= 0b01111111;
                else ds_rx[byte_cnt] |= 0b10000000;
            __delay_us(60);
            bit_cnt--;
        }
    }
    GIE = 1;
}

void check_ds() // Тип датчика.
{
    if (init_ds())
    {
        send_ds(0x33);  // Read ROM
        read_ds(1); // 8-bit family code
        init_ds();  // Stop transmission.
        family = ds_rx[0];
        switch (family)
        {
            case 0x10: ds_type = 1; break;  // DS18(S)20
            case 0x28: ds_type = 2; break;  // DS18B20
        }
    }
        else
        {
//вывод на индикатор "nods" не показан
            ....
            ds_type = 0;
            family = 0;
        }
    if (ds_type == 2) config_ds();  // Там проверяется и прописывается при необходимости 9-битный режим.
}
Если у кого есть Saleae (и у кого его нет), могут посмотреть временнЫе графики с обоих датчиков.
DS18B20.rar
(2.68 КБ) 155 скачиваний
Меня эти графики заинтересовали тем, что почему-то идут 2 запроса подряд вместо одного. По коду такого быть не должно, придется в Проте пошагать, чтоб отловить.
А вообще опрос датчика делаю каждые 5 секунд (1000 обновлений индикатора).
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

В чём смысл макроса DQ1?
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

Никакого смысла, ибо и без него работает :) Оставил на всякий случай, считать состояние порта, ведь в защёлке до этого прописался 0. Типа RMW.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

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

        DQ0;
        DQ_OUT;
Местами поменяйте, во всех позициях.
Нужно сначала установить направление, а потом уже защёлкой рулить.

Функция read_ds.

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

            DQ0;
            DQ_OUT;
            __delay_us(10);
            DQ_IN;
            DQ1;
            __delay_us(10);
            if (DQ == 0)  ..........
Не много 20 us до чтения бита ?
5-7 us максимум нужно, как показала практика. Не будет сенсор столько удерживать линию в нуле.

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

ds_rx[byte_cnt]
Не пишите таких весомых кодов там, где каждый такт проца играет огромную роль.
Добавьте ещё одну функцию - чтения байта и вызывайте её сколь угодно раз.

Это что на первый взгляд.
Вообще, у Вас всё как то запутанно, можно всё упростить и привести к нормальному виду. Могу помочь, если нужно ?

PS:
ведь в защёлке до этого прописался 0. Типа RMW.
Пофиг, что там было в защёлке :) Если речь идёт, как я понял, о мелких PIC'ах.
В защёлке всегда будет то состояние, которое было на входе ПИНа (физически !) с предыдущего обращения к порту. По этому, рулить просто направлением, как делают некоторые - косяк. Необходимо ещё обновлять содержимое защёлки, после установки ПИНа на выход.
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

Аlex писал(а):Нужно сначала установить направление, а потом уже защёлкой рулить.
Поменял местами.
Функция read_ds. Не много 20 us до чтения бита ?
Судя по графику, не много, хотя согласен, что можно меньше.
Изображение
Это остатки экспериментов, когда я мучился с этим нерабочим датчиком. Увеличивал тайминги, решив, что он не воспринимает команды.

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

ds_rx[byte_cnt]
Не пишите таких весомых кодов там, где каждый такт проца играет огромную роль.
Добавьте ещё одну функцию - чтения байта и вызывайте её сколь угодно раз.
В термометре на асм так же делал, через косвенную адресацию. Сейчас пробежался по асм выхлопу компилятора этой функции (оптимизация ПРО). Он конечно понаписал побольше, чем я писал на асм. Пересмотрю код, хотя не знаю, что я там смогу оптимизировать.
К тому же при чтении байта отдельным куском тоже будет перерасход тактов на call и return (retlw). И здесь опять-таки косвенная адресация останется.
Вообще, у Вас всё как то запутанно, можно всё упростить и привести к нормальному виду. Могу помочь, если нужно?
Чужой код - потемки :) Но я в нем хорошо ориентируюсь. Помочь только советом, если можно, писать я должен сам.
Пусть я лучше буду эволюционировать естественным путем (если получится) :)))
Пофиг, что там было в защёлке :) Если речь идёт, как я понял, о мелких PIC'ах.
Старик 876. Даже без буквы.
В защёлке всегда будет то состояние, которое было на входе ПИНа (физически !) с предыдущего обращения к порту. По этому, рулить просто направлением, как делают некоторые - косяк. Необходимо ещё обновлять содержимое защёлки, после установки ПИНа на выход.
Ну я так и сделал. DQ_OUT -> DQ0 -> pause -> DQ_IN -> DQ1, который суть (PORTB &= 0xFF) - обновление содержимого защелки.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Zhuk72 писал(а):К тому же при чтении байта отдельным куском тоже будет перерасход тактов на call и return (retlw). И здесь опять-таки косвенная адресация останется.
А это уже не важно.
Самое главное - выдержать временные интервалы в пределах работы с одним битом. Время между тайм-слотами (чтение/запись бита) не оговорено и может быть сколь угодно большим. А между байтами и подавно...
В реализации 1-Wire протокола, достаточно реализовать одну базовую функцию работы с битом, остальное - дело вкуса. Причём она может быть одной и для чтения и для записи, т.к. тайм-слоты, в обоих случаях, ничем не отличаются.
На вскидку :

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

bool wire_bit(bool tx){
bool ret=0;
    GIE=0;
    DQ_OUT(0);          // Линию в 0
    __delay_us(2);      // Задержка стартового импульса
    DQ_OUT(tx);         // Выводим в линию из tx
    __delay_us(5);      // Задержка до чтения бита
    if(DQ_IN)   ret=1;  // Читаем линию
    __delay_us(60);     // Задержка до окончания тайм-слота
    DQ_OUT(1);          // Отпускаем линию
    GIE=1;
return ret;
}
Ну а дальше уже работаем с этой единственной функцией, не парясь на счёт времён.
Создаём функцию для работы с байтом. Причём она, также, может быть одна единственная, и для чтения, и для записи.

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

unsigned char wire_byte(unsigned char tx){
unsigned char ret=0, i;
    for(i=0;i<8;i++){
        ret>>=1;
        if(wire_bit(tx&0x01))   ret|=0x80;
        tx>>=1;
    }
return ret;
}
Всё :)

Запись байта в шину :

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

wire_byte(0xCC);
Чтение :

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

unsigned char   read_byte;
read_byte = wire_byte(0xFF);
Для осознанных имён, можно создать макросы :

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

#define     wire_send_byte(b)   wire_byte(b)
#define     wire_read_byte()    wire_byte(0xFF)
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15595
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Может простая банальность - попалось некоторое количество DS18S20
8)
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку

Сообщение Zhuk72 »

Alex, спасибо большое за такой развернутый ответ!
Я предполагаю, что все это должно работать, но у меня пока в мозгах все это не укладывается :)
Мне требуется время, чтоб в это вникнуть и переварить, т.к., не будучи программистом, не могу схватить это на лету. Плюс еще мозги другим (не электронным) заняты, не дают сосредоточиться.

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

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Сообщение wellcom »

Мяу! Собственно вопрос: Возможно ли (мож кто пробовал), использовать общую команду для установки разрешающей способности N датчиков 18В20?

Например, установить всем датчикам на шине одинаковую разрешающую способность:

0. Presece (питание трехпроводное)
1. шлем SKIP ROM [0xCC]
2. шлем write 3 byte [0x4E]
3. шлем byte TH
4. шлем byte TL
5. шлем byte регистр конфигурации
6. Правильность записанных данных проверяем уже по ROM коду

В даташите на счет этого ничего запретного, ровно как и разрешающего не выявил.
:solder: 32-х ядерный процессор из П213В
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

насколько я знаю стандарт, это делать можно.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Сообщение wellcom »

Еще вопрос - правильно ли я считаю Т при более низком разрешении?

Установил разрешение 11 бит, в даташите сказано, что бит 0 не имеет значения в таком случае.
1820.jpg
18b20
(168.12 КБ) 407 скачиваний
http://labkit.ru/userfiles/file/documen ... B20_RU.pdf

я в таком случае откидываю знак (биты 11-15) и сдвигаю вправо на 1.

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

fl_Temperature= (float)((sData18B20.i16_Temperature[u8_Nsensor]&0x7FF)>>1) *0.125; //res=11 bit, 0 bit neopredelen 
Или не нужно сдвигать? ....По показаниям Т вроде правильно считает, но сомневаюсь в точности....
:solder: 32-х ядерный процессор из П213В
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Судя по написанному и табличке ниже, сдвигать не нужно. Нужно просто игнорировать младшие биты.
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Сообщение wellcom »

да вот трактовать можно по разному, интересно то, что при сдвиге вправо на 1, температура примерно правильная (разница с другим термоментром цифровим не более 0,5 С). Если не сдвигать явно туфта, вместо 23 считает 44 С.
:solder: 32-х ядерный процессор из П213В
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Умножать нужно на 0.0625, а не на 0.125. Т.б. - делить на 16.
Вот Вам и лишний сдвиг (аля деление ещё на 2)...
Т.е. Вы сдвинули (поделили на 2), затем умножили на число, в 2 раза больше нужного. Двойки сократились, получился верный результат. Только в точности потеряли при сдвиге, на цену младшего бита. Но при меньшей битности, это не имеет никакого значения.
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 190
Зарегистрирован: Чт фев 24, 2011 13:00:49

Сообщение wellcom »

Аlex писал(а):Умножать нужно на 0.0625, а не на 0.125. Т.б. - делить на 16.
Вот Вам и лишний сдвиг (аля деление ещё на 2)...
Т.е. Вы сдвинули (поделили на 2), затем умножили на число, в 2 раза больше нужного. Двойки сократились, получился верный результат. Только в точности потеряли при сдвиге, на цену младшего бита. Но при меньшей битности, это не имеет никакого значения.
т.е выходит все верно, сдвинул вправо на 1(разделил на 2) при 11 битном разрешении (0,125 град/деление).
см. ниже
1820.jpg
(40.14 КБ) 372 скачивания
берем из таблички строку с разрешением 0,125 -> +10,125 С = 00A2h, что равно числу 162. Теперь 162*0,125= 20,25/2=10,125 С
или

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

(0хА2>>1)*0.125 // = 10.125 C
или

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

0хА2*0.0625 // = 10.125 C
тогда выходит, что изменяя разрешающую способность датчика, мы только сокращаем время преобразования, но считаем как и при максимальной разр способности, т.е. 0,0625....что то я туплю...
Последний раз редактировалось wellcom Чт окт 20, 2016 20:15:26, всего редактировалось 1 раз.
:solder: 32-х ядерный процессор из П213В
Ответить

Вернуться в «Периферия»