STM Урок 94. DS18B20. Подключаем несколько датчиков на провод. Часть 3



В предыдущей части урока мы написали полностью функцию поиска идентификаторов датчиков и считали уникальные коды со всех датчиков температуры.

Перейдём в функцию main() файла main.c и добавим локальную переменную для счётчика

 

char c;

uint8_t i;

 

 

Затем после вызова функции инициализации покажем наши результаты в терминальной программе

HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

sprintf(str1,"Dev count: %d\r\n", Dev_Cnt);

HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

for(i=1;i<=Dev_Cnt;i++)

{

  sprintf(str1,"Device %d\r\n", i);

  HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  sprintf(str1,"ROM RAW: %02X %02X %02X %02X %02X %02X %02X %02X\r\n",

    Dev_ID[i-1][0], Dev_ID[i-1][1], Dev_ID[i-1][2], Dev_ID[i-1][3],

    Dev_ID[i-1][4], Dev_ID[i-1][5], Dev_ID[i-1][6], Dev_ID[i-1][7]);

  HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  sprintf(str1,"Family CODE: 0x%02X\r\n", Dev_ID[i-1][0]);

  HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  sprintf(str1,"ROM CODE: 0x%02X%02X%02X%02X%02X%02X\r\n", Dev_ID[i-1][6], Dev_ID[i-1][5],

    Dev_ID[i-1][4], Dev_ID[i-1][3], Dev_ID[i-1][2], Dev_ID[i-1][1]);

  HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  sprintf(str1,"CRC: 0x%02X\r\n", Dev_ID[i-1][7]);

  HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

}

/* USER CODE END 2 */

 

Соберём код, прошьём контроллер и посмотрим результат в терминальной программе

 

image05

 

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

Перейдём в функцию ds18b20_MeasureTemperCmd файла ds18b20.c и добавим для начала в неё локальную переменную

void ds18b20_MeasureTemperCmd(uint8_t mode, uint8_t DevNum)

{

  int i = 0;

  ds18b20_Reset();

 

 

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

 

ds18b20_WriteByte(0xCC);

}

else

{

  //Match Rom

  ds18b20_WriteByte(0x55);

  for(i=0;i<=7;i++)

  {

    ds18b20_WriteByte(Dev_ID[DevNum-1][i]);

  }

}

//CONVERT T

Здесь мы используем команду Match Rom с кодом 0x55, после передачи которой мы передаём полностью ROM-код устройства вместе с вендором и контрольной суммой. Поэтому нам нет необходимости её генерировать заново. И после этого все команды и всё чтение до сброса устройств будут принадлежать тому устройсву, чей код в шину мы и передадим.

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

Вернёмся в файл main.c и в бесконечном цикле функции main() дадим всем нашим датчикам команду начинать конвертировать значение температуры

/* USER CODE BEGIN 3 */

for(i=1;i<=Dev_Cnt;i++)

{

  ds18b20_MeasureTemperCmd(NO_SKIP_ROM, i);

}

HAL_Delay(800);

Соберём код, прошьём контроллер, и посмотрим как происходит обращение к разным устройствам в программе логического анализа

image06

 

 

Вернёмся в файл ds18b20.c в функцию ds18b20_ReadStratcpad и уже известный нам по предыдущей функции код в неё. Переменная для счётчика у нас уже есть

  ds18b20_WriteByte(0xCC);

}

else

{

  //Match Rom

  ds18b20_WriteByte(0x55);

  for(i=0;i<=7;i++)

  {

    ds18b20_WriteByte(Dev_ID[DevNum-1][i]);

  }

}

//READ SCRATCHPAD

Также мы кое-что не закончили в функции инициализации. Мы там не проинициализировали некоторые конфигурационные регистры в датчике, так как мы ещё не знали как к ним обращаться и с каким кодом.

Выйдем в данной функции из цикла считывания кодов ROM из датчиков и напишем ещё один цикл, который и запишет необходимые значения в регистры всех наших датчиков

    else break;

  }

  for(i=1;i<=Dev_Cnt;i++)

  {

    if(ds18b20_Reset()) return 1;

    //Match Rom

    ds18b20_WriteByte(0x55);

    for(j=0;j<=7;j++)

    {

      ds18b20_WriteByte(Dev_ID[i-1][j]);

    }

    //WRITE SCRATCHPAD

    ds18b20_WriteByte(0x4E);

    //TH REGISTER 100 градусов

    ds18b20_WriteByte(0x64);

    //TL REGISTER - 30 градусов

    ds18b20_WriteByte(0x9E);

    //Resolution 12 bit

    ds18b20_WriteByte(RESOLUTION_12BIT);

  }

}

return 0;

Вернёмся в бесконечный цикл функции main() файла main.c и добавим туда следующий код для считывания и обработки показаний

  HAL_Delay(800);

  for(i=1;i<=Dev_Cnt;i++)

  {

    ds18b20_ReadStratcpad(NO_SKIP_ROM, dt, i);

    sprintf(str1,"STRATHPAD %d: %02X %02X %02X %02X %02X %02X %02X %02X; ",

      i, dt[0], dt[1], dt[2], dt[3], dt[4], dt[5], dt[6], dt[7]);

    HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

    raw_temper = ((uint16_t)dt[1]<<8)|dt[0];

    if(ds18b20_GetSign(raw_temper)) c='-';

    else c='+';

    temper = ds18b20_Convert(raw_temper);

    sprintf(str1,"Raw t: 0x%04X; t: %c%.2f\r\n", raw_temper, c, temper);

    HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);

  }

  HAL_Delay(150);

}

/* USER CODE END 3 */

Соберём код, прошьём контроллер и посмотрим результат в терминальной программе

image07

Мы видим, как попеременно читается температура из обоих датчиков.

Давайте поместим один из датчиков в стакан с кипятком и посомтрим реакцию программы

image08

Мы видим, что показания температуры первого датчика неуклонно увеличиваются, а показания второго — не меняются.

Это с уверенностью позволяет нам убедиться в том. что мы написали всё правильно и тем самым также убедиться в том, что мы научились работать с несколькими устройствами на шине 1-WIRE, отдавая раздельно им команды, считывать с них уникальные коды независимо от количества таких устройства, а также обращаться раздельно к любому из них.

Спасибо всем за внимание!

 

 

Предыдущая часть Программирование МК STM32 Следующий урок

 

 

Исходный код

 

 

Отладочную плату можно приобрести здесь STM32F103C8T6

Логический анализатор можно приобрести здесь Логический анализатор на 8 каналов

Датчик температуры в экране с проводом можно приобрести здесь DS18B20 в экране с проводом

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM DS18B20. Подключаем несколько датчиков на провод