Подключение DS18B20 к ATmega8 и вывод на LCD HD44780-MicroPi

#define DEVICES_ERROR  1

#include "config.h"

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include "OneWire.h"

 

uint8_t ONE_WIRE_DQ = PINB0;

 

void oneWireInit(uint8_t pin) {

  ONE_WIRE_DQ = pin;

  ONE_WIRE_PORT |= (1 << ONE_WIRE_DQ);

  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход

}

 

/*

* сброс

*/

uint8_t reset() {

  uint8_t response;

 

  // импульс сброса, минимум 480us

  ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);

  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход

  _delay_us(480);

 

  // Когда ONE WIRE устройство обнаруживает положительный перепад, он ждет от 15us до 60us

  ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход

  _delay_us(60);

 

  // и затем передает импульс присутствия, перемещая шину в логический «0» на длительность от 60us до 240us.

  response = (ONE_WIRE_PIN & (1 << ONE_WIRE_DQ));

  _delay_us(410);

 

  // если 0, значит есть ответ от датчика, если 1 - нет

  return response;

}

 

/*

* отправить один бит

*/

void writeBit(uint8_t bit) {

  if (bit & 1) {

    cli();

    // логический «0» на 1us

    ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);

    ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход

    _delay_us(10);

    sei();

    ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход

    _delay_us(55);

  } else {

    cli();

    // логический «0» на 1us

    ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);

    ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // выход

    _delay_us(65);

    ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход

    sei();

    _delay_us(5);

  }

}

 

/*

* отправить один байт

*/

void writeByte(uint8_t byte) {

  uint8_t i = 8;

  while (i--) {

    writeBit(byte & 1);

    byte >>= 1;

  }

}

 

/*

* получить один байт

*/

uint8_t readByte() {

  uint8_t i = 8, byte = 0;

  while (i--) {

    byte >>= 1;

    byte |= (readBit() << 7);

  }

  return byte;

}

 

/*

* получить один бит

*/

uint8_t readBit(void) {

  uint8_t bit = 0;

  cli();

  // логический «0» на 1us

  ONE_WIRE_PORT &= ~(1 << ONE_WIRE_DQ);

  ONE_WIRE_DDR |= (1 << ONE_WIRE_DQ); // вход

  _delay_us(3);

 

  // освободить линию и ждать 14us

  ONE_WIRE_DDR &= ~(1 << ONE_WIRE_DQ); // вход

  _delay_us(10);

 

  // прочитать значение

  if (ONE_WIRE_PIN & (1 << ONE_WIRE_DQ)) {

    bit = 1;

  }

 

  // ждать 45us и вернуть значение

  sei();

  _delay_us(45);

  return bit;

}

 

/*

* читать ROM подчиненного устройства (код 64 бита)

*/

uint64_t readRoom(void) {

  uint64_t oneWireDevice;

  if(reset() == 0) {

    writeByte(CMD_READROM);

    //  код семейства

    oneWireDevice = readByte();

    // серийный номер

    oneWireDevice |= (uint16_t)readByte()<<8 | (uint32_t)readByte()<<16 | (uint32_t)readByte()<<24 | (uint64_t)readByte()<<32 | (uint64_t)readByte()<<40 | (uint64_t)readByte()<<48;

    // CRC

    oneWireDevice |= (uint64_t)readByte()<<56;

  } else {

    return 1;

  }

  return oneWireDevice;

}

 

/*

* Команда соответствия ROM, сопровождаемая последовательностью

* кода ROM на 64 бита позволяет устройству управления шиной

* обращаться к определенному подчиненному устройству на шине.

*/

void setDevice(uint64_t rom) {

  uint8_t i = 64;

  reset();

  writeByte(CMD_MATCHROM);

  while (i--) {

    writeBit(rom & 1);

    rom >>= 1;

  }

}

 

/*

* провеска CRC, возвращает "0", если нет ошибок

* и не "0", если есть ошибки

*/

uint8_t crcCheck(uint64_t data8x8bit, uint8_t len) {

  uint8_t dat, crc = 0, fb, stByte = 0;

  do {

    dat = (uint8_t) (data8x8bit >> (stByte * 8));

    for (int i = 0; i < 8; i++) {  // счетчик битов в байте

      fb = crc ^ dat;

      fb &= 1;

      crc >>= 1;

      dat >>= 1;

      if (fb == 1) {

        crc ^= 0x8c; // полином

      }

    }

    stByte++;

  } while (stByte < len); // счетчик байтов в массиве

  return crc;

}

 

/*

* поиск устройств

*/

void searchRom(uint64_t * roms, uint8_t & n) {

  uint64_t lastAddress = 0;

  uint8_t lastDiscrepancy = 0;

  uint8_t err = 0;

  uint8_t i = 0;

  do {

    do {

      lastAddress = searchNextAddress(lastAddress, lastDiscrepancy);

      if(lastAddress != DEVICES_ERROR) {

        uint8_t crc = crcCheck(lastAddress, 8);

        if (crc == 0) {

          roms[i++] = lastAddress;

          err = 0;

        } else {

          err++;

        }

      } else {

        err++;

      }

      if (err > 3) {

        return;

      }

    } while (err != 0);

  } while (lastDiscrepancy != 0 && i < n);

  n = i;

}

 

/*

* поиск следующего подключенного устройства

*/

uint64_t searchNextAddress(uint64_t lastAddress, uint8_t & lastDiscrepancy) {

  uint8_t searchDirection = 0;

  uint64_t newAddress = 0;

  uint8_t idBitNumber = 1;

  uint8_t lastZero = 0;

  reset();

  writeByte(CMD_SEARCHROM);

 

  while (idBitNumber < 65) {

    uint8_t idBit = readBit();

    uint8_t cmpIdBit = readBit();

 

    // id_bit = cmp_id_bit = 1

    if (idBit == 1 && cmpIdBit == 1) {

      return DEVICES_ERROR;

    } else if (idBit == 0 && cmpIdBit == 0) {

      // id_bit = cmp_id_bit = 0

      if (idBitNumber == lastDiscrepancy) {

        searchDirection = 1;

      } else if (idBitNumber > lastDiscrepancy) {

        searchDirection = 0;

      } else {

        if ((uint8_t) (lastAddress >> (idBitNumber - 1)) & 1) {

          searchDirection = 1;

        } else {

          searchDirection = 0;

        }

      }

      if (searchDirection == 0) {

        lastZero = idBitNumber;

      }

    } else {

      // id_bit != cmp_id_bit

      searchDirection = idBit;

    }

    newAddress |= ((uint64_t) searchDirection) << (idBitNumber - 1);

    writeBit(searchDirection);

    idBitNumber++;

  }

  lastDiscrepancy = lastZero;

  return newAddress;

}

 

/*

* пропустить ROM

*/

void skipRom() {

  reset();

  writeByte(CMD_SKIPROM);

}

micro-pi.ru

1-Wire. Работа с DS18B20. Часть 1

     Все (и в том числе я) называют DS18B20 цифровым датчиком температуры. Однако это не просто датчик, это программируемый цифровой термометр. Он измеряет температуру в диапазоне от –55 до +125 градусов Цельсия, имеет программируемое температурное разрешение от 9 до 12 бит и позволяет задавать верхний и нижний температурные пороги, в случае превышения которых,  устанавливается флаг аварии. 

   Каждый термометр DS18B20 имеет уникальный 64 битный серийный номер, который используется для его адресации на 1-Wire шине. Это позволяет объединять на одной шине несколько независимо работающих термометров и осуществлять между ними и микроконтроллером обмен данными по 1-Wire протоколу. 

   Также особенностью данного термометра является то, что его можно запитывать не только от источника питания, но и от сигнального провода. Это так называемый режим паразитного питания. В этом режиме для подключения DS18B20 требуется всего два провода — сигнальный и возвратный (земляной, GND).

       Схема подключения нескольких датчиков DS18B20 с внешним питанием.     1-Wire шина  должна быть обязательно подтянута к плюсу питания через резистор номиналом 4,7 Ком. Напряжение источника питания от 3 до 5 Вольт. 

   Схема подключения датчика DS18B20 в режиме паразитного питания. 

   Вывод Vdd соединяется с GND, а 1-Wire шина дополнительно подключается к источнику питания через полевой транзистор. 

   Когда датчик DS18B20 выполняет преобразование температуры или копирует данные из ОЗУ в EEPROM память, он потребляет ток до 1,5 мА. Этот ток может вызывать недопустимое снижение напряжения на 1-Wire шине. Чтобы этого не происходило, 1-Wire шину на время выполнения этих операций подключают к источнику питания. Для этого и нужен полевой транзистор.   

     Для обмена данными термометр DS18B20 использует 1-Wire протокол (однопроводный протокол). Это низкоскоростной двунаправленный полудуплексный последовательный протокол обмена данными использующий всего один сигнальный провод. Естественно требуется еще и возвратный (земляной) провод, но об этом маркетологи обычно умалчивают. 1-Wire протокол был разработан фирмой Dallas Semiconductor в конце 90-х годов.    

     

   Имеется несколько типов сигналов, определенных 1-Wire протоколом - импульс сброса, импульс присутствия, запись 0, запись 1, чтение 0 и чтение 1. Все эти сигналы, за исключением импульса присутствия, формируются на шине главным устройством — MASTERом . В нашем случае это  микроконтроллер AVR. 

  Принцип формирования сигналов во всех случаях одинаковый. В начальном состоянии 1-Wire шина с помощью резистора подтянута к плюсу питания. Главное устройство «проваливает» на определенное время 1-Wire шину в ноль, затем «отпускает» ее и, если нужно, «слушает» ответ подчиненного (SLAVE) устройства. В нашем случае подчиненное устройство - термометр DS18B20. 

 

  Физически это реализуется так. 

  Операция записи бита: Вывод микроконтроллера устанавливается в режим выхода и на нем устанавливается логический ноль. Выдерживается пауза, длительность которой зависит от значения передаваемого бита (0 или 1), затем вывод переводится в режим входа в состоянии Hi-z и снова выдерживается пауза. 

  Операция чтения бита: Вывод микроконтроллера устанавливается в режим выхода и на нем устанавливается логический ноль. Выдерживается определенная пауза, вывод переводится в режим входа в состоянии Hi-z, выдерживается пауза, а затем микроконтроллер считывает потенциал вывода. 

 

   Все сеансы связи микроконтроллера с датчиком DS18B20 начинаются с сигнала сброса.  Микроконтроллер на 480 мкс «проваливает» 1-Wire шину в ноль, а затем «отпускает» ее. Если к шине подключен термометр DS18B20, то он  обнаруживает положительный перепад и после паузы в 15-60 мкс отвечает микроконтроллеру импульсом присутствия — «проваливает» шину в ноль на время от 60 до 240 мкс. 

  

   Обмен данными по 1-Wire шине происходит последовательно, младшим битом вперед. Передача или прием одного бита данных выполняются в течении фиксированного промежутка времени, так называемого тайм слота (time slot). Различают тайм слоты записи и тайм слоты чтения. Длительность всех тайм слотов должна быть > 60 мкс, а пауза между тайм слотами  > 1 мкс.   

 

   Для передачи нуля микроконтроллер «проваливает» 1-Wire шину на время от 60 до 120 мкс. Затем «отпускает» ее и перед записью следующего бита выдерживает паузу >1  мкс.

   Для передачи единицы микроконтроллер «проваливает» 1-Wire шину на время от 1 до 15 мкс,  «отпускает» ее и выдерживает паузу. Пауза должна быть такой, чтобы длительность тайм слота была > 60+1 мкс. 

   

   DS18B20 является подчиненным устройством и может передавать данные, только когда микроконтроллер формирует на 1-Wire шине тайм слоты чтения. Для формирования тайм слота чтения микроконтроллер «проваливает» 1-Wire шину на время от 1 до 15 мкс, а затем «отпускает» ее, передавая  управление состоянием 1-Wire шины датчику DS18B20. Если DS18B20 передает ноль, он удерживает шину в «проваленном» состоянии (в состоянии логического нуля) до конца тайм слота. Если он передает 1, он оставляет шину в «подтянутом» состоянии. 

   Микроконтроллер может считывать данные датчика DS18B20 через 15 мкс после начала тайм слота чтения. 

chipenable.ru

Подключение температурного датчика DS18B20 по схеме с «паразитным» питанием

Существует несколько способов подключения датчиков температуры DS18B20 к сети 1-wire. В этой заметке я опишу способ подключения температурного датчика по схеме с «паразитным» питанием,  где в качестве мастера сети 1-wire используется оригинальное USB-устройство DS9490R.

Данный способ подключения является очень удобным, т.к. используются всего две жилы проводника, а так же нет необходимости в дополнительной обвязке со схемой стабилизации питания (если вы планируете использовать в качестве мастера другие устройства, то возможно будет необходима подтяжка — об этом я расскажу позже). Правда стоит отметить, что в официальной документации говорится о возможных негативных последствиях при подключении температурного датчика, но на практике, при использовании мастера DS9490R,  я с этими проблемами не встречался.

Итак, схема подключения датчика довольно простая: в качестве шины сети 1-wire я использую простой кабель UTP-5 (витая пара) и, с целью уменьшения помех на линии, использовал для DATA и GND две свитых в одну пару жилы. Ножки датчика 1 (GND) и 3 (Vdd) соединяются накоротко и подключаются к PIN4 у DS9490R. Ножка 2 (DATA) подключается к PIN3 у DS9490R. Таким способом к одному мастеру можно подключить много датчиков (я проверял работоспособность на 15 одновременно подключенных датчиках).

Принципиальная схема подключения DS18B20 с паразитным питанием:

После подключения, датчики появляются в OWFS и показывают температуру 🙂

Преимущества данной схемы подключения:

  • Простой и довольно дешевый способ подключения большого количества датчиков температуры
  • Нет необходимости во внешнем питании
  • Нет необходимости в дополнительной «обвязке»

Недостатки:

  • Возможна нестабильная работа на шинах большой длинны и большим количеством ведомых устройств в сети
  • Желательно использовать фирменный мастер сети DS9490R
Запись опубликована автором Ilshat в рубрике Без рубрики с метками DS18B20, датчики, температура.

dom-v-provodah.ru

Датчик температуры DS18B20. Описание, характеристики, подключение, распиновка, datasheet

DS18B20 — цифровой датчик температуры фирмы Dallas. Отправляет данные о температуре, используя только один цифровой вывод и специальный протокол, называемый 1-Wire. Вы можете подключить несколько датчиков к одному контакту. Датчик измеряет температуру в градусах Цельсия.

Технические характеристики DS18B20

  • Датчик можно питать напряжением от 3 до 5,5В
  • Датчик может измерять температуру от -55 до 125 °C
  • Датчик имеет цифровое разрешение от 9 до 12 бит
  • Точность измерения +/- 0,5 °C в диапазоне от -10 до 85 °C
  • Точность измерения: + /- 2 °C для диапазона от -55 до 125 °C
  • Дрейф измерения +/- 0,2 °C

Распиновка DS18B20

Схема подключения DS18B20

Что такое разрешение?

В технических характеристиках сообщается, что датчик DS18B20 может измерять температуру с различным разрешением. Разрешение — это как у линейки: миллиметры между сантиметрами. Так же и c разрешением у DS18B20 — это шаг между последовательными ступенями градусов Цельсия.

Разрешение выбирается с помощью количества бит. Диапазон выбора от 9 до 12 бит. Выбор разрешения влечет за собой определенные последствия. Чем выше разрешение, тем дольше придется ждать результат измерений.

Для 9 битного разрешения есть 2 шага между последовательными уровнями:

То есть, вы можете прочитать температуру с разрешением 0,5 °C. Для 9 битного разрешения время измерения составляет 93,75 мс. То есть, вы можете выполнять 10,6 измерений в секунду.

Для 10 битного разрешения есть 4 шага между последовательными уровнями:

  • 0,0 °C
  • 0,25 °C
  • 0,5 °C
  • 0,75 °C

В этом случае мы считываем температуру с разрешением 0,25 °C. Время измерения для 10 битного разрешения составляет 187,5 мс, что позволяет выполнить 5,3 измерений в секунду.

Для 11 битного разрешения есть 8 шагов между последовательными уровнями:

  • 0,0 °C
  • 0,125 °C
  • 0,25 °C
  • 0,375 °C
  • 0,5 °C
  • 0,625 °C
  • 0,75 °C
  • 0,875 °C

То есть разрешение составляет 0,125 °C. Время измерения для 11 битного разрешения составляет 375 мс. Это позволяет выполнить 2,6 измерения в секунду.

Для 12 битного разрешения есть 16 шагов между последовательными уровнями:

  • 0,0 °C
  • 0,0625 °C
  • 0,125 °C
  • 0,1875 °C
  • 0,25 °C
  • 0,3125 °C
  • 0,375 °C
  • 0,4375 °C
  • 0,5 °C
  • 0,5625 °C
  • 0,625 °C
  • 0,6875 °C
  • 0,75 °C
  • 0,8125 °C
  • 0,875 °C
  • 0,9375 °C

Следовательно, разрешение составляет 0,0625 °C. Время измерения для 12 битного разрешения в районе 750 мс. То есть вы можете сделать 1,3 измерений в секунду.

Что такое точность измерения?

Ничто в мире, и особенно в электронике, не является совершенным. Можно только приближаться к совершенству, тратя все больше и больше денег и сил. Так же и с этим датчиком. Он имеет некоторые неточности, о которых вы должны знать.

В технических характеристиках сказано, что в диапазоне измерения от -10 до 85 °C датчик DS18B20 имеет точность на уровне +/- 0,5 °C. Это значит, что, когда в комнате у нас температура 22,5 °C, то датчик может вернуть нам результат измерения от 22 до 23 °C. То есть, может показать на 0,5 °C больше или меньше. Все это зависит от индивидуальной характеристики датчика.

В диапазоне от -55 до 125 °C погрешность измерения может возрасти до +/- 2 °C. То есть, когда вы измеряете что-то с температурой 100 °C, то датчик может показать температуру от 98 до 102 °C.

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

Что такое дрейф измерения?

Дрейф измерения — это наиболее худшая форма неточности. Суть дрейфа измерения заключается в том, что при измерении постоянной температуры — при одном измерении датчик может показывать одну температуру, а при последующем другую (на величину дрейфа).

Дрейф датчика температуры DS18B20 +/- 0.2 °C. Например, когда в комнате постоянная температура составляет 24 °C, датчик может выдавать результат в диапазоне от 23,8 °C до 24,2 °C.

Скачать datasheet DS18B20 (379,0 Kb, скачано: 803)

www.joyta.ru

alexxlab

Отправить ответ

avatar
  Подписаться  
Уведомление о