niedziela, 20 marca 2011

DIY: Wyświetlacz LED na 1-wire (by Dejmos)


Autor: Dejmos
Redakcja: Dondu

Witam wszystkich!

Jest to mój pierwszy artykuł i wpis na tym blogu. Mam nadzieję, że nie ostatni. :-)

Chciałbym tu zaprezentować swoją konstrukcję sześciocyfrowego wyświetlacza LED z interfejsem 1-wire. O tym, że 1-wire jest chronione patentem dowiedziałem się już po zlutowaniu płytki, w trakcie pisania programu. Dlatego też protokół komunikacyjny jest zmieniony (uproszczony), co wcale nie ogranicza jego funkcjonalności w tym projekcie.

Udostępniam dla ogółu użytkowników pełną dokumentację projektu wraz z kodem źródłowym, w którym znajdują się funkcje z komentarzami, na podstawie których można napisać pełnowartościową aplikację do obsługi 1-wire. Wszystko znajdziesz na końcu artykułu.


Wyświetlacz LED 1wire.

Założenia

Zacznijmy od początku. Stwierdziłem, że czasami podczas projektowania jakiegoś urządzenia na mikrokontroler zaczyna brakować nam pinów lub urządzenie wykonuje krytyczne zadania, które utrudnią obsługę wyświetlacza LED. Można w takim przypadku zastosować większy procesor, szybszy zegar itd. Można też zostawić wyświetlanie dla zewnętrznego urządzenia, a dane mu przesyłać tylko w chwili kiedy jest to konieczne.

Ważnym założeniem była również poprawność komunikacji wyświetlacza z urządzeniem (masterem), w którym będzie on pracował. Wyobraźmy sobie, że przyrząd będzie rejestrował pojedyncze zdarzenia, które ciężko powtórzyć, lub będzie wykorzystywany przy badaniach, które najprościej rzecz ujmując są drogie. Nie może być takiej sytuacji , że przyrząd zarejestruje zdarzenie poprawnie, a na wyświetlaczu pojawią się „krzaki”.

I z tych założeń wyszedłem. Tak powstał 6-cyfrowy wyświetlacz z interfejsem 1-wire na procesorze ATtiny2313. Poniżej kilka zdjęć.







Początkowe problemy

Początkowo projekt zakładał 7 wyświetlaczy, a procesor miał pracować na wewnętrznym zegarze. Jednak komunikacja mi się ciągle rozjeżdżała. Nie pomagało konfigurowanie bitu kalibracyjnego. Układ zachowywał się tak, że jednego dnia po kilku godzinach pracy wszystko wyglądało obiecująco, transmisja prawie bezbłędna. Następnego dnia po włączeniu układu cały czas występował błąd crc.

Dlatego zastosowałem rezonator zewnętrzny i stwierdziłem, że 6 wyświetlaczy spokojnie wystarczy do większości zastosowań.

Schemat i PCB

Płytka PCB została zaprojektowana tak, aby można ją było wykonać w warunkach domowych. Podczas projektowania płytki schemat był ciągle modyfikowany przeze mnie tak, aby jak najbardziej uprościć wzór ścieżek.

I tutaj rada dla początkujących projektantów układów mikroprocesorowych. Nigdy nie trzymajcie się sztywno wcześniej zaprojektowanego schematu. Prawie zawsze można pomiędzy dwoma pinami przełożyć linie, a projekt płytki dzięki temu może się diametralnie uprościć, zaś program napisać tak aby zadbał o poprawne działanie układu. Co innego gdy wykorzystujmy alternatywne funkcje portów. W takich przypadkach nie możemy tak postąpić.


Schemat multipleksowanego wyświetlacza LED.
Schemat multipleksowanego wyświetlacza LED.

Płytka:





Płytka strona TOP - mirror.


Płytka strona BOTTOM - mirror.

Na końcu artykułu zamieściłem zbiorczy plik, w którym znajdziesz między innymi płytkę PCB w formie plików PDF.


Zasada działania

Komunikacja między masterem, a wyświetlaczem 6xLED wygląda następująco:
  • Master wykonuje reset linii, który trwa 480us.
  • Wyświetlacz 6xLED po tym czasie generuje impuls obecności również o długości 480us.
  • Master wysyła 10 bajtów z czego 6 pierwszych to cyfry do wyświetlenia.
  • 7 i 8 bajt - rezerwa na przyszłość.
  • 9 bajt - adres wyświetlacza.
  • 10 bajt - crc.

Wyświetlacz 6xLED po odebraniu całej paczki danych oblicza swoje crc (sumę kontrolną) i porównuje z odebranym (ostatnim bajtem paczki). Jeżeli crc się zgadza sprawdza adres (przedostatni bajt paczki danych) jeżeli to jego adres - wyświetla na wyświetlaczu 6 pierwszych bajtów, które muszą odpowiadać tablicy znaków zadeklarowanej w programie. Jeżeli crc jest błędne wyświetlacz zwiera linię na 480us co master odbiera jako prośbę o ponowne wysłanie danych.

W przypadku kilka wyświetlaczy 6xLED podłączonych do jednej linii, procedura wygląda następująco (przynajmniej jest takie założenie, bo nie testowałem tego na większej ilości wyświetlaczy) Wszystkie odbierają wysyłane przez mastera dane. Wszystkie obliczają crc. Dana zostaje wyświetlona tylko przez wyświetlacz o adresie z 9 bajtu. Jednak wystarczy, że tylko jednemu (niekoniecznie temu do którego jest adresowana dana) nie zgodzi się crc wtedy linia jest zwierana przez niego na 480us, a master jest zmuszony do ponownego wysłania danych, niezależnie od tego czy błąd zgłosił wyświetlacz, do którego była adresowana paczka danych, czy też inny.

Multipleksowaniem wyświetlaczy steruje timer0, który jest ustawiony w tryb CTC z częstotliwością 180Hz, czyli każdy wyświetlacz zapala się na około 5,5ms 30 razy na sekundę. Odbiór danych zrealizowany jest na przerwaniu z INT0, które po wykryciu zbocza opadającego (impulsu reset generowanego przez master) jest blokowane na czas odbioru danych. W programie wykorzystana jest instrukcja ISR_NOBLOCK, dzięki której wyeliminowane jest miganie wyświetlacza podczas odbioru danych.

Czas trwania jednego bitu wynosi 120us a cała ramka wraz z impulsem reset i ewentualnym błędem crc trwa 11,04ms z czego wynika, że w tym czasie występuje dwu lub trzykrotne przerwanie od timera0 i wywołanie funkcji obsługującej wyświetlanie. Czas wykonywania funkcji obsługującej wyświetlacze to około 6,5us co przy trzykrotnym wywołaniu podczas odbioru danych przesuwa moment próbkowania linii 1-wire o jakieś 20us.

Dlatego przyjąłem tak długi czas trwania jednego bitu (120us), aby transmisja się nie rozjechała. Układ testowy, który co 10 ms wysyłał wartość licznika zwiększanego za każdym razem o 1 i zrobił to milion razy, przy takich czasach opóźnień nie zarejestrował ani jednego błędu transmisji. Dlatego aby upewnić się że wszystko jest poprawne napisałem też program, który co jakiś czas wysyłał błędne crc i wszystko było tak jak powinno. Ilość błędów transmisji zgadzała się z ilością błędnych crc.

Schemat układu do testów (master):


Układ do testów (master).

Koszty

Koszty projektu to około 35 zł bez wytrawiacza, pasty, cyny, itp.

Może w przyszłości

Można do programu dodać kilka funkcji, które będą np. migały wyświetlanymi danymi, powodowały efekt wjazdu z prawej lub lewej strony itp. wykorzystując do tego 8 bajt paczki danych, w którym master mógłby określał co wyświetlacz ma robić. Ale to już pozostawiam w kwestii otwartej w zależności od wykorzystania wyświetlacza.

Kody:
//*********************************************************************
//***                                                               ***
//***                 6-cyfrowy wyświetlacz LED 1wire               ***
//***                       by Dejmos                               ***
//***                   uC - ATtiny2313  F_CPU - 8MHz               ***  
//***                 FUSES - low: 0xFF;    high: 0xFF              ***
//***   Eclipse SDK       Version: 3.7.1                            ***
//***   AVR Eclipse Plugin    Version: 2.4.0.201203041437           ***
//***                                                               ***
//*********************************************************************

#include <avr\io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <util/crc16.h>

#define LED_1 6                    //definicja
#define LED_2 5                    //makr
#define LED_3 4                    //dla
#define LED_4 3                    //wyświetlaczy
#define LED_5 1                    //LED
#define LED_6 0                    //--
#define ADRESS 0x01                //adres wyswietlacza
#define INPUT 0x04                 //nr pinu 1wire
#define PIN_1WIRE PIND             //wejście 1wire na porcie D
#define CLEAR_1WIRE DDRD |= _BV(2) //wyjście - ściągnięcie lini 1wire do 0
#define SET_1WIRE DDRD &= ~_BV(2)  //wejście (zwolnienie lini 1wire)
//pin w stanie wysokiej impedancji
//linia 1wire podciągana przez rezystor
uint8_t dane[6];                   //tablica danych do wyświetlenia
uint8_t temp[10];                  //tablica odebranych danych

uint8_t z=0;                       //deklaracja zmiennej globalnej z

uint8_t flaga=0;

uint8_t Digits[] = {0xed,0x44,0x79,0x75,0xd4,0xb5,0xbd,0x64,0xfd,0xf5,0xef,0x46,0x7b,0x77,0xd6,0xb7,0xbf,0x66,0xff,0xf7,0x00};
//w. wyswietlana:     0   1    2  3    4    5    6  7    8    9    0.  1.   2.   3. 4.   5.   6.   7. 8.   9.  wygas
//kod wysw:           0   1    2  3  4    5    6  7  8    9   10    11   12   13   14   15   16   17   18   19    20


//----------------------------------------------------------------

void DisplayDigit(uint8_t digit)    //wyświetlanie cyfr na wyświetlaczu
{
  PORTB = Digits[digit]; //ustaw wyjścia poru B w zależności od tablicy Digits
}

//----------------------------------------------------------------

void Display(uint8_t *str)      //obsługa wyświetlaczy
{
  uint8_t i=0;                  //deklaracja zmiennej i
  PORTD = 0x00;                 //wygaś wszystkie
  PORTB = 0x00;                 //wyświetlacze
  while(str[i]==0) {            //funkcja wygaszająca
    //zera wiodące
    str[i]=20;                  //w
    i++;                        //danej
    if(i==5) {
      break;                    //do wyswietlenia
    }
  }
  switch(z) {                   //funkcja multipleksująca wyswietlacze
  case 0:                       //dla z = 0
    if(str[z]!=20) {
      PORTD |= _BV(LED_1);      //zapal pierwszy wyświetlacz jeżeli nie jest
                            //zerem wiodącym
    }
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z++;                        //zwiększ z
    break;                      //przerwij

  case 1:                       //dla z = 1
    if(str[z]!=20) {
      PORTD |= _BV(LED_2);      //zapal drugi wyświetlacz jeżeli
                             //nie jest zerem wiodącym
    }
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z++;                        //zwiększ z
    break;                      //przerwij

  case 2:                       //dla z = 2
    if(str[z]!=20) {
      PORTD |= _BV(LED_3);      //zapal trzeci wyświetlacz jeżeli 
                             //nie jest zerem wiodącym
    }
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z++;                         //zwiększ z
    break;                      //przerwij

  case 3:                       //dla z = 3
    if(str[z]!=20) {
      PORTD |= _BV(LED_4);      //zapal czwarty wyświetlacz jeżeli
                            //nie jest zerem wiodącym
    }
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z++;                        //zwiększ z
    break;                      //przerwij

  case 4:                       //dla z = 4
    if(str[z]!=20) {
      PORTD |= _BV(LED_5);      //zapal piąty wyświetlacz jeżeli
                             //nie jest zerem wiodącym
    }
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z++;                        //zwiększ z
    break;                      //przerwij

  case 5:                       //dla z = 5
    PORTD |= _BV(LED_6);        //zapal szósty wyświetlacz
    DisplayDigit(str[z]);       //wywołaj funkcję wyświetlającą cyfrę
    z=0;                        //z = 0
    break;                      //przerwij
  }
}

//----------------------------------------------------------------

unsigned char ReadBit()         //funkcja odbierająca bit
{
  uint8_t bit=0;                //deklaracja zmiennej bit
  _delay_us(35);                //opóźnienie
  if(PIN_1WIRE&INPUT) {
    bit=1;                      //jeżeli jeden na linii 1-wire
  } else {
    bit=0;                      //jeżeli zero
  }
  _delay_us(85);                //opóźnienie - pozostały czas trwania bitu
  return bit;
}

//----------------------------------------------------------------

unsigned char ReceiveByte()     //funkcja odbierająca 1 bajt
{
  uint8_t SetData=0;            //początkowa wartoć odbieranego bajtu
  uint8_t i;                    //deklaracja zmiennej i
  for(i=0; i<8; i++) {          //wykonaj 8 razy (odbieraj bit po bicie)
    if(ReadBit()) {
      SetData |= 0x01<<i;       //jeżeli ReadBit==1 ustaw 1
    }
  }                             //w miejsce i-tego bitu w odbieranym bajcie
  return SetData;               //zwróć odebrany bajt
}

//----------------------------------------------------------------

void ReceiveData()              //funkcja odpowiedzialna za odbiór danych
{
  uint8_t i, crc8=0;            //deklaracja zmiennych: i, crc8
  _delay_us(480);               //odczekaj aż minie impuls zerujący
  CLEAR_1WIRE;                  //ściągnięcie lini 1wire do 0
  _delay_us(480);               //przytrzymaj przez 480us (impuls obecności)
  SET_1WIRE;                    //zwolnienie lini 1wire
  for(i=0; i<10; i++) {        //odbierz 10 bajtów
    temp[i] = ReceiveByte();    //odbierz bajt
  }
  for(i=0; i<9; i++) {         //wykonaj 9 razy
    crc8 = _crc_ibutton_update(crc8, temp[i]); //oblicz crc z pierwszych
                                               //9 bajtow
  }
  if(temp[9]==crc8) {           //porównaj crc odebrane z obliczonym
    //jeżeli crc zgodne
    if(temp[8]==ADRESS) {       //sprawdz adres urządzenia
      //jeżeli adres zgodny
      for(i=0; i<6; i++) {
        dane[i] = temp[i];      //przepisz 6 bajtów do wyswietlenia
      }
    }
    _delay_us(480);             //opóźnenie 480us
  } else {                      //jeżeli crc niezgodne
    CLEAR_1WIRE;                //ściągnij linię 1wire do 0
    _delay_us(480);             //i przytrzymaj przez 480us
    SET_1WIRE;                  //zwolnij linię
  }
}

//----------------------------------------------------------------

ISR(INT0_vect, ISR_NOBLOCK)     //obsługa przerwania z INT0 bez
                                // blokowania innych przerwań
{
  GIMSK &= ~_BV(INT0);          //zablokuj przerwanie z INT0
  ReceiveData();                //odbierz dane
  EIFR |= _BV(INTF0);           //"wyzeruj" flagę przerwania z int0
  GIMSK |= _BV(INT0);           //odblokuj przerwanie z INT0
}

//----------------------------------------------------------------

ISR(TIMER0_COMPA_vect)
{
  Display(dane);                //wyświetlaj
}

//----------------------------------------------------------------

int main(void)                       //main
{
  GIMSK |= _BV(INT0);                //włącz przerwanie z INT0
  MCUCR=0x02;                        //przerwanie z INT0 wyzwalane zboczem
                                     // opadającym

  TIMSK |= _BV(OCIE0A);              //włącz timer0
  TCCR0A |= _BV(WGM01);              //tryb CTC
  TCCR0B |=  _BV(CS02) | _BV(CS00);  //prescaler 1024
  OCR0A = 20;                        //wartość przy której TCNT0 ma być
                                     //czyszczony( 180Hz )

  DDRB=0xff;                         //port B - wyjscia
  PORTB=0x00;                        //port B = 00000000

  DDRD=0xfb;                         //PD2 - wejscie pozostałe wyjscia
  PORTD=0x00;                        //port D = 00000000

  sei();                             //odblokuj przerwania

  while(1);                          //petla nieskończona 
                                     //wszystko działa w przerwaniach :-)
}



Do pobrania: Wyswietlacz_6_LED_1wire.c (kopia)

Program nadajnika układu testowego:

//*********************************************************************
//***                     Program testowy dla                       ***
//***                 6-cyfrowego wyświetlacza LED 1wire            ***
//***                          by Dejmos                            ***
//***                uC - ATtiny2313       F_CPU - 8MHz             ***      
//***                FUSES - low: 0xFF;    high: 0xFF               ***
//***   Eclipse SDK       Version: 3.7.1                            ***
//***   AVR Eclipse Plugin    Version: 2.4.0.201203041437           ***
//***                                                               ***
//*********************************************************************

#include <avr\io.h>
#include <util/delay.h>
#include <util/crc16.h>

#define adress_device_1 0x01       //adres pierwszego wyświetlacza
#define INPUT 0x01                 //nr pinu 1wire
#define PIN_1WIRE PINB             //wejście 1wire na porcie B
#define CLEAR_1WIRE DDRB |= _BV(0) //wyjście - ściągnięcie lini 1wire do 0
#define SET_1WIRE DDRB &= ~_BV(0)  //wejście (zwolnienie lini 1wire)
//pin w stanie wysokiej impedancji
//linia 1wire podciągana przez rezystor
uint8_t MeasuredData[10];          //tablica danych pomiarowych i instrukcji

long int counter=0;                //licznik
long int counter2=0;               //licznik2

//----------------------------------------------------------------

unsigned char ResetPresence()      //detekcja obecnoci urządzenia
{
  uint8_t PRESENCE;                //deklaracja zmiennej PRESENCE
  CLEAR_1WIRE;                     //ściągnięcie lini 1wire do 0
  _delay_us(480);                  //przytrzymaj przez 480us (impuls resetu)
  SET_1WIRE;                       //zwolnienie lini 1wire
  _delay_us(180);                  //odczekaj część impulsu obecności
  if(!(PIN_1WIRE&INPUT)) {
    PRESENCE=1;                    //sprawdź czy urządzenie obecne
  } else {
    PRESENCE=0;                    //urządzenie nieobecne
  }
  _delay_us(300);                  //odczekaj pozostałą część impulsu obecności
  return PRESENCE;                 //zwróć wartość PRESENCE
}

//----------------------------------------------------------------

void SendByte(uint8_t bajt)        //funkcja wysyłająca bajt
{
  uint8_t i, temp;                 //deklaracja zmiennych i , temp
  for(i=0; i<8; i++) {             //powtórz 8 razy (wysyłaj 8 bitów)
    temp = bajt & 0x01;            //wyłuskaj najmniej znaczący bit
    CLEAR_1WIRE;                   //zeruj 1wire
    if(temp) {                     //jeżeli najmniej znaczący bit = 1
      _delay_us(10);               //generyj opóźnienie 10 us
      SET_1WIRE;                   //zwolnij 1wire
      _delay_us(110);              //generyj opóźnienie 110 us
    } else {                       //w przeciwnym wypadku
      _delay_us(110);              //generyj opóźnienie 110 us
      SET_1WIRE;                   //zwolnij 1wire
      _delay_us(10);               //generyj opóźnienie 10 us
    }
    bajt>>=1;                      //przesuń bajt o 1 w prawo.
  }
}

//----------------------------------------------------------------

void SendMeasure(uint8_t *str)     //funkcja wysyłająca tablicę danych
{
  uint8_t Present, i;              //deklaracja zmienneych Present, i
  uint8_t Err=0;                   //deklaracja zmiennej Err 
                                   //i przypisanie jej wartości 0
  uint8_t crc8=0;                  //deklaracja zmiennej crc8 
                                   //i przypisanie jej wartości 0
  str[8]=adress_device_1;          //adres wyswietlacza do 9 komórki tablicy
  for(i=0; i<9; i++) {             //wykonaj 9 razy
    crc8 = _crc_ibutton_update(crc8, str[i]); //oblicz crc z pierwszych
                                           //9 bajtów
  }
  str[9]=crc8;                     //wpisz wartość crc jako ostatni bajt
                                   //do wysłania
  Present = ResetPresence();       //resetuj linię 1wire
  if(Present) {                    //sprawdź czy wyświetlacz się zgłosił
    Present=0;                     //wyzeruj flagę zgłoszenia
    for(i=0; i<10; i++) {          //wykonaj 10 razy
      SendByte(str[i]);            //wyślij dane i instrukcje
    }
  }
  do {                             //wykonuj i sprawdzaj flagę Err
    _delay_us(250);                //czekaj 250 us
    if(!(PIN_1WIRE&INPUT)) {       //sprawdź stan lini 1wire
      //jeżeli zero na lini - bład danych crc - ponowne wysłanie
      crc8=0;                      //zeruj crc8
      counter2++;                  //zwiększ licznik 2 (licznik ilości 
                                //błędów transmisji)
      PORTB ^= _BV(7);             //zmień stan diody
      Err = 1;                     //ustaw flagę Err
      _delay_ms(3);                //odczekaj 3 ms
      str[8]=adress_device_1;      //do 9 komórki tablicy
      for(i=0; i<9; i++) {         //wykonaj 9 razy
        crc8 =_crc_ibutton_update(crc8,str[i]); //ponownie oblicz crc 
                                          //z pierwszych 9 bajtów
      }
      str[9]=crc8;                 //wpisz wartość crc jako ostatni
                                //bajt do wysłania
      Present = ResetPresence();   //resetuj linię 1wire
      if(Present) {                //sprawdź czy wyświetlacz się zgłosił
        Present=0;                 //wyzeruj flagę zgłoszenia
        for(i=0; i<10; i++) {      //wykonaj 10 razy
          SendByte(str[i]);        //wyślij dane i instrukcje
        }
      }
    } else {                       //jeżeli linia wolna
      Err = 0;                     //zeruj flagę Err
      _delay_ms(3);                //odczekaj 3 ms
    }
  } while(Err);                    //wykonuj dopuki flaga Err jest ustawiona
}

//----------------------------------------------------------------

void Conversion(long int value)    //funkcja konwertująca liczbę
{
  //na poszczególne cyfry
  MeasuredData[0]=(value/100000)%10;  //i
  MeasuredData[1]=(value/10000)%10;   //wpisująca
  MeasuredData[2]=(value/1000)%10;    //ich
  MeasuredData[3]=(value/100)%10;     //wartość
  MeasuredData[4]=(value/10)%10;      //do odpowiednich
  MeasuredData[5]=value%10;           //komórek tablicy
}

//----------------------------------------------------------------

int main(void)                     //main
{
  DDRB=0xfd;                       //PB1 wejście pozostałe wyjścia
  PORTB=0xfe;                      //port B = 11111110
  uint8_t i, j;
  while(1) {                       //pętla nieskończona
    Conversion(counter);           //konwertuj licznik
    _delay_ms(100);                //opóźnienie 100 ms
    SendMeasure(MeasuredData);     //wyślij dane
    counter++;                     //zwiększ counter o 1
    if(counter>1000) {             //jeżeli licznik przekroczył wartość
      _delay_ms(100);              //opóźnienie 100ms
      counter=0;                   //wyzeruj licznik
      for(i=0; i<6; i++) {
        MeasuredData[i]= i;        //wpisz wartości do wysłania
      }
      for(j=0; j<20; j++) {        //wykonaj 20 razy
        for(i=0; i<6; i++) {       //wykonaj 6 razy
          MeasuredData[i]++;       //zwiększ wartość komórki i
          if(MeasuredData[i]>20) {
            MeasuredData[i]=20;    //jeżeli przekroczyła zakres
          }
        }
        _delay_ms(1);              //opóźnienie 1ms
        SendMeasure(MeasuredData); //wyślij dane do wyświetlenia
        _delay_ms(500);            //opóźnienie 500ms
      }
      Conversion(counter2);        //konwertuj licznik błędów
      SendMeasure(MeasuredData);   //wyslij wartość licznika błędów
      counter2=0;                  //wyzeruj licznik 2
      while(PINB&0x02);            //czekaj na wciśnięcie przycisku
      _delay_ms(5);                //opóźnienie
      while(!(PINB&0x02));         //czekaj na puszczenie przycisku

    }
  }
}

Do pobrania: Nadajnik_1wire_do_wyswietlacza_6_LED_1wire.c (kopia)


Komplet plików

Do pobrania komplet plików: Dokumentacja.rar (kopia)


Pytania?

Jeżeli masz jakieś pytania, śmiało zadawaj za pomocą komentarzy.
Pozdrawiam,
Dejmos :-)

3 komentarze:

  1. Witam. Na początku piszesz, że uprościłeś protokół. Czy jest on w takim razie zgodny z 1wire?

    OdpowiedzUsuń
    Odpowiedzi
    1. Jeżeli chciałbyś podłączyć jakiś układ Dallasa do tej samej magistrali to raczej się nie uda. Czasy i struktura bajtów zostały takie jak są dopuszczone dla 1wire dlatego napisałem też, że na podstawie umieszczonych tutaj listingów można napisać pełnowartościową procedurę obsługi magistrali. Wyświetlacz zachowuje się jak pasywny slave, który zgłasza tylko swoją obecność i dla potrzeb aplikacji błąd crc.
      Dejmos.

      Usuń
    2. Dziękuję za odpowiedź. W weekend wykorzystam twój protokół transmisji do innego projektu, gdzie mam mało pinów. Fajnie, że podzieliłeś się całym projektem. Mam nadzieję, że to nie będzie jedyny twój artykuł. :) Pozdrawiam. Arek

      Usuń