реклама на сайте
подробности

 
 
> Датчик DS18B20, Нужен совет
Letis
сообщение Sep 14 2010, 21:11
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 124
Регистрация: 10-07-07
Пользователь №: 29 027



У меня проблема следующего характера. К микроконтроллеру Mega8535 подключены 4 датчика DS18B20. Но я их не могу подключить на одну линию, так как нужно считывать адреса, а датчики розмещены в разных местах, ну в общем, этот вариант мне не подходит.
Тогда я решил разместить датчики на одном порте на на разных линиях. Но когда дело дошло дело до программирования (Code Vision), у меня ничего не получается.
Вот так я подключаю первый датчик
#asm
.equ __w1_port=0x12 ;PORTD
.equ __w1_bit=0
#endasm
Считываю те-ру и хочу сменить адрес шины:
#asm
.equ __w1_port=0x12 ;PORTD
.equ __w1_bit=1
#endasm
Но при компиляции выбивает ошибку.
Посоветуйте, что делать.

Как повесить 4 датчика DS18B20 на разные ноги контроллера ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Леонид Иванович
сообщение Sep 17 2010, 17:59
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986



Для нескольких термометров делал так:

Код
//----------------------------------------------------------------------------
//--------------------------- Цифровые датчики: ------------------------------
//----------------------------------------------------------------------------

//Используются термометры DS18B20 (S20), которые подключены к портам OWPn.
//Считывание и повторный запуск преобразования производится
//в момент считывание таходатчика того же канала.
//Считываются только два байта температуры, CRC не проверяется.
//Суммарное время опроса всех термометров должно быть больше
//времени преобразования, т.е. длительность интервала счета тахометра
//не должна быть меньше 750 мс / CHANNELS.
//Считанное значение температуры заносится в массив Temp[],
//температура представлена в десятых долях градуса.
//Диапазон возможных температур составляет от TEMP_MIN до TEMP_MAX
//градусов. При отсутствии термометра показания равны TEMP_MIN.

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

  #define OWP0   (1 << PC0) //порт цифрового термометра 0
  #define OWP1   (1 << PC1) //порт цифрового термометра 1
  #define OWP2   (1 << PC2) //порт цифрового термометра 2
  #define OWP3   (1 << PC3) //порт цифрового термометра 3
  #define OWP4   (1 << PC4) //порт цифрового термометра 4
  #define OWP5   (1 << PC5) //порт цифрового термометра 5
  
  //Направление:
  #define I_DDRC  (0)
  //Подтягивающие резисторы / начальное состояние:
  #define I_PORTC (0)
  //Макроопределения для работы с портами:
  #define Port_OWP_0(m)   (DDRC |= m)
  #define Port_OWP_Z(m)   (DDRC &= ~m)
  #define Pin_OWP(m)      (PINC & m)

//Маски термометров:
const __flash char Masks[CHANNELS] = {OWP0, OWP1, OWP2, OWP3, OWP4, OWP5};

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

static int Temp[CHANNELS];     //текущая температура
static bool Present[CHANNELS]; //флаги присутствия термометров

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

void Start(char n);         //старт термометра
void Read(char n);          //чиение термометра
void TReset(char n);        //генерация импульса сброса
char TByte(char n, char dat); //запись/чтение байта
bool TBit(char n, bool b);  //запись/чтение бита
void Do_Crc(char b, char *crc); //вычисление CRC

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

void Therm_Init(void)
{
  ACSR = (1<<ACD);          //запрещение аналогового компаратора
  for(char i = 0; i < CHANNELS; i++)
  {
    Temp[i] = TEMP_MIN;     //инициализация температуры
    Start(i);               //старт всех термометров
  }
}

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

void Therm_Exe(char n)
{
  Read(n);                  //чтение термометра - самое первое измерение
  Start(n);                 //старт термометра
}

//-------------------------- Старт термометра: -------------------------------

void Start(char n)
{
  TReset(n);                //импульс сброса
  if(Present[n])
  {
    TByte(n, 0xCC);         //skip ROM
    TByte(n, 0x44);         //convert T
  }
}

//------------------------- Чтение термометра: -------------------------------

void Read(char n)
{
  if(Present[n])
  {
    TReset(n);              //импульс сброса
    if(Present[n])
    {
      TByte(n, 0xCC);       //skip ROM
      TByte(n, 0xBE);       //read scratchpad
#ifdef DS18B20      
      char l = TByte(n, 0xFF); //чтение младшего байта
      char h = TByte(n, 0xFF); //чтение старшего байта
      int t = WORD(h, l);   //температура с дискретностью 0.0625°C
      t = (t * 10) / 16;    //температура с дискретностью 0.1°C
#else
      char Data[9];               //данные термометра
      char Crc = 0;               //инициализация CRC
      for(char i = 0; i < 9; i++)
      {
        char b = TByte(n, 0xFF);  //чтение данных
        Do_Crc(b, &Crc);          //обновление CRC
        Data[i] = b;              //сохранение данных
      }
      int t = TEMP_MIN;
      if(!Crc)
      {
        t = WORD(Data[1], Data[0]) / 2;
        t = (t * 20 - 5 + (int)(Data[7] - Data[6]) * 20 / Data[7]) / 2;
      }
#endif      
      Temp[n] = t;
      return;
    }
  }
  Temp[n] = TEMP_MIN;       //термометр отсутствует
  return;
}

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

void TReset(char n)
{
  char m = Masks[n];
  char si;
  Present[n] = 0;              //сброс флага присутствия термометра
  Port_OWP_0(m);               //OWP <- 0
  Delay_us(500);               //delay 500 uS
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP_Z(m);               //OWP <- 1
  Delay_us(14);                //delay 14 uS
  if(Pin_OWP(m))               //если OWP = 0, то ошибка
  {
    Delay_us(52);              //delay 52 uS
    if(!Pin_OWP(m))            //если OWP = 1, то ошибка
    {
      __restore_interrupt(si); //восстанавление прерываний
      Delay_us(250);           //delay 250 uS
      if(Pin_OWP(m))           //если OWP = 0, то ошибка
      {
        Present[n] = 1;        //если ошибок нет, термометр присутствует
      }
    }
  }
  __restore_interrupt(si);     //восстанавление прерываний в случае ошибки
}

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

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

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

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

//--------------------- Вычисление контрольной суммы: ------------------------

void Do_Crc(char b, char *crc)
{
  for(char i = 0; i < 8; b = b >> 1, i++)
    if((b ^ *crc) & 1) *crc = ((*crc ^ 0x18) >> 1) | 0x80;
     else *crc = (*crc >> 1) & ~0x80;
}


--------------------
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Letis   Датчик DS18B20   Sep 14 2010, 21:11
- - miksergei   Цитата(Letis @ Sep 15 2010, 00:11) У меня...   Sep 14 2010, 23:41
- - Letis   А как нужно сделать ?   Sep 15 2010, 00:51
- - vovanse   AVR318: Dallas 1-Wire master on tinyAVR and megaAV...   Sep 15 2010, 02:35
- - Letis   Чесно говоря я ничего не понял с єтого app_note. М...   Sep 15 2010, 07:06
- - wer_1   http://www.gaw.ru/html.cgi/txt/app/micros/avr/avr3...   Sep 15 2010, 07:32
- - Letis   м-да, сложно єто, проще поставить ключ 4066. А мо...   Sep 15 2010, 08:14
- - Сергей Борщ   Цитата(Letis @ Sep 15 2010, 00:11) Посове...   Sep 15 2010, 08:16
- - Letis   Например ?   Sep 15 2010, 09:42
|- - Сергей Борщ   Цитата(Letis @ Sep 15 2010, 12:42) Наприм...   Sep 15 2010, 10:35
- - Letis   что надежнее ключи или программный метод?   Sep 15 2010, 12:37
|- - MrYuran   Цитата(Letis @ Sep 15 2010, 16:37) что на...   Sep 15 2010, 12:55
- - zalg   У меня такая проблема. Писал код "с нуля...   Sep 15 2010, 17:04
|- - ILYAUL   Цитата(zalg @ Sep 15 2010, 21:04) При вкл...   Sep 15 2010, 17:22
|- - alexeyv   to zalg Цитата(zalg @ Sep 15 2010, 23:04)...   Sep 16 2010, 03:04
|- - serge71   to zalg: Если младший бит "0", может всё...   Sep 16 2010, 08:04
- - zalg   Опыт программирования у меня не большой, так что з...   Sep 15 2010, 17:37
- - ARV   у меня вообще сложилось впечатление, что Code Visi...   Sep 15 2010, 18:01
- - ILYAUL   zalg Вы создайте свою тему всё таки.   Sep 15 2010, 21:12
- - Letis   Цитатаи сам не один вариант написал для обмена 1-w...   Sep 16 2010, 09:20
|- - ARV   Цитата(Letis @ Sep 16 2010, 13:20) Виложи...   Sep 16 2010, 11:42
- - Letis   Код несколько не понятен в силу того что пишу в Co...   Sep 16 2010, 21:18
|- - ARV   Цитата(Letis @ Sep 17 2010, 01:18) Как мн...   Sep 17 2010, 06:17
|- - xemul   Цитата(Letis @ Sep 17 2010, 01:18) Код не...   Sep 17 2010, 09:56


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 13:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01414 секунд с 7
ELECTRONIX ©2004-2016