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

[MSP430F149][C] Współpraca z DS18B20

azureone 13 Cze 2008 19:58 4020 10
  • #1 5243138
    azureone
    Poziom 2  
    Witam,
    mam problem z pomiarem temperatury na MSP430f149 za pomocą układu DS18B20, próbowałem na prawde wielu rzeczy i przeglądalem te forum jednak nic nie pomogło. Moim zdaniem mam problem z czasami i nie jestem pewien czy procedura DelayUs tak na prawde czeka te 1 us, pozatym urzadzenie nie odpowiada w ogole na sygnal presence czyli nie moge go w ogole zainicjalizowac. Prosiłbym o pomoc, porady co jest zle!!! Ponizej zamiesazczam kod programu, ktory ma mi wyspisac na ekranie zawartosc pamieci ROM.

    
    
    #include<msp430x14x.h>
    #include "lcd.h"
    #include "portyLcd.h"
    
    // Port DS18B20
    #define DQ_DIR  P6DIR
    #define DQ_IN  P6IN
    #define DQ_OUT  P6OUT
    
    // Linia DQ na bicie 0
    #define DQ  BIT0  
    
    // polecenia ROM dla DS18B20
    #define ReadRom   0x33
    #define MatchRom  0x55
    #define SearchRom  0xf0
    #define AlertSearch  0xec
    #define CopyScratchpad  0x48
    #define SkipRom   0xcc
    #define ReadPower  0xb4
    
    // funckje DS18B20
    #define ConvertTemperature 0x44
    #define ReadScratchpad  0xbe
    #define WriteScratchpad  0x4e
    #define RecallE   0xb8
    
    void DelayUs(unsigned int value) {
    
      do {
        __no_operation();
        __no_operation();
        value--;
      }while(value>0);
    }
    
    //inicjalizacja DS18B20
    unsigned char DS_reset(void){
      unsigned char gotowy;
      DQ_DIR |= DQ;		//ustawiamy port na wyjscie
      DQ_OUT &= ~DQ; 	//nastawiamy linie DQ na 0
      DelayUs(480);	//czekamy 480 us
      DQ_OUT |= DQ;		//ustawiamy linie DQ na 1
      DelayUs(60);//czekamy 60 us
      DQ_DIR &= ~DQ;	//ustawiamy port na wyjscie
      gotowy = DQ_IN & DQ;	//zapisujemy stan wejscia
      DQ_DIR |= DQ;	//ustawiamy port na wyjscie
      DelayUs(480);	//czekamy 480 us
      return gotowy; 	//gotowy=0 urzadzenie jest podlaczone
    }
    
    //wyslanie 1 bitu do DS18B20
    void write_bit(unsigned char bit)
    {
      DQ_DIR |= DQ;		//port na wyjscie
      DQ_OUT &= ~DQ;	//ustawiamy linie DQ na 0
     
      if(bit==1) DQ_OUT |= DQ;	//ustawiamy linie DQ na 1 
     DelayUs(80);	//czekamy 100 us	 
      DQ_OUT |= DQ;		//ustawiamy linie DQ na 1
    }
    
    //czytanie 1 bitu z DS18B20
    unsigned char read_bit(void)
    {
        unsigned char wynik=0; 
        DQ_DIR |= DQ;		//port na wyjscie 
      	DQ_OUT &= ~DQ;		//ustawiamy linie DQ na 0
    	DelayUs(2);
    	DQ_OUT |= DQ;		//ustawiamy linie DQ na 1
        DelayUs(15);
    	DQ_DIR &= ~DQ;		//linia na wejscie
    	wynik = DQ_IN & DQ;	//czytamy stan linii DQ
        DQ_DIR |= DQ;		//port na wyjscie
    	return wynik;
    }
    
    //zapisywanie bajtu do urzadzenia
    void write_byte(unsigned char val)
    {
          unsigned char i;
          unsigned char pom;
          for (i=0; i<8; i++) // writes byte, one bit at a time
          {
          pom = val>>i; // shifts val right 'i' spaces
          pom &= 0x01; // copy that bit to temp
          write_bit(pom); // write bit in temp into
    }
          DelayUs(70);	//czekamy 70us
    }
    
    //czytanie bajtu z urzadzenia
    unsigned char read_byte(void)
    {
          unsigned char i;
          unsigned char value = 0;
          for (i=0;i<8;i++)
          {
          if(read_bit() == 1) 
    	  value|=0x01<<i; // reads byte in, one byte at a time and then
    					// shifts it left
          DelayUs(15); // czekamy 15 us
    	}
          return value;
    }
    
    int main( void )
    {
         
    WDTCTL = WDTPW + WDTHOLD;         // Stop watchdog timer to prevent time out reset
    
    InitPortsLcd();                   // inicjalizacja portów LCD
    InitLCD();                        // inicjalizacja LCD
    clearDisplay();                   // czyszczenie wyświetlacza   
    
    unsigned char wynik[8];
    int k;
     
      while(1)
          {          
    	if(DS_reset()==0)
                {    
               write_byte(ReadRom); //Read ROM
               wynik[0]=read_byte(); 
    	       wynik[1]=read_byte();
    	       wynik[2]=read_byte();
    	       wynik[3]=read_byte();
    	       wynik[4]=read_byte();
    	       wynik[5]=read_byte();
    	       wynik[6]=read_byte();
    	       wynik[7]=read_byte();
               for (k=0;k<8;k++) putc(wynik[k]); //wypisuje znak na LCD
    	    }
    	else printString("nie dziala!");
          }
    }
    
    
    



    Poprawiłem tytuł:
    https://www.elektroda.pl/rtvforum/topic1015361.html
    [c_p]
  • #2 5251765
    Konto nie istnieje
    Konto nie istnieje  
  • #3 5253635
    azureone
    Poziom 2  
    albertb napisał:

    Nie wiem, jaki masz zegar, jak jest zdefiniowane __no_operation().


    #define _NOP() __no_operation()

    Co do zegara to nigdize w programie nie zmieniam jego taktowania, zakładam ze jest 8 MHz, jezeli sie mysle to moge dodac czesc kodu

    
    BCSCTL1 |= XTS;                       // ACLK = LFXT1 = HF XTAL 8MHz
    
    int i=0;
    do 
      {
      IFG1 &= ~OFIFG;                     // Czyszczenie flgi OSCFault
      for (i=255; i>0; i--);         // odczekanie
      }
      while ((IFG1 & OFIFG) == OFIFG);    // dopóki OSCFault jest ciągle ustawiona   
    
    BCSCTL1 |= DIVA_0;                    // ACLK=8 MHz/1=8 MHz
    BCSCTL2 |= SELM0 | SELM1;             // MCLK= LFTX1 =ACLK
    
  • #4 5255262
    Konto nie istnieje
    Konto nie istnieje  
  • #5 5255275
    Freddie Chopin
    Specjalista - Mikrokontrolery
    albertb napisał:

    2 Przeanalizować skompilowany kod assemblerowy.

    assembler MSP jest chyba jednym z najprostszych ktore istnieja - analiza tego co tam kompilator naprodukowal jest bardzo prosta. pozatym wystarczy uzyc symulatora wbudowanego w kazde sensowne srodowisko, aby zmierzyc ilosc cykli poswiecanych na ta instrukcje.

    4\/3!!
  • #6 5255313
    Konto nie istnieje
    Konto nie istnieje  
  • #8 5255653
    azureone
    Poziom 2  
    Używam IAR Embedded Workbench, tylko to mamy na komputerach w laboratoriach i to w wersji KickStart (nie da sie kompilować programów większych niż 4 kB). Dzięki za pomoc, niedługo postaram sie to wszystko przetestować (deadline tego projektu jest wyznaczony na czwartek :>).

    Co do zegara to inicjalizacja jest dobra, pisałem zegar na MSP z kurantem, który działał bez zarzutów.
    Zegar oczywiście robiony był z wykorzystaniem przerwań i timera, wiec a propos tego, piszesz Albert zeby użyć timera.
    Nie do końca rozumiem jakby ta procedura opóźniająca wyglądała, przypuśćmy ze chciałbym otrzymać procedurę oczekującą od 1-2us
  • #9 5256325
    Konto nie istnieje
    Konto nie istnieje  
  • #10 5257665
    AnIHiL
    Poziom 1  
    albertb napisał:

    Programujesz timer i czekasz na ustawienie flagi przerwania.
    Przerwań nie musisz nawet włączać.


    Witam albertb czy moglbys przyklad takiego timera. Szukam w manualu do MSP430, aby sprawdzic czy flaga jest ustawiona jednak nie moge znalezc.

    Wczesniejsza wersja programu powyzej uzywala TimerA jednak operacja, ktora sie wykonywala byla:

    i przy wiekszych wartosciach 100 000 i wyzej licznik zwalnial i nie odliczal rowno czasu np. 1s.
  • #11 5258501
    Konto nie istnieje
    Konto nie istnieje  
REKLAMA