Одна проблема с проводом

Мне нужна ваша квалифицированная помощь! Я программирую на С++, используя PIC 18F87J50 и пытаюсь подключить DS18B20 к моему порту H0!

Я думаю, что моя базовая программа правильная, поэтому... проблема у меня (думаю, у меня есть), когда вы выполняете команду ПЗУ, я ищу 64-битный код ПЗУ.

Первый байт должен указать мне, в какой семье принадлежит компонент (28h). Следующие 48 бит должны дать мне серию uniq только для этого компонента. Последний используется для CRC.

Я правильно думаю, когда делаю так:

void Device_ID( uint8_t command ){
    uint8_t ROM_CODE[8]; // 1 byte CRC, 6 bytes SERIAL, 1 byte Family code
    uint8_t loop;
    static char container[8];

    OW_reset_pulse();
    OW_write_byte( command );

    for(loop = 0; loop < 8; loop++)     // 1 byte in per time = 64-bits
    {
        ROM_CODE[loop] = OW_read_byte(); 
    }

    HexToStrWithZeros(ROM_CODE[0], container);
    Display_Cls();
    Display_StringAt ("Family Code: ",5,6);
    Display_Buffer (container);
}

Если я попрошу код в ROM_CODE [1-6], я должен получить номер uniq? should'nt я??

С уважением!

4
задан Christian 15 дек. '09 в 13:07
источник поделиться

2 ответов

Ну, лучший способ получить доступ к серийному номеру - это, вероятно, скопировать его в отдельный буфер, используя strncpy.

#include <string.h>

...

char family;
char serial[7]; // Extra byte for null terminator
char checksum;

...

family = ROM_CODE[0];

strncpy(serial, &ROM_CODE[1], 6);
serial[6] = '\0';

checksum = ROM_CODE[7];

...

&ROM_CODE[1] нужно найти адрес второго элемента в ROM_CODE. ROM_CODE+1 также может работать, но мой C - это ржавый прикосновение.

В конце добавляется нуль ('\ 0'), поскольку C использует строки с нулевым завершением. Это обеспечит совместимость с подпрограммами библиотеки C и обычно используемыми идиомами C.

Вы также можете получить доступ к нему непосредственно из массива. Но с этим будет труднее работать и вряд ли стоит того, если вам не понадобится действительно, что 6 байт памяти.

В зависимости от того, насколько сложным является ваше приложение, вы можете обернуть это в класс. Передайте 8-символьный буфер в конструктор, а затем используйте методы, такие как getFamily()/getSerial(), чтобы получить нужную информацию.

Для очень простого приложения, однако, есть много дополнительного кода, чтобы упростить что-то, что уже очень управляемо.

2
ответ дан Adam Luchjenbroers 15 дек. '09 в 14:25
источник поделиться

Вот код, который должен позволить вам прочитать идентификатор устройства. Я думаю, что ваш код работает быстро, вот какой-то код, который я использовал для взаимодействия с DS18B20.

/****************************************************************************
* temperature.h
****************************************************************************/

#ifndef TEMP_H
#define TEMP_H

extern double read_temp ( void );
extern   void start_temp( void );
extern   void Device_ID ( void );

#endif

/****************************************************************************
* temperature.c
****************************************************************************/

void     reset_ow(void);
void     write_ow(uint8_t  b);
uint8_t  read_ow (void);

#define OW_TEMP_SIG LATHbits.LATH0
#define OW_TEMP_TRIS TRISHbits.TRISH0
#define OW_TEMP_SIG_IN PORTHbits.RH0
#define DIR_OUT 0
#define DIR_IN 1


void Device_ID( void )
{
    uint8_t loop; 
   uint8_t family; 
   uint8_t checksum; 
   uint8_t ROM_CODE[8];         // 1 byte CRC, 6 bytes SERIAL, 1 byte Family code

   reset_ow();
   write_ow(0x33); // READ ROM COMMAND DS18B20

    for(loop = 0; loop < 8; loop++) // 1 byte in per time = 64-bits
    {
        ROM_CODE[loop] = read_ow();
    }

    family = ROM_CODE[0];
    checksum = ROM_CODE[7];

  // add extra code to handle code
}

void start_temp(void) 
{
   uint8_t i;

   OW_TEMP_SIG=1;
   OW_TEMP_TRIS=DIR_OUT;
   for ( i=0;i<100;i++)
   {
       Delay_us(100);
   }
   reset_ow();
   write_ow(0xcc); // skip rom
   write_ow(0x44); // start t conv
}

double read_temp(void) 
{
   double temp=0;
   S16 itemp;

   reset_ow();
   write_ow(0xcc); // skip rom
   write_ow(0xbe); // read scratch pad
   itemp=read_ow();
   itemp|=(S16)read_ow()<<8;

   temp = itemp*(0.0625);
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   return temp; 
}


void reset_ow(void)
{
   OW_TEMP_TRIS=DIR_OUT;
   OW_TEMP_SIG=0;
   Delay_us(250);
   Delay_us(250);
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   Delay_us(250);
   Delay_us(250);
}

void write_ow(uint8_t b)
{
   uint8_t i;

   OW_TEMP_SIG=1;
   OW_TEMP_TRIS=DIR_OUT;
   for ( i=0;i<8;i++)
   {
      OW_TEMP_SIG=0;
      if ( b & 0x01 )
      {
         Delay_us(10);
         OW_TEMP_SIG=1;
      }
      Delay_us(70);
      OW_TEMP_SIG=1;
      Delay_us(10);
      b >>= 1;
   }
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
}

uint8_t read_ow(void)
{
   uint8_t b=0;
   uint8_t m;
   uint8_t i;

   m=1;
   for ( i=0;i<8;i++)
   {
      OW_TEMP_SIG=1;
      OW_TEMP_TRIS=DIR_OUT;
      OW_TEMP_SIG=0;        
      Delay_us(8);
      OW_TEMP_TRIS=DIR_IN;
      OW_TEMP_SIG=1;
      Delay_us(15);

      if ( 1 == OW_TEMP_SIG_IN )
      {
         b |= m;
      }
      m <<=1;
      Delay_us(60);
   }
   OW_TEMP_TRIS=DIR_IN;
   OW_TEMP_SIG=1;
   return b;
}
0
ответ дан Rex Logan 26 дек. '09 в 21:59
источник поделиться

Другие вопросы по меткам