Nesse artigo disponibilizo uma biblioteca para acesso a dispositivos one wire.


O que é one wire?

 O 1-Wire é um sistema de barramento projetado pela Dallas Semicondutor Corp. que provê dados de baixa velocidade, sinalização e sinal único de energia. Ele tem um conceito similar ao do I²C, mas com taxas mais baixas de dados e maior alcance.

 O 1-Wire é basicamente um acessório pequeno e utilizado em funções digitais e também em instrumentos de medição de temperatura (termômetro).

 Uma rede de dispositivos 1-Wire associados com um Mestre, é chamada de MicroLan.

 Um diferencial do barramento 1-Wire é o fato de poder utilizar apenas dois fios: dados e GND. Para isso, o dispositivo 1-Wire dispõe de um capacitor de 800 pF para armazenar carga e alimentar o dispositivo durante os períodos onde o cabo de dados estiver sendo usado para o tráfego de dados.

 Dependendo de sua função, os dispositivos 1-Wire podem ser utilizados como componentes únicos num circuito integrado e em pacotes TO92. Em alguns casos é utilizado de forma portátil no chamado iButton que utiliza uma bateria de relógio de pulso.

 Alguns fabricantes também produzem dispositivos um pouco mais complexos que um componente único utilizando o barramento 1-Wire para comunicação.

 Um dispositivo 1-Wire pode ser apenas um de vários componentes em uma placa de circuitos dentro de um produto, mas também é encontrado em isolamento dentro de dispositivos como sensores de temperatura ou anexo a um dispositivo sendo monitorado.

 Alguns sistemas de laboratório e outros tipos de sistemas de aquisição de dados e controle, conectam-se ao dispositivo 1-Wire usando cabos com o conector modular ou com o cabo do tipo CAT-5 com o dispositivo montado em um soquete incorporado a um pequeno PCB ou anexo a um objeto sendo monitorado. Em tais sistemas, conectores RJ11 (6P2C ou 6P4C, comumente utilizados em telefones) são populares.

 Sistemas de sensores e atuadores podem ser construídos conectando componentes 1-Wire, cada qual incluindo toda a lógica necessária para a operação do barramento 1-Wire. Como exemplificação temos loggers de temperatura, temporizadores, sensores de tensão e corrente, monitores de bateria e de memória. Estes podem ser conectados a um computador utilizando um conversor de seu barramento. USB, serial RS-232 e porta paralela são interfaces populares em soluções que visam conectar a MicroLan ao computador provedor. MicroLans também fazem interface com microcontroladores como o Arduino, Parallax BASIC Stamp, Parallax Propeller, PICAXE, a família Microchip PICe a família RENESAS.

 O iButton (também conhecido como Dallas Key ou Chave Dallas) é um encapsulamento mecânico que coloca o componente 1-Wire dentro de um pequeno “botão” similar a uma bateria em forma de disco. Os iButtons são conectados a um sistema que usa o barramento 1-Wire através de soquetes com contatos que tocam a “tampa” e a “base” da caixinha. iButtons são como Smart Tickets da Akbil dentro do transporte público de Istambul. Como alternativa, a conexão pode ser semi-permanente com um tipo de soquete diferente o iButton afixa-se a ele, mas é facilmente removível.

 Cada chip 1-Wire tem um código único gravado nele. Essa característica faz com que o chip, especialmente no encapsulamento do iButton, seja adequado para a utilização como uma chave para abrir fechaduras, armar e desarmar alarmes, fazer autenticação de usuários em sistemas computacionais, operações de registro de tempo e outras utilizações similares.

Fonte: wikipedia

Essa biblioteca foi escrita para a linha PIC da Microchip, porem com algumas pequenas modificações é possível a utilização em qualquer linha de microcontrolador.

Segue os códigos da biblioteca:

Arquivo .h:

// 1-wire functions
unsigned short Ow_Read_Bit();
unsigned char Ow_Read_Byte();
void Ow_Write_One();
void Ow_Write_Zero();
void Ow_Write_Byte(unsigned char);
unsigned short Ow_Reset();

Arquivo .c:

 
#include "one_wire_functions.h"
 
// Variables used by the 1-wire I/O functions
 
sbit OW_DIR at TRISC.B0; // Direction of I/O pin
sbit OW_READ at PORTC.B0; // Read from I/O pin
sbit OW_WRITE at LATC.B0; // Write to I/O pin
// Reads one bit from the I/O pin
unsigned short Ow_Read_Bit()
{
   unsigned short BitValue; // Bit to be returned
   OW_DIR = 0; // Set I/O pin to output
   OW_WRITE = 0; // Drive bus low
   Delay_us(6); // Wait 6 usecs
   OW_DIR = 1; // Release the bus
   Delay_us(9); // Wait 9 usecs
   BitValue = OW_READ; // Read bit value on I/O pin
   Delay_us(55); // Wait 55 usecs
   return BitValue; // Return bit read
}
// Reads a byte from the I/O pin
unsigned char Ow_Read_Byte()
{
   unsigned char ByteRead; // Byte to be returned
   // Get the byte value by reading the I/O pin
   // once for each bit
   ByteRead.B0 = Ow_Read_Bit();
   ByteRead.B1 = Ow_Read_Bit();
   ByteRead.B2 = Ow_Read_Bit();
   ByteRead.B3 = Ow_Read_Bit();
   ByteRead.B4 = Ow_Read_Bit();
   ByteRead.B5 = Ow_Read_Bit();
   ByteRead.B6 = Ow_Read_Bit();
   ByteRead.B7 = Ow_Read_Bit();
   return ByteRead; // Return the byte
}
// Sends a '1' bit to the I/O pin
void Ow_Write_One()
{
   OW_DIR = 0; // Set I/O pin to output
   OW_WRITE = 0; // Drive bus low
   Delay_us(6); // Wait 6 usecs
   OW_DIR = 1; // Release the bus
   Delay_us(64); // Wait 64 usecs
}
// Sends a '0' bit to the I/O pin
void Ow_Write_Zero()
{
   OW_DIR = 0; // Set I/O pin to output
   OW_WRITE = 0; // Drive bus low
   Delay_us(60); // Wait 60 usecs
   OW_DIR = 1; // Release the bus
   Delay_us(10); // Wait 10 usecs
}
// Sends a byte to the I/O pin
void Ow_Write_Byte(unsigned char ByteToSend)
{
// Writes the byte passed by checking
   // it one bit at a time and sending the
   // bit's value to the I/O pin
   if (ByteToSend.B0)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B1)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B2)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B3)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B4)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B5)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B6)
      Ow_Write_One();
   else
      Ow_Write_Zero();
   if (ByteToSend.B7)
      Ow_Write_One();
   else
      Ow_Write_Zero();
}
// Sends a reset signal then reads the I/O pin for a device presence pulse
unsigned short Ow_Reset()
{
   unsigned short response; // Holds the bit to be returned
   OW_DIR = 0; // Set I/O pin to output
   OW_WRITE = 0; // Drive bus low
   Delay_us(480); // Wait 480 usecs
   OW_DIR = 1; // Release the bus
   Delay_us(70); // Wait 70 usecs
   response = OW_READ; // Check I/O pin for presence pulse
   // (0 if device(s) responded, 1 if no devices did)
   Delay_us(410); // Wait 410 usecs
   return response; // Return result
}
//--------------------------------------------------------
//
// The functions below are from an example published
// in Maxim's Application Notes ac:AN187
//
//--------------------------------------------------------
static unsigned char dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
unsigned char crc8;
unsigned char docrc8(unsigned char value)
{
   crc8 = dscrc_table[crc8 ^ value];
   return crc8;
}

Exemplo de utilização [Nesse exemplo o pino de dados do one-wire está no PORTC.0]:

ds1820_uc_interface-1device
Esquema de ligação de sensor de temperatura DS1820
unsigned char Leitura_Temperatura(unsigned char Canal,unsigned int *Valor,unsigned char *contTemperatura)
{
   unsigned char v1,v2,v3;
 
   GIE_bit = 0;
   if((*contTemperatura)++==0) // Solicita o inicio da conversão
   {
      Ow_Reset(&PORTC, Canal);       // Onewire reset signal
      Ow_Write(&PORTC, Canal, 0xCC); // Issue command SKIP_ROM
      Ow_Write(&PORTC, Canal, 0x44); // Issue command CONVERT_T
   }
   else if(*contTemperatura>5) // Aguarda a conclusão da conversão
   {      
      *contTemperatura=0;
      Ow_Reset(&PORTC, Canal);
      Ow_Write(&PORTC, Canal, 0xCC); // Issue command SKIP_ROM
      Ow_Write(&PORTC, Canal, 0xBE); // Issue command READ_SCRATCHPAD
      v1 = Ow_Read(&PORTC, Canal);  //parte baixa
      v2 = Ow_Read(&PORTC, Canal);  //parte alta
      GIE_bit = 1;
      if((v1==0xff)&&(v2==0xff))
      {
         *Valor = 0;
         return 1;
      }
// Check if temperature is negative
      v3 = v1>>1;
      Valor1= (v1&1)?5:0;
      Valor1+=v3*10;
      Valor1*=(v2!=0)?-1:1;
      *Valor = Valor1;
      return 1;
   }
   Delay_us(120);
   return 0;
}
 
void main()
{
   unsigned int Temp1;
   unsigned char cTemperatura1;  
   while(1)
   {
      Leitura_Temperatura(0,&Temp1,&cTemperatura1);
   }
}
[C] Rotinas de acesso – One Wire por software
Tags:                     

Deixe uma resposta

%d blogueiros gostam disto: