Время выполнения функций библиотеки OneWire (для управления термодатчиками DS18B20).

Вопросы программирования в системе Ардуино
Эдуард
Администратор
Сообщения: 119
Зарегистрирован: 30 окт 2016, 20:53

Время выполнения функций библиотеки OneWire (для управления термодатчиками DS18B20).

Сообщение Эдуард » 11 дек 2016, 18:59

Функции библиотеки Ардуино для работы с интерфейсом 1-Wire достаточно сложные и явно требуют для выполнения значительного времени. К тому же функции работают с последовательным интерфейсом, а значит, в цикле повторяются многочисленные операции с передачей и приемом битов, что вносит еще больше неопределенности по поводу времени выполнения.

Если программа Ардуино строится по традиционному принципу – последовательное выполнение программных блоков, то время выполнений операций с шиной 1-Wire не имеет большого значения. Одна, две, десять миллисекунд. Какая разница, если все происходит в цикле, например, 1 сек.

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

При разработке Ардуино контроллера элемента Пельтье я вынужден был реализовывать параллельное выполнение нескольких задач с разными временными циклами.
Остро встали вопросы:
    Сколько времени выделять на управление датчиками температуры DS18B20?
    Как организовывать обмен данными по 1-Wire шине?

Пришлось определить время выполнения функций класса OneWire. Я сделал это двумя способами:
    Посчитал теоретически, исходя из временных требований к операциям на шине 1-Wire.
    Измерил специальной программой. Я писал о ней в этой теме.

Для измерения времени выполнения функций библиотеки OneWire я подкорректировал программу, добавил библиотеку и объявление класса OneWire.

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

// определение времени выполнения функций OneWire

#include <OneWire.h>

OneWire sensD (16);  // датчик подключен к выводу 16 (A2)
unsigned int  timerValue; // значение таймера
byte bufData[9];  // буфер данных
 
void setup() {
  Serial.begin(9600);  // инициализируем порт
  // установки таймера 1
  TCCR1A = 0;
  TCCR1B = 0; 
}

void loop() {
  noInterrupts(); // запрет прерываний
  TCNT1H = 0; // сброс таймера
  TCNT1L = 0;
  TCCR1B = 1; // разрешение работы таймера

  // ---------- исследуемый программный блок ---------

   // sensD.reset();  // сброс шины
   // sensD.write(0xCC, 1); // пропуск ROM
   // sensD.write(0x44, 1); // инициализация измерения

  // sensD.reset();  // сброс шины
  // sensD.write(0xCC, 1); // пропуск ROM 
  // sensD.write(0xBE, 1); // команда чтения памяти датчика 
  // sensD.read_bytes(bufData, 9);  // чтение памяти датчика, 9 байтов
  // bufData[0]= sensDs.read();  // чтение памяти датчика, 9 байтов

  // if ( OneWire::crc8(bufData, 8) == bufData[8] ) { bufData[8]=0; }  // проверка CRC
  // else bufData[8]=1;
     
  // -------------------------------------------------

  TCCR1B = 0; // остановка таймера
  timerValue = (unsigned int)TCNT1L | ((unsigned int)TCNT1H << 8); // чтение таймера
  interrupts(); // разрешение прерываний
     
  // вывод на компьютер
  Serial.print( (float)(timerValue - 2) * 0.0625);
  Serial.println(" mks");
  delay(500);
}

По очереди открывал от комментариев функции и получал время выполнения. Результаты я свел в таблицу.

Функция Назначение Расчетное время Измеренное время
reset() Инициализация обмена 960 мкс 966 мкс
write() Запись байта 480 - 960 мкс 548 мкс
read() Чтение байта 480 - 960 мкс 522 мкс
read_bytes() Чтение блока байтов (9байтов) 4320 - 8640 мкс 4700 мкс
crc8 Вычисление контрольной суммы - 7,3 мкс

Получается, что последовательность самой простой инициализации измерения датчика DS18B20 требует 2063 мкс.

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

sensD.reset();  // сброс
sensD.write(0xCC, 1); // пропуск ROM
sensD.write(0x44, 1); // инициализация измерения


А на чтение температуры из датчика DS18B20 и проверку контрольной суммы требуется 6,8 мс.

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

sensD.reset();  // сброс
sensD.write(0xCC, POWER_MODE); // пропуск ROM 
sensD.write(0xBE, POWER_MODE); // команда чтения памяти датчика 
sensD.read_bytes(bufData, 9);  // чтение памяти датчика, 9 байтов
if ( OneWire::crc8(bufData, 8) == bufData[8] ) {  // проверка CRC

Вернуться в «Программирование Ардуино»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость