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

Magistrala 1-wire z separacją.

11 Mar 2008 13:21 1808 3
  • Poziom 11  
    Witam!
    Mam drobny problem z układem monitorującym baterie 7 ogniw Li-Ion
    Każda bateria ma swój "monitor" (jak na schemacie)
    Komunikacja 1-wire po wspólnej magistrali
    I tu sie zaczyna problem: pojedynczo nie ma problemu, odczyt jest doskonały
    Jak tylko podłacze więcej monitorów razem - tracę komunikację z niektórymi
    poniższy kod w pętli pokazuje devices = od 1 do 7, często staje na 1 i nie rozpoznaje pozostałych
    CodeVisionAVR, ATMEGA8535, 16MHz
    Code:
        
    
         delay_ms(1000);
         devices=w1_search(0xf0,rom_codes);

    Prośba o ewentualną korekcję układu i jestem otwarty na wszelkiego rodzaju pomysły
  • Poziom 11  
    Po pewnych zmianach doszedłem do momentu, kiedy 4 urządzenia pracują na jednej magistrali stabilnie. Jednak podłączenie piątego psuje sielankę: pracują stabilnie 2 a następne 2 przerywają, piąty nie odpowiada.
    Magistrala 1-wire z separacją.
    Każdy monitor osobno działa bez zarzutu, parami także.
    nasuwa mi się pytanie: czy podłączenie tylu urządzeń do jednego portu uC może powodować takie problemy? Sprawdzając na oscyloskopie nie zauważyłem różnic w kształcie przebiegów...
    Zakładam, że skoro działają osobno to problem jest po stronie uC (separacja powinna robić swoje)

    Code:
    #include <mega8535.h>
    

    // 1 Wire Bus functions
    #asm
       .equ __w1_port=0x18 ;PORTB
       .equ __w1_bit=0
    #endasm
    #include <1wire.h>

    // Alphanumeric LCD Module functions
    #asm
       .equ __lcd_port=0x15 ;PORTC
    #endasm
    #include <lcd.h> 

    #include <delay.h>
    #include <stdio.h>
    #include <ctype.h>

    //deklaracja stałych
    #define MAX_DEVICES 8   //maksymalna ilość czujników do wyszukiwania


    //deklaracja funkcji
    void chip_select(int k1);
    void odczyt_czujnika(int numer_czujnika);
    int inicjal(void);         
    void konwersja_napiecia(void);

    //deklaracja zmiennych

    unsigned char rom_codes[6][8]={ {38,38,21,161,0,0,0,237},
                                      {38,85,16,161,0,0,0,254},
                                      {38,56,28,161,0,0,0,86},
                                      {38,223,5,161,0,0,0,117},
                                      {38,28,239,64,0,0,0,18},
                                      {38,3,18,161,0,0,0,225}
                                      }; 
    int i,j,count;
    char devices;
    char input_buff[10];

    char b1,b2,b3;
    char U[MAX_DEVICES][3];

    void main(void)
    {


    lcd_init(24);


          delay_ms(1000);

          devices = 6;   
     while (1)
          {     
         
          konwersja_napiecia();
       
          for (i=0;i<devices;i++)
            {
            U[i][1] = 0;
                    if(i==0)
                    {
                    PORTB.1=1;
                    delay_us(100);
                    PORTB.1=0;   
                    };
           
            odczyt_czujnika(i);
            lcd_gotoxy(0,1);         
            lcd_putchar(i+48);
            lcd_puts(input_buff);
            delay_ms(500);
              };
     

          lcd_gotoxy(0,0);       
          for (i=0;i<devices;i++)
          {
          b3 = U[i][2] / 100;
          lcd_putchar(b3+48);
          b2 = U[i][2] - b3 * 100;
          b2 = b2 / 10;
          lcd_putchar(b2+48);
          b1 = U[i][2] - b3 * 100 - b2*10;
          lcd_putchar(b1+48);
          lcd_putsf(":");
       
          };                 
       
          };
           
    }


    //polecenie odczytu napięcia
     
      void konwersja_napiecia()
      {
     
      if(inicjal())
              {   
              w1_write(0xCC);  //komenda odczytu z określonego urządzenia
              w1_write(0xB4);  //konwersja napięcia
              inicjal();
             
              delay_ms(25);   // opóźnienie w [ms], minimum 10ms dla DS2438
             
              inicjal();
              w1_write(0xCC);  //komenda odczytu z określonego urządzenia
              w1_write(0xB8);  //kopiowanie rejestrów do bufora wyjściowego
              w1_write(0x00); 
     
           
              }
             else
              {
     
              };
                 
      }
     
     
     
     //odczyt napięcia
      void odczyt_czujnika(int numer_czujnika)
      {
       
       
      chip_select(numer_czujnika);       
         
       w1_write(0xBE);  //wybór strony
       w1_write(0x00);  //do odczytu
       
       for (j=0;j<10;j++)
        {
        input_buff[j] = w1_read();
        };

       U[numer_czujnika][2]=input_buff[3];  //LSB
       U[numer_czujnika][1]=input_buff[4];  //MSB   
        inicjal();
       
       }
     

    // inicjalizacja magistrali
    int inicjal(void) 
      {
             
      if (w1_init())
            {
            return(1);
            }
      else 
            {   
            lcd_putsf("Blad!!!!");
            delay_ms(2000);
            return(0);
            };
       
      }
     
                             

    //funkcja wybierająca dany czujnik do komunikacji
    void chip_select(int k1)
    {
     if(inicjal())
     {   
      w1_write(0x55);  //komenda odczytu z określonego urządzenia
           
            for (j=0;j<8;j++)
                    {
                    w1_write(rom_codes[k1][j]);
                    };   
                       
      }
      else
      {
     
      };
    }
  • Poziom 18  
    Proponuje zmienić rezystor 4k7 na 3k3. U mnie z odczytem kilku czujników temp. pomogło. Spróbuj też odpalić je z pominięciem całej separacji (jeśli masz możliwość to odetnij ją całkowicie).
  • Poziom 11  
    Separacja musi być, wpinam się w drabinkę aku Li-Ion.
    Ale dzięki, spróbuje ze zmianą rezystora.