Print this page

1-Wire. Работа с DS18B20. Использование двух датчиков. Часть 4

24/09/2011 - 12:07

   Введение

   Одно из преимуществ 1-Wire интерфейса заключается в том, что он позволяет организовать сеть из нескольких устройств. До сих пор мы не использовали эту возможность и рассматривали работу только с одним датчиком. Мы разобрались, как подключить Atmel`овскую библиотеку к проекту, как в DS18B20 запустить преобразование температуры, как считывать ее и выводить на дисплей. Настало время перейти к следующему этапу работы – коммуникация с несколькими датчиками на одной 1-Wire шине.

   Получение адресов датчиков

   Каждый датчик DS18B20 имеет 64-ех разрядный серийный номер, который используется для его адресации  на шине. Для получения адресов 1-Wire устройств существует команда SEARCH ROM (0xf0). Процедура выглядит следующим образом. 
   Микроконтроллер выполняет инициализацию 1-Wire устройств и посылает команду SEARCH ROM, которая инициирует цикл чтения 64 разрядного кода. Затем он формирует на 1-Wire шине два тайм слота чтения, в течение которых датчики DS18B20 должны выдать первый бит своего адреса и его инвертированное значение. 
   Если испускаемый бит адреса у всех датчиков один и тот же, например, единица, тогда в первый тайм слот микроконтроллер примет единицу, а во второй ноль. 
   Если испускаемый бит адреса у одного или нескольких датчиков отличается, например, у первого датчика бит – единица, у второго – ноль, тогда в оба тайм слота микроконтроллер примет ноль. Почему? Потому что датчики подключены к шине по схеме монтажного И, а значит логический ноль «перетянет» логические единицы.
   Если на шине активных устройств нет - микроконтроллер в оба тайм слота примет единицу. 
   В ситуации, когда микроконтроллер принимает два нуля, возникает неоднозначность – непонятно у каких датчиков DS18B20 преданный бит адреса ноль, а у каких единица. Чтобы устранить эту неоднозначность микроконтроллер должен ответить датчикам, с какими из них он будет продолжать работу. Для этого он выставляет на шине соответствующий бит — ноль или единицу. Датчики, у которых переданный бит соответствует выставленному, продолжат работу, остальные замолчат (станут не активными) до следующего сигнала сброса. 
   Далее процедура повторяется еще 63 раза: формирование первого тайм слота чтения, чтение состояние шины, формирование второго тайм слота чтения, чтение состояния шины, ответ подчиненным устройствам. 
   После завершения цикла чтения 64 разрядного кода, микроконтроллер будет знать адрес одного датчика DS18B20. Для получения следующего адреса, нужно снова запустить цикл чтения, но на этот раз в случае неоднозначности выставить другой бит. 
  Сколько датчиков подключено к шине, столько раз и нужно провести описанную процедуру.

Обращение к датчику

   Когда адреса датчиков получены, микроконтроллер может индивидуально обращаться к любому из них. Для этого используется команда MATCH_ROM (0x55). 
 
Последовательность работы будет выглядеть так:
 
- инициализация
- выдача команды MATCH ROM
- выдача 64 разрядного адреса датчика
- выдача функциональной команды

Описание функций библиотеки

   Функции, выполняющие поиск адресов и адресацию 1-Wire устройств, расположены в файле OWIHighLevelFunctions.с. Некоторые из функций я модифицировал. 

unsigned char OWI_SearchRom(unsigned char * bitPattern, unsigned char lastDeviation, unsigned char pin)  
 
Назначение:    Получение адреса одного 1-Wire устройства. 
Посылает команду SEARCH ROM, получает адрес одного 1-Wire устройства и сохраняет его в массиве. 
 
Принимает:     
unsigned char * bitPattern – указатель на массив, в который будет сохраняться адрес 
unsigned char lastDeviation – номер бита, на котором возникла неоднозначность
unsigned char pin – пин, к которому подключена шина
 
Возвращает: номер бита, на котором возникла неоднозначность
 
Пример:
 
#define BUS   OWI_PIN_7
 
unsigned char id1[8];
unsigned char id2[8];
unsigned char lastDeviation = 0;
 
….
//получение первого адреса
lastDeviation = OWI_SearchRom(id1, lastDeviation, BUS);
 
//получение второго адреса
OWI_SearchRom(id1, lastDeviation, BUS);
 

unsigned char OWI_SearchDevices(OWI_device * devices, unsigned char numDevices, unsigned char pin, unsigned char *num)
 
Назначение:   Получение адресов 1-Wire устройств. 
Посылает команду SEARCH ROM, получает адреса нескольких 1-Wire устройств, сохраняет их и проверяет контрольную сумму каждого адреса.
 
Принимает:     
OWI_device * devices – указатель на структуру, в который будет сохраняться адрес
Структура определена в файле OWIHighLevelFunctions.h
 
typedef struct
{
    unsigned char id[8];    //!< The 64 bit identifier.
} OWI_device;
 
unsigned char numDevices – количество 1-Wire устройств, подключенных к шине
unsigned char pin – пин, к которому подключена шина
unsigned char *num – указатель на переменную, в которой сохраняется количество найденных 1-Wire устройств прошедших проверку 
 
Возвращает: код ошибки.
SEARCH_SUCCESSFUL (0x00) - ошибок нет
SEARCH_CRC_ERROR (0x01)  - ошибка CRC в одном из адресов
 
Пример:
 
#define BUS   OWI_PIN_7
 
//количество устройств на 1-Wire
#define MAX_DEVICES       0x02
 
//массив структур для хранения адресов
OWI_device allDevices[MAX_DEVICES];
 
int main( void )
{
  unsigned char num = 0;
 
  num = 0;
  OWI_SearchDevices(allDevices, MAX_DEVICES, BUS, &num);
  …..
 

void OWI_MatchRom(unsigned char * romValue, unsigned char pin)
 
Назначение:  адресация 1-Wire устройства. 
Посылает команду MATCH ROM и выдает на шину адрес. 
 
Принимает:     
romValue – указатель на массив в котором храниться адрес 1-Wire устройства
unsigned char pin – пин, к которому подключена шина
 
Возвращает: -
 
Пример:
 
#define BUS   OWI_PIN_7
#define DS18B20_CONVERT_T             0x44
 
unsigned char id[8];
 
….
/*подаем сигнал сброса
адресуем нужный датчик
запускаем команду преобразования*/
 OWI_DetectPresence(BUS);
 OWI_MatchRom(id, BUS);
 OWI_SendByte(DS18B20_CONVERT_T ,  BUS);


Тестовый проект для AVR

  Для демонстрации использования двух датчиков DS18B20 на одной шине, я написал учебный проект. Суть его в следующем. 
   Микроконтроллер выполняет процедуру поиска адресов датчиков. Если найдены два датчики и полученные адреса прошли проверку контрольной суммы, выставляется флаг и процедура поиска больше не повторяется. 
   Микроконтроллер запускает температурное преобразование первого датчика, считывает значение температуры и проверяет контрольную сумму. Если ошибок нет, температура отображается на дисплее, если обнаружена ошибка, на дисплее пишется, что датчик не найден и микроконтроллер выставляет флаг для повторного запуска процедуры поиска адресов. Далее те же самые действия повторяется со вторым датчиком. 
   Если какой-то из датчиков отключается от сети – микроконтроллер отображает это на дисплее. 
  Разжевывать код нет смысла – в нем достаточно комментариев. Единственное, что отмечу, перед функцией main нужно объявить массив структур, в котором будут храниться адреса датчиков.
Подключение двух датчиков DS18B20 к микроконтроллеру 

Ссылки

Основы 1-Wire. Схемы подключения. Типы сигналов.
Обзор команд DS18B20. Инициализация, ROM команды, функциональные команды.
Работа с DS18B20. Подключение 1-Wire библиотеки. Получение температуры.
Datasheet DS18B20

Файлы

Подключение двух датчиков DS18B20. Проект для IAR AVR
Проект для WinAVR
Проект для CodeVisionAVR
Проект для Proteus
Си библиотека 1-Wire 

Related items