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] czujnikami temperatury DS18B20

marti_ql 24 Maj 2009 11:05 1851 3
REKLAMA
  • #1 6567766
    marti_ql
    Poziom 10  
    Mam problem z czujnikami temperatury DS18B20 na 1wire.
    Polega na tym, że procesor widzie oba podłączone czujniki, ale czyta tylko z jednego. Czytanie ROMu skutkuje wyświetleniem informacji z jednego czujnika (28 FF FC 29 01 00 00 87) natomiost z drugiego czujnika - 28 00 00 00 00 00 00 00 (przy podłączeniu pojedyńczo informacja z czujnika wygląda następująco: 28 B8 64 2A 01 00 00 76).
    Co może być tego przyczyną?

    Na szybko wyrysowany schemat:
    [ATmega8][C] czujnikami temperatury DS18B20
  • REKLAMA
  • Pomocny post
    #2 6567862
    Dawid_20
    Poziom 17  
    A w jaki sposób wyszukujesz te czujniki? Należy to zrobić przez SEARCHROM, zapisać gdzieś wszystkie adresy, a przy odczycie temperatury wywoływać kolejno te adresy.

    Wyszukiwanie wszystkich układów:
    unsigned char ow_search_address()
    {
    	uint8_t conf_mask[8]={0};
    	uint8_t i, j, retcode;
    	unsigned char dev_num;
    
    	for(j=0;j<3;j++)
    	for(i=0;i<8;i++)
    	rom_address[j][i]=0;
    
    	i=255;
    
    	for(dev_num=0;dev_num<max_device;dev_num++)
    	{
    		if(ow_reset()) return 3;
    		ow_write_byte(search_rom);
    
    		if(dev_num)
    		{
    			
    			 // Search for the last conflict
    			 
    			for(i=63; i<64; i--)
    			{
    				if(conf_mask[i/8] & (1<<(i%8))) break;
    			}
    
    			
    			 // If i==255 than there was no conflicts and we found all devices
    			 
    			if(i==255) 
    			{
    				dev_num--;
    				break;
    			}
    
    			
    			 // Rewrite all bits before conflict bit
    			 
    			for(j=0;j<i;j++)
    			{
    				rom_address[dev_num][j/8] |= (rom_address[dev_num-1][j/8] & (1<<(j%8)));
    				
    				ow_read_bit();
    				ow_read_bit();
    				ow_write_bit(rom_address[dev_num][j/8]&(1<<(j%8)));
    			}
    
    			
    			 // In conflict position choose other option = 0
    			 
    			if(i<64)
    			{
    				rom_address[dev_num][i/8] &= ~(1<<(i%8));
    				
    				ow_read_bit();
    				ow_read_bit();
    				ow_write_bit(0);
    
    				conf_mask[i/8] &= ~(1<<(i%8));
    			}
    		}
    
    		for(j=i+1;j<64;j++) 
    		{
    			retcode = ow_read_bit();
    			retcode <<= 1;
    			retcode |= ow_read_bit();
    
    			if (retcode == 1) // all zeros
    			{
    				ow_write_bit(0);
    			}
    			if (retcode == 2) // all ones
    			{
    				rom_address[dev_num][j/8] |= (1<<(j%8));
    				ow_write_bit(1);
    			}
    			if (!retcode) // conflict
    			{
    				conf_mask[j/8] |= (1<<(j%8));
    				rom_address[dev_num][j/8] |= (1<<(j%8));
    				ow_write_bit(1);
    			}
    		}
    	}
    
    	if (dev_num!=max_device) dev_num++;
    	return dev_num;
    }


    Zapis pod konkretny układ:
    void ow_write_address(uint8_t dev)
    {
    	uint8_t j;
    
    	for(j=0;j<8;j++)
    	{
    		ow_write_byte(rom_address[dev][j]);
    	}
    }


    Ogólny odczyt:
    .....
    .....
    dev = ow_search_address();
    lcd_puts("Ukladow: ");
    lcd_digit(dev);
    
    if(dev!=3 && dev!=0)
    {
             for(i=0;i<dev;i++)
    	{
    	       t=pomiar(i);					
    					
    		if((t>>15)&0x01)		t = ~t + 0x01;
    					
       		t=(t*10)>>4;
              }
    }
    ...
    ...


    
    int pomiar(char uklad)
    {
    	unsigned char msb, lsb;
    	
    	ow_reset();
    	ow_write_byte(match_rom);
    	ow_write_address(uklad);	//ustawienie czujnika
    	ow_write_byte(convert); //pomiar
    	ow_reset();
    	ow_write_byte(match_rom);
    	ow_write_address(uklad);	//ustawienie czujnika
    	ow_write_byte(read_scratchpad); //oczyt
    
    	lsb = ow_read_byte();
    	msb = ow_read_byte();
    
    	 return ((msb << 8) | lsb);
    }


    Trochę to rozstrzelone jest, ale pisałem na szybkiego, jednak wszystkie niezbędne rzeczy do prawidłowej pracy są. Ja zawsze korzystam z tych funkcji. Myślę że powinny być pomocne
    Pozdrawiam
  • REKLAMA
  • #3 6567937
    marti_ql
    Poziom 10  
    Tak wyszukiwanie poprzez SEARCHROM (0xF0) i zapis do tablicy odczytanych wartości.

    Dzięki porównam z tym (dość podobne) co mam może jakiś błąd wypatrze.
    Mógłbyś jeszcze zapodać ow_reset()
  • #4 6571830
    marti_ql
    Poziom 10  
    Dziękuje za pomoc.
    Temat zamknięty,
REKLAMA