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

DS18B20 + AT89C2051 po raz n, ale proszę pomóźcie

sisco85 26 Maj 2007 00:22 1653 1
REKLAMA
  • #1 3921966
    sisco85
    Poziom 2  
    Posty: 2
    Witam.
    Jestem nowy na forum i nie mam zbyt duzego doświadczenia w programowaniu mikrokontrorów wiec z gory przepraszam za błedy.

    Otóż mam do napisania projekt w którym mam DS18B20i za nic w swiecie nie moge dokonać odczytu z czujnika. Analizowałem datasheeta dosc dlugo i nie widze błedu.Przegladałem również tematy na forum, próbowałem różnych rzeczy i nic. Urządzenie teoretycznie zgłasza sie po resecie, ale na tym koniec. Programuje w C gdyz assembler nie jest moją mocną stroną(C zresztą tez :D ). Na forum wyczytałem ze ważne są czasy i poświeciłem im duzo uwagi,ale wegług mnie obliczam je dobrze. Ponizej zamieszczam kawałek kodu wraz z tlumaczeniem kompilatora na asm. Dodam ze uzywam kwarcu 11.059Mhz i porcka AT89c2051. No więc licząc opożninie pisze takie cos:

    wait=(unsigned char)((XTAL/12e6)*30/2);//30us
    W1_IO=1;
    while(--wait);
    co odpowiada nastepującym poleceniom asm:
    MOV R7,#0Dh
    SETB W1_IO
    DJNZ R7,025Ah

    Tak więc ponieważ mam taktowanie 11,059MHz, a wewnetrze procek dzieli to przez 12 to wynika z tego ze jeden cykl maszynowy trwa mniej wiecej 1,08us tak wiec liczymy: na poczatku załadowanie do R7 0x0Dh czyli 13 dec. Z tego co sie doczytałem to DJNZ zajmuje 2 cykle maszynowe.Wiec mamy 13x2=26 cykli + 1(MOV) + 1(SETB) czyli łącznie 28cykli*1,08us=30,24us czyli tyle ile zakładałem. Debbuger w RIDE mówi mi to samo więc to raczej nie kwestia czasów.

    Układ sprawdzany na 3 czujnikach na kazdym to samo..same jedynki w odbiorze,czyli nie zyje, a nie mozliwe zeby 3 uklady byly walniete. Czujnik podpiety pod P1^0, z podciagniem przez 4,7kOM do +5V.Wszystko wydaje sie byc dobrze,ale nie działa. Naprawde nie wiem co zrobic.Prosze o pomoc


    #pragma SMALL
    #include <reg51.h>


    
    #define CONVERT_T		0x44		// Komendy DS1820
    #define READ1W			0xBE
    #define SKIP_ROM 		0xCC
    #define PORT P1
    #define XTAL 11059200
    //ZMIENNE GLOBALNE
    unsigned char Tmax=0;
    unsigned char Tmin=0;
    unsigned char TmaxHalf=0;
    unsigned char TminHalf=0;
    unsigned char TmaxMinus=0;
    unsigned char TminMinus=0;	
    unsigned char Hour=0,Minute=0,Second=0,InterruptCounter=0;
    unsigned char AlarmHour=0,AlarmMinute=0;
    unsigned char Mode=0;
    
    
    //FUNCKJE OBSUGI WYSWIETLACZA
    sbit LcdEnable = 		P1^3;
    sbit LcdRead = 		P1^1;
    sbit LcdRS = 			P1^2;
    sbit  W1_IO = 			P1^0;
    sbit Key = 				P3^0;
    sbit Buzer = 			P3^1;
    
    
    //FUNKCJE OBSLUGI 1-WIRE
    	//definicja podlaczenia linii portu 1W
    //wyslanie polecenia "1W Reset"
    bit W1_reset(void)
    {
    	unsigned char wait;
    	bit present;
    	
    	wait=(unsigned char)((XTAL/12e6)*490/3);//obliczenie opoznienia 491us 
    	do
    	{
    	 W1_IO=0;
    	}	 	
    	while(--wait);//1 wait to 2us
    			
    	wait=(unsigned char)((XTAL/12e6)*30/2);//30us
    	W1_IO=1;
    	while(--wait);
    	
    	present=W1_IO;
    	wait=(unsigned char)((XTAL/12e6)*70/2);//70us
    	while(--wait);
    	present=W1_IO;
    	return !present;
    	
    }
    
    //przeslanie lub odczyt bitu przez linie W1
    void W1_bit_write(bit b)//zapis bitru z master2slave
    {
    	unsigned char wait;
    	wait=(unsigned char)((XTAL/12e6)*15/2);//15 us
    	W1_IO=0;
    	while(--wait);
    	W1_IO=b;
    	wait=(unsigned char)((XTAL/12e6)*47/2);//47 us
    	while(--wait);
    	W1_IO=1;
    	wait=(unsigned char)((XTAL/12e6)*2/2);//2 us
    	while(--wait);
    }
    
    bit W1_bit_read()
    {
    	unsigned char wait;
    	bit b;
    	W1_IO=0;
    	wait=(unsigned char)((XTAL/12e6)*4/2);//4us
    	while(--wait);
    	W1_IO=1;
    	wait=(unsigned char)((XTAL/12e6)*8/4);//10us	
    	do
    	{
    	 b=W1_IO;
    	}
    	while(--wait);
    	wait=(unsigned char)((XTAL/12e6)*55/2);//47us
    	while(--wait);
    	return b;
    }
    
    void W1_byte_write(unsigned char b)
    {
    	unsigned char mask=0x01;
    	unsigned char counter=8;
    	do
    	{
    	 if ((b & mask)) 
    	 	{W1_bit_write(1);} //if ((byte & mask)!=0) W1_bite_write(1)
    	else	 
    	   {W1_bit_write(0);} //if ((byte & mask)=0) W1_bite_write(0)
    	   mask=mask<<1;
    	}
    	while(counter--); 
    }
    
    unsigned char W1_byte_read()
    {
     unsigned char byte=0x00;
     unsigned char mask=0x01;
     unsigned char counter;
     
     
     for (counter=0;counter<8;counter++)
      {
    	if (W1_bit_read()) byte=byte|mask;
    	mask=mask<<1;    
      } 
     return byte;
    }
    //FUNCKJE OBSLUGI POMIARU
    
    unsigned char ConverT(unsigned char LSByte,unsigned char MSByte)
    {
     unsigned char Temp=0x07;
    
     Temp=Temp & MSByte;//wyłuskanie 3 najmniej znaczących bitów z MSByte
     Temp=Temp<<4;//Przesuniesie o 4 w lewo,aby zrobic miejsce dla gornej polowki LSByte
     Temp=Temp & 0xF0;//ustawienie dolnej polownki Temp na '0'
     LSByte=LSByte & 0xF0;//wylusaknie gornej polowki LSByte
     LSByte=LSByte>>4;//Przsuniecie o 4 w lewo
     Temp=Temp | LSByte;//ustawienie dolnej połowki Temp na wlasciwa wartosc
     
     
     //Temperature=LSByte+(MSByte*256);
     //Temperature=Temperature/16; 
     
     return Temp;
     
    }
    
    void WriteTempOnLcd(unsigned char Temp,bit Minus,bit HalfDegree,char select)
    {
    unsigned char NumOfTens=0x00;
    
    while (Temp>9)
      {
       Temp=Temp-10;
       NumOfTens++;  
      }
     
     //LcdClrScr();
     switch(select)
     {
      case 0:
       if (Minus) WriteTextXY(0,1,"-",0);
       else (WriteTextXY(0,1,"+",0));
       break;
      case 1:
       if (Minus) WriteTextXY(0,2,"Max:-",0);
       else (WriteTextXY(0,2,"Max:+",0));
       break;
      case 2:
       if (Minus) WriteTextXY(8,2,"Min:-",0);
       else (WriteTextXY(8,2,"Min:+",0));
       break; 
     }
     LcdRS=1;
     WriteByte2Lcd(NumOfTens+48);//wypisanie cyfry dziesiatek
     LcdRS=1;
     WriteByte2Lcd(Temp+48);//wypisanie cyfry jednostek
     LcdRS=1;
     WriteByte2Lcd(44);//wypisanie przecinka
     if (HalfDegree) 
      {
    	LcdRS=1;
    	WriteByte2Lcd(53);//wypisanie '5'  
      }
     else
      {
      	LcdRS=1;
    	WriteByte2Lcd(48);//wypisanie '0'
      }; 
     LcdRS=1;
     WriteByte2Lcd(223);//wypisanie znaku stopnia
     LcdRS=1;
     WriteByte2Lcd(67);//wypisanie 'C' 	
    
    }
    
    
    void Temp2LCD_MAXMIN(unsigned char LSByte,unsigned char MSByte)
    {
     
     bit Minus,HalfDegree;
     unsigned char Temp=0;
     
     if ((LSByte & 0x08)!=0) HalfDegree=1;
     else HalfDegree=0;
     
     if ((MSByte & 0xF8)==0) Minus=0;
     else {Minus=1;MSByte=~MSByte;LSByte=~LSByte;}
     
     Temp=ConverT(LSByte,MSByte);
    
     if (TmaxMinus)
      {
       if (Minus)
        {
         if (Temp<=Tmax)
          {
             Tmax=Temp;
             TmaxMinus=1;
             if (TmaxHalf) TmaxHalf=HalfDegree;
              
          }
        }
       else
        {
         Tmax=Temp;
         TmaxMinus=0;
         TmaxHalf=HalfDegree;
        } 
      }
     else
      {
       if (Temp>=Tmax)
        {
           Tmax=Temp;
           TmaxMinus=0;
           if (HalfDegree) TmaxHalf=1;
        }
      } 
    
     if(TminMinus)
     {
      if (Minus)
       {
        if (Temp>=Tmin)
         {
          Tmin=Temp;
          TminMinus=1;
          if (HalfDegree) TminHalf=1;
         }
       }
     }
     else
     {
      if (Minus)
      {
       Tmin=Temp;
       TminMinus=1;
       TminHalf=HalfDegree;
      }
      else
       {
        if (!TminMinus)
         {
          if (Temp<=Tmin)
           {
            Tmin=Temp;
            TminMinus=0;//nawet nie trza tego modyfikowac
            if (HalfDegree==0) TminHalf=0;
           }
         }
       }
     }
    
    WriteTempOnLcd(Temp,Minus,HalfDegree,0);
    WriteTempOnLcd(Tmax,TmaxMinus,TmaxHalf,1);
    WriteTempOnLcd(Tmin,TminMinus,TminHalf,2);
    }
    
    
    
    
    void main (void)
    {
    
    	unsigned char Counter=0;
    	unsigned char ScratchPad[9];
    	bit noerror=0;
    
    	
    	TMOD=0x01;//ustawienie TIMER 0 w tryb 16-bit
    	TR0=1;//uruchomienie TIMER 0
    	EA=1;//zezwolenie na przerwania
    	ET0=1;//zezwolenie na przerwania z Timera
    	EX0=1;//zezwolenie ma przerwania z INT0
    	IT0=1;//wywolanie przerwania INT0 zboczem opadającym
    	
    	LcdInitialize();    				// inicjalizacja wyswietlacza
    	LcdClrScr();
       
       
    	while(1)
    	{
    
    			LcdClrScr();
    			WriteTextXY(0,1,"Witamy",100);
    			Delay(2000);
    			LcdClrScr();
    			WriteTextXY(0,1,"Initiation",100);
    			WriteTextXY(0,2,"1-WIRE",100);
    			Delay(2000);
    			noerror=W1_reset();
    			if (noerror) 
    			 {
    			  	LcdClrScr();
    			  	WriteTextXY(0,1,"Initiation OK",100);
    
    			 }
    			else
    			 {
    			  LcdClrScr();
    			  WriteTextXY(0,1,"InitiationERROR",100);			  
    			 };
    			LcdClrScr();
    	
    			while(noerror)
    
    			 {
    				 W1_reset();
    				 W1_byte_write(SKIP_ROM);
    				 W1_byte_write(CONVERT_T);
    				 
    				 Delay(1000);
    				 W1_reset();
    				 W1_byte_write(SKIP_ROM);
    				 W1_byte_write(READ1W);
    				 for (Counter=0;Counter<9;Counter++) ScratchPad[Counter]=W1_byte_read();
    				 Temp2LCD_MAXMIN(ScratchPad[0],ScratchPad[1]);
    			 }
    				
    			 
    
    					
    	}		  
    			
    }


    Aha po lekturze forum wiem ze duzo prosciej mozna napisac funcje konwerujace otrzymane dane na liczby do wyslania na LCD(wlasnie projekt zawiera LCD,który dziala i fukcji jego obslugi nie zamieszczalem) no ale ogolnie nie o to chodzi.Jak DS przemówi do mnie to zmienie to.

    Z góry wielkie dzieki za pomoc.
  • REKLAMA
  • #2 3972058
    sisco85
    Poziom 2  
    Posty: 2
    Ogolnie to dzieki za zaiteresowanie...:cry:....ale jakos sobie poradzialem...okazalo sie ze po rozdzieleniu funcji zapisu jedynki i zera do DS18B20,oraz rodzaju zmiennej zwracanej przez funkcie odczytujaca bit z DS18B20 (zmienna typu bit zamienilem na char) ruszylo....
REKLAMA