Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[MSP430] Dokładna funkcja "czekaj"

Galkio 10 Sty 2012 18:32 1862 6
  • #1 10 Sty 2012 18:32
    Galkio
    Poziom 7  

    Witam,
    Korzystam z MSP430 i aktualnie potrzebuję napisać kawałek kodu, który umożliwi mi pobieranie temperatury za pomocą czujnika DS18B20 (wykorzystanie zasilania pasożytniczego).

    Przykładowych kodów do obsługi jest pełno, a w moim przypadku problem dotyczy raczej funkcji "delay". Opiszę Wam co zrobiłem i proszę o ewentualną korektę, bo raczej niezbędna skoro nie działa :) Opiszę tylko funkcję reset bo bez niej dalej nie pójdzie, a jak reset pójdzie to reszta też pójdzie na pewno. Czujnik podłączony jest do P1.7.

    A więc na początku definiuje stan niski i wysoki dla linii danych:

    Code:
    #define DQ1 P1OUT |= BIT7
    
    #define DQ0 P1OUT &= ~BIT7


    Funkcja resetująca:

    Code:
    unsigned char RESET_PULSE(void)
    
    {
        unsigned char presence;
       
     
        DQ0;
        Delay_us(500);
        DQ1;
        Delay_us(55);
        P1DIR &=~ BIT7;
        _NOP();
        if(P1IN & BIT7)     
        {
            presence = 1;
            P1DIR |= BIT7;
        }
        else
        {
            presence = 0;     
            P1DIR |= BIT7;
            DQ1;
        }
       
        Delay_us(400);
       
        return presence;
    }


    Funkcja napisana zgodnie z tym: http://img580.imageshack.us/img580/6069/resetp.png

    Moja funkcja delay wygląda tak:

    Code:
    void delay_us(unsigned int delay)
    
    {
        while (delay--)
        {
            __delay_cycles(8);
        }
    }


    8 bo wybieram zegar 8MHZ czyli 8*10^6 hz i zeby uzyskać czas w us dziele przez 10^6.

    Jeszcze to:
    Code:
        P1DIR |= BIT7;
    
        P1OUT |= BIT7;


    Funkcja reset zwraca błąd, bo nie działa poprawnie - brak sygnału. Gdzie popełniam błąd ?

    Datasheet DS18B20: http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf

    0 6
  • #2 10 Sty 2012 19:50
    lehastar
    Poziom 14  

    A co z kompilatorem? Napisałem do IAR. Jest wbudowany w Delay.

    Code:


    #define  XTAL               7372800ul

    u8_t Onewire_Reset(u8_t reader)
    {
      volatile u16_t i;
      u8_t err;

      err = 0;

    //******   
      ONEWIRE_DDR |= (1<<(TP0 + reader));
      __delay_cycles((unsigned)(0.00049*XTAL));
      ONEWIRE_DDR &= ~(1<<(TP0 + reader));   

    //******
      i = 1082*2;
      if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0)
      {
          while(--i)
          {
              if((ONEWIRE_PIN & (1<<(TP0 + reader))) != 0) break;
          }

          if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0) return err;
      }

    //*******      
      i = 212*2;
      while(--i)
      {
        if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0) err = 1;
      }

      __delay_cycles((unsigned)(0.000020*XTAL));

      return err;
    }


    Próbować void delay_us(unsigned int delay) -> void delay_us(volatile unsigned int delay)

    0
  • #3 10 Sty 2012 20:27
    63404
    Użytkownik usunął konto  
  • #4 10 Sty 2012 22:47
    94075
    Użytkownik usunął konto  
  • #5 10 Sty 2012 23:03
    63404
    Użytkownik usunął konto  
  • #6 12 Sty 2012 11:02
    Galkio
    Poziom 7  

    lehastar napisał:
    A co z kompilatorem? Napisałem do IAR. Jest wbudowany w Delay.

    Code:


    #define  XTAL               7372800ul

    u8_t Onewire_Reset(u8_t reader)
    {
      volatile u16_t i;
      u8_t err;

      err = 0;

    //******   
      ONEWIRE_DDR |= (1<<(TP0 + reader));
      __delay_cycles((unsigned)(0.00049*XTAL));
      ONEWIRE_DDR &= ~(1<<(TP0 + reader));   

    //******
      i = 1082*2;
      if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0)
      {
          while(--i)
          {
              if((ONEWIRE_PIN & (1<<(TP0 + reader))) != 0) break;
          }

          if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0) return err;
      }

    //*******      
      i = 212*2;
      while(--i)
      {
        if((ONEWIRE_PIN & (1<<(TP0 + reader))) == 0) err = 1;
      }

      __delay_cycles((unsigned)(0.000020*XTAL));

      return err;
    }


    Próbować void delay_us(unsigned int delay) -> void delay_us(volatile unsigned int delay)


    Dzięki za odpowiedź, ale nie do końca rozumiem Twój kod.

    Dlaczego korzystasz z volatile dla zmiennej (wiem do czego służy ale po co tutaj?) ?

    Ja także korzystam z IAR'a ale Twój kod jest dla mnie nie jasny, bo chociażby skąd doszedłeś do takiego wzoru wewnątrz argumentu funkcji:

    Code:
      __delay_cycles((unsigned)(0.00049*XTAL)); 


    Czy mógłbyś objaśnić działanie tego kodu krótkimi komentarzami ?

    Dzięki za pomoc!

    0
  • #7 12 Sty 2012 12:28
    lehastar
    Poziom 14  

    Code:

    __delay_cycles((unsigned)(0.00049*XTAL));
    __delay_cycles((unsigned)(0.000020*XTAL));
    __delay_cycles((unsigned)(0.000005*XTAL));


    To opóźnienie jest 490 mikrosekund. Opóźnienie do 20 mikrosekund. Opóźnienie do 5 mikrosekund. Kod używam do czytania DS1990A. I przyprowadził go do opóźnienia tworzenia przykład IAR wbudowanych. (Unsigned) tak umieścić w niektórych wersjach IAR wydane bez ostrzeżenia. Użyłem volatile, tak, że kompilator nie usunąć zmienną.

    XTAL - częstotliwości rezonatora kwarcowego = 7372800Hz

    #define ONEWIRE_DDR P3DIR
    #define ONEWIRE_PORT P3OUT
    #define ONEWIRE_PIN P3IN
    #define TP0 6


    Czytania i wysyłania bitów

    Code:

    u8_t Onewire_Bit_IO(u8_t bit, u8_t reader)
    {
      if(bit != 0)
      {
        __disable_interrupt();

        ONEWIRE_DDR |= (1<<(TP0 + reader));

      #ifdef PULLUP_5K1
        __delay_cycles((unsigned)(0.000002*XTAL));
      #else
        __delay_cycles((unsigned)(0.000007*XTAL));
      #endif
        ONEWIRE_DDR &= ~(1<<(TP0 + reader));

      #ifdef PULLUP_5K1
        __delay_cycles((unsigned)(0.000011*XTAL));
      #else
        __delay_cycles((unsigned)(0.000006*XTAL));
      #endif
      }
        else
        {
          __disable_interrupt();
          ONEWIRE_DDR |= (1<<(TP0 + reader));
      #ifdef PULLUP_5K1
          __delay_cycles((unsigned)(0.000013*XTAL));
      #else
          __delay_cycles((unsigned)(0.000015*XTAL));
      #endif
        }
       
      bit = ONEWIRE_PIN & (1<<(TP0 + reader));
       
      __delay_cycles((unsigned)(0.000060*XTAL));

      ONEWIRE_DDR &= ~(1<<(TP0 + reader));

      __delay_cycles((unsigned)(0.000020*XTAL));

      __enable_interrupt();   

      return bit;
    }

    0