logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMega8][C] 1wire wyszukiwanie

morson 27 Sty 2010 16:35 1610 1
REKLAMA
  • #1 7600875
    morson
    Poziom 14  
    Witam

    Mam prośbę, napisałem sobie bibliotekę do obsługi 1wire i mam problem w procedurze wyszukiwania do 3 urządzeń wykrywa mi poprawnie, a powyżej wykrywa mi więcej niż powinien
    
    #ifndef _AVR_ONEWIRE_
    #define _AVR_ONEWIRE_
    
    #include <avr/interrupt.h>
    
    #define ONEWIRE_SEARCH_ROM 0xF0
    
    #define ONEWIRE_NO_DEVICES 0xFF
    #define ONEWIRE_DATA_ERROR 0xFE
    #define ONEWIRE_OK 0x00
    
    #define ONEWIRE_LAST_DEVICE -2
    
    int8_t _onewire_level;
    uint32_t _onewire_mask;
    
    static uint8_t onewire_reset()
    {
     ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
     _delay_us(480);
     ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
     _delay_us(70);
     uint8_t ret = ~(ONEWIRE_PORT & (1<<ONEWIRE_PIN));
     _delay_us(410);
     return ret;
    }
    
    static void _onewire_write_bit(uint8_t value)
    {
     uint8_t sreg = SREG;
     cli();
     ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
     _delay_us(1);
     if(value)
     {
      ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
      _delay_us(59);
     }
     else
     {
      _delay_us(59);
      ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
     }
     SREG = sreg;
     _delay_us(30);
    }
    
    static uint8_t _onewire_read_bit()
    {
     uint8_t sreg = SREG;
     cli();
     ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
     _delay_us(1);
     ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
     _delay_us(15);
     uint8_t ret = ONEWIRE_PORT & (1<<ONEWIRE_PIN);
     SREG = sreg;
     _delay_us(75);
     return ret;
    }
    
    static void onewire_write_byte(uint8_t value)
    {
     for(uint8_t i = 0; i < 8; i++)
     {
      _onewire_write_bit(value & 0x01);
      value = value >> 1;
     }
    }
    
    static uint8_t onewire_read_byte()
    {
     uint8_t ret = 0;
     for(uint8_t i = 0; i < 8; i++)
     {
      ret = ret >> 1;
      if(_onewire_read_bit()) ret |= 0x80;
     }
     return ret;
    }
    
    static void onewire_write_command(uint8_t *id)
    {
     onewire_reset();
     if(id)
     {
      onewire_write_byte(0x55);
      for(uint8_t i = 0; i < 8; i++)
       onewire_write_byte(*id++);
     }
     else
     {
      onewire_write_byte(0xCC);
     }
    }
    
    static uint8_t _onewire_search_rom(uint8_t *buffer)
    {
     if(_onewire_level == ONEWIRE_LAST_DEVICE) return ONEWIRE_NO_DEVICES;
     int8_t pos = -1;
     uint8_t bufpos = 0;
     if(!onewire_reset()) return ONEWIRE_NO_DEVICES;
     onewire_write_byte(ONEWIRE_SEARCH_ROM);
     for(uint8_t i = 0; i < 64; i++)
     {
      bufpos = i / 8;
      buffer[bufpos] >>= 1;
      if(_onewire_read_bit())
      {
       if(_onewire_read_bit())
       {
        return ONEWIRE_DATA_ERROR;
       }
       else
       {
    	buffer[bufpos] |= 0x80;
    	_onewire_write_bit(1);
       }
      }
      else
      {
       if(_onewire_read_bit())
       {
    	_onewire_write_bit(0);
       }
       else
       {
        pos++;
        if(pos > _onewire_level)
    	{
    	 _onewire_write_bit(0);
    	 _onewire_mask <<= 1;
    	 _onewire_level++;
    	}
    	else
    	{
    	 if(_onewire_mask & (1<<(_onewire_level - pos)))
    	 {
    	  _onewire_write_bit(1);
          buffer[bufpos] |= 0x80;
         }
    	 else
    	 {
    	  _onewire_write_bit(0);
         }
        }
       }
      }
     }
     uint8_t bits = 0;
     for(int8_t i = 0; i <= _onewire_level; i++)
      if((_onewire_mask >> i) & 1) bits++;
     if(bits == _onewire_level + 1)
     {
      _onewire_level = ONEWIRE_LAST_DEVICE;
      return ONEWIRE_OK;
     }
     if(_onewire_level >= 0) _onewire_mask++;
     if((_onewire_mask & 0x0003) == 0x0002){
      _onewire_mask >>= 1;
      _onewire_level--;
     }
     return ONEWIRE_OK;
    }
    
    static void onewire_findinit()
    {
     _onewire_level = -1;
     _onewire_mask = 0;
    }
    
    static inline uint8_t onewire_find(uint8_t *buffer)
    {
     return _onewire_search_rom(buffer);
    }
    
    #endif
    


    w zastosowaniu ta procedura ma się tak

    
    #include <avr/io.h>
    
    #define ONEWIRE_PORT PINB
    #define ONEWIRE_DDR DDRB
    #define ONEWIRE_PIN PB0
    
    #include "1wire.c"
    
    int main()
    {
     unit8_t ids[8][8];
     ids_count=0;
     onewire_findinit();
     while(ids_count < 8 && onewire_find(ids[id_count]) == ONEWIRE_OK)
     {
      ids_count++;
     }
     while(1);
    }
    


    Byłbym wdzięczny za jakąś sugestię co może być nietak w algorytmie wyszukiwania
  • REKLAMA
  • #2 7613256
    morson
    Poziom 14  
    Problem rozwiązałem sam, stosując procedury Dallasa.

    W pliku dołączam całą bibliotekę 1wire.

    Może komuś się przydadzą.
REKLAMA