Динамическая индикация и датчик DS18B20

Обсуждаем цифровые устройства...
Ответить
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

Добрый день. Возник вопрос. Есть светодиодный 7-сегментный индикатор. Динамически вывожу цифры, все нормально, а вот в момент опроса датчика, индикация гаснет, так как МК работает с датчиком. Как это победить. Если общаюсь с датчиком в обработчике прерывания по таймеру, та же шляпа. Может я что-то не догоняю?
Я не волшебник, я только лечусь
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4752
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Нужно прерывания от таймера заточить под индикацию. Тогда не зависимо от работы с датчиком цифры будут выводиться.
Только во время расчета температуры(преобразования полученных данных от датчика) прерывание это отключать во избежании не верного преобразования.
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2365
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград

Сообщение Dmitry Dubrovenko »

Gurvinok писал(а):общаюсь с датчиком в обработчике прерывания по таймеру
Что значит "общаюсь"?
Процедуру запускаете, или каждый тайм-слот?
ICQ нет, и, в ближайшее время, не будет.
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

Я раньше дел с динамической индикацией не имел. Отсюда и возник вопрос. Я пытался каждую секунду в обработчике прерывания по таймеру получить температуру из датчика. Как я понял надо делать все на оборот. Температура в основном цикле, индикация в прерывании. Единственная засада в том что я использую готовую библиотеку для работы с датчиком. Терзают смутные сомнения что придется все делать самому.
Я не волшебник, я только лечусь
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

Тему модно закрывать. В библиотеке было так.

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

w1_write(0x44);
delay_ms(550);
Я не понял зачем там такая задержка. После ее выкидывания все заработало.
Я не волшебник, я только лечусь
Контактная информация:
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

Вообще-то для более правильного ответа ТС не помешало-бы выложить исходник, и уже опираясь на него (исходник) вести дальнейшую дискуссию ИМХО....
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

Я уже писал, что разобрался. Сочинители библиотеки в CVAVR с перепугу вогнали задержку в пол секунды. Зачем она нужна я так и не понял. В общем перехожу на AVRStudio и буду все с низов писать. CVAVR фигня какая-то.
Я не волшебник, я только лечусь
Контактная информация:
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

Gurvinok писал(а):В общем перехожу на AVRStudio и буду все с низов писать. CVAVR фигня какая-то.
120% поддерживаю :beer: :beer:
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2365
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград

Сообщение Dmitry Dubrovenko »

Gurvinok писал(а):После ее выкидывания все заработало.
Вы, батенька, оказывается "либерал". А я тут про тайм-слоты распинаюсь. :roll:
Gurvinok писал(а):Я не понял зачем там такая задержка.
А если посмотреть в ДШ, что означает команда 0x44, а после этого во временнЫе характеристики?
Выяснится, что, например для 12-битного преобразования, задержка нужна вообще не менее 750ms.
Хотя такая реализация, это - "решение в лоб", или для "паразитного" питания. При всех других условиях, его можно реализовать гораздо правильней.

P.S.: Ну, а что бы получать равные временнЫе интервалы (что необходимо для нормальной динамической индикации), надо научиться пользоваться такими вещами, как прерывания от таймера. :)
ICQ нет, и, в ближайшее время, не будет.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2055
Зарегистрирован: Вт ноя 03, 2009 21:02:38
Откуда: Москва

Сообщение Microtech »

Я столкнулся с такой проблемой в часах на неоновом индикаторе ГИПС-16. Там нужно разворачивать строку из 111 столбцов по 7 точек в высоту. Вывод на индикацию завязан на прерывания от таймера, а нарушения последовательности заметны сразу. Если дать приоритет прерываний на индикацию, датчик DS18B20 может неправильно среагировать на нарушенную временную диаграмму. В итоге он иногда даёт чушь, а не температуру. Если часто опрашивать датчик, глуша прерывания, На индикации заметны "бяки" и моргания.
Сделал опрос редким, раз в пол-минуты. Не глуша прерывания, шлю команды: reset bus, затем &HCC (skip rom), затем &H44 (Convert).
Далее, через несколько секунд, глушу прерывания и шлю &HCC и &HBE. Получаю температуру. Запускаю прерывания. На индикаторе, при тщательном рассмотрении, может что-то и мигает. Не особо заметно. Вся математика преобразования 2-х байт в градусы и другие дела, происходят в фоне, не мешая динамической индикации.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15751
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Стандартное решение подсчет строк на длительность межопросного интервала и передача/прием данных в "мертвом окне" в конце строки. 8)
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

Когда сделал динамическую индикацию не по прерываниям, а в основном цикле, тоже возник конфликт с DS18B20. Пришлось обмен разбить на элементарные операции:
Спойлер

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

//----------------------------------------------------------------------------

//Модуль обслуживания термометра DS18B20

//Цифровой датчик температуры DS18B20 подключен по 1-проводному
//интерфейсу, который реализован программно.
//Для подключения датчика используется порт OWP.
//Порт должен быть  настроен на ввод,
//внутренний подтягивающий резистор должен быть отключен,
//используется внешний подтягивающий резистор 4.7 кОм.
//Во время измерения обеспечивается сильноточная
//подтяжка линии данных (порт переключается на вывод ВЫСОКОГО уровня),
//поэтому возможно использование термометра с паразитным питанием.
//Должны быть определены следующие макросы:
//#define OWP (1 << Pxn)
//#define Port_OWP_OUT (DDRx |= OWP)
//#define Port_OWP_IN (DDRx &= ~OWP)
//#define Pin_OWP   (PINx & OWP)
//Датчик DS18B20 должен быть запрограммирован в 12-разрядный режим
//(биты R0, R1 в регистре конфигурации равны единице,
//это заводская установка).

//Дискретность измерения температуры составляет 0.1°C.
//Из датчика считываются только 2 байта, CRC не проверяется.

//Для инициализации модуля один раз в начале программы должна
//вызываться функция DS18B20_Init(). Функция DS18B20_Exe() должна
//вызываться в основном цикле, она осуществляет запуск преобразования,
//формирует в фоновом режиме временную задержку и производит считывание
//температуры во внутреннюю переменную Temp.

//Поскольку обмен по однопроводной шине довольно медленный (чтение или
//запись одного байта занимает около 0.5 мс), целиком выполнять
//чтение температуры и запуск преобразования за один вызов DS18B20_Exe()
//нельзя. Это может нарушить выполнение других задач. Поэтому процесс
//обмена с термометром разбит на элементарные операции, каждая из
//которых включает в себя обмен не более чем одним байтом.

//Значение температуры в любой момент может быть считано с помощью функции
//DS18B20_GetT(). Значение представлено в виде 16-разрядного целого числа
//со знаком и представляет собой температуру в десятых долях градуса.
//До того, как закончится первое преобразование температуры, возвращается
//значение T_NORDY. В случае отсутствия ответа термометра возвращается
//код ошибки T_ERROR.

//----------------------------------------------------------------------------

#include "Main.h"
#include "DS18B20.h"

//------------------------------ Константы: ----------------------------------

#define TCONV 800      //время преобразования температуры, мс

//----------------------------- Переменные: ----------------------------------

static int Temp;       //текущая температура
static char TState;    //состояние процесса измерения

//-------------------------- Прототипы функций: ------------------------------

bool TReset(void);     //формирование импульса сброса
char TByte(char dat);  //запись/чтение байта
bool TBit(bool b);     //запись/чтение бита

//--------------------- Инициализация термометра: ----------------------------

;вызывается 1 раз
void DS18B20_Init(void)
{
  Temp = T_NORDY;      //результат измерения не готов
  TState = 0;          //начало процесса
}

//----------------------- Измерение температуры: -----------------------------

;вызывается в цикле, t устанавливается в обработчике
;системного таймера раз в 0.5 мс
void DS18B20_Exe(bool t)
{
  static int TTimer = 0;              //таймер термометра
  static int T;                       //код температуры
  if(t)
  {
    if(TTimer)                        //если интервал таймера не истек,
    {
      TTimer--;                       //ожидание (и декремент таймера)
    }
    else                              //иначе выполнение шага
    {
      switch(TState)
      {
      case 0: if(TReset())            //команда RESET
                TState++;             //если выполнена успешно, следующий шаг
                  else TState = 0xFF; //если ошибка, переход на задержку
              break;
      case 1: TByte(0xCC);            //команда SKIP ROM
              TState++;               //следующий шаг
              break;               
      case 2: TByte(0x44);            //команда START CONVERSION
              TTimer = ms2sys(TCONV); //загрузка задержки преобразования
              TState++;               //следующий шаг
              break;
      case 3: if(TReset())            //команда RESET
                TState++;             //если выполнена успешно, следующий шаг
                  else TState = 0xFF; //если ошибка, переход на задержку
              break;
      case 4: TByte(0xCC);            //команда SKIP ROM
              TState++;               //следующий шаг
              break;
      case 5: TByte(0xBE);            //команда READ SCRATCHPAD
              TState++;               //следующий шаг
              break;
      case 6: T = TByte(0xFF);        //чтение TL
              TState++;               //следующий шаг
              break;
      case 7: T |= TByte(0xFF) << 8;  //чтение TH
              TState++;               //следующий шаг
              break;
      case 8: Temp = 10 * T / 16;     //вычисление температуры
              TState = 0;             //переход на первый шаг
              break;
      default: TTimer = ms2sys(TCONV); //загрузка задержки
              Temp = T_ERROR;         //код ошибки
              TState = 0;             //переход на первый шаг
      }
    }
  }
}

//--------------------- Генерация импульса сброса: ---------------------------

bool TReset(void)
{
  char si;
  Port_OWP_0;
  Port_OWP_OUT;                //OWP <- 0
  Delay_us(500);               //delay 500 uS
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP_IN;                 //OWP <- 1
  Delay_us(14);                //delay 14 uS
  if(Pin_OWP)                  //если OWP = 0, то ошибка
  {
    Delay_us(52);              //delay 52 uS
    if(!Pin_OWP)               //если OWP = 1, то ошибка
    {
      __restore_interrupt(si); //восстанавление прерываний
      Delay_us(250);           //delay 250 uS
      if(Pin_OWP)              //если OWP = 0, то ошибка
      {
        return(1);             //если ошибок нет, термометр присутствует
      }
    }
  }
  __restore_interrupt(si);     //восстанавление прерываний в случае ошибки
  return(0);
}

//-------------- Запись/чтение байта по однопроводной шине: ------------------

char TByte(char dat)
{
  char res;
  for(char i = 0; i < 8; i++)
  {
    res = res >> 1;
    if(TBit(dat & 1)) res |= 0x80;
     else res &= ~0x80;
    dat = dat >> 1;
  }
  return(res);
}

//--------------- Запись/чтение бита по однопроводной шине: ------------------

bool TBit(bool b)
{
  char si;
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP_0;
  Port_OWP_OUT;                //OWP <- 0
  Delay_us(2);                 //delay 2 uS
  if(b) Port_OWP_IN;           //bit = 1, OWP <- 1
  Delay_us(13);                //delay 13 uS
  bool owp = Pin_OWP;          //чтение порта
  Delay_us(45);                //delay 45 uS
  Port_OWP_1;                  //force pullup
  Port_OWP_OUT;
  __restore_interrupt(si);     //восстанавление прерываний
  Delay_us(2);                 //delay 2 uS
  return(owp);
}

//------------------------- Чтение температуры: ------------------------------

int DS18B20_GetT(void)
{
  return(Temp);
}

//----------------------------------------------------------------------------
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2055
Зарегистрирован: Вт ноя 03, 2009 21:02:38
Откуда: Москва

Сообщение Microtech »

BOB51 так действительно не будет костылей в цикле индикации. Будет время - переделаю. Сейчас цикл опроса никак не связан с индикацией. Индикация только по таймеру, другое по циклу и счётчику в программе. Лениво переделывать то, что работает пару лет без вмешательства...
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

А если посмотреть в ДШ, что означает команда 0x44, а после этого во временнЫе характеристики?
А если еще посмотреть, то можно увидеть что если используем внешнее питание то после команды 0х44 можно забить на временнЫе интервалы. Пока датчик думает и раскладывает все по своим полкам, шину прижимает к нулю, а когда все готово отпускает.
Ну, а что бы получать равные временнЫе интервалы (что необходимо для нормальной динамической индикации), надо научиться пользоваться такими вещами, как прерывания от таймера.
Может я и ошибаюсь, но CVAVR запрещает прерывания при работе функций 1-wire. Где находится библиотека я так и не понял. Только хедоровый файл с объявленными функциями. Еще раз повторяю! CVAVR это какое-то недоразумение. Переписал все в Студии 6.1 и все работает.
Я не волшебник, я только лечусь
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2365
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград

Сообщение Dmitry Dubrovenko »

Gurvinok писал(а):А если еще посмотреть, то можно увидеть что если используем внешнее питание то после команды 0х44 можно забить на временнЫе интервалы
А если посмотреть ещё внимательней, то можно обнаружить, что про это уже давно сказано. :)))
ICQ нет, и, в ближайшее время, не будет.
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 198
Зарегистрирован: Вт ноя 07, 2006 00:09:58
Откуда: Москва

Сообщение Gurvinok »

про это уже давно сказано
Где? :shock:
Лан, хорош. :)) Все работает как часы. Тссс я про DS1307 ничего не говорил. :)))
Я не волшебник, я только лечусь
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2365
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград

Сообщение Dmitry Dubrovenko »

Gurvinok писал(а):Где?
Да вот же:
Dmitry Dubrovenko писал(а):Хотя такая реализация, это - "решение в лоб", или для "паразитного" питания. При всех других условиях, его можно реализовать гораздо правильней.
ICQ нет, и, в ближайшее время, не будет.
Контактная информация:
Ответить

Вернуться в «Цифровая техника»