Przejściówka i2c na 1wire – AVR + bascom

Moje stacje pogody bazują w większości na czujnikach z interfejsem i2c. Jednak maksymalnym bezpiecznym dystansem dla tej magistrali jest, według różnych źródeł, od 0.4 do 2 metrów. Możliwym rozwiązaniem było zastosowanie układu P82B715 – dwukierunkowego transceivera i2c. Niemniej jednak, P82B715 jest dostępny tylko w jednym sklepie w sieci, jest stosunkowo drogi, a wysyłka kosztuje sporo. Z tego powodu zdecydowałem się na użycie konwertera i2c do 1wire – magistrali dla której nawet odległość 300 metrów nie jest straszna – oczywiście przy zastosowaniu prawidłowego okablowania. Dodatkowo, nie muszę podłączać do routera kolejnego konwertera (USB->i2c).

W tym wpisie opisywałem klon układu DS2423, czyli scalonego licznika impulsów, na bazie ATTiny, napisany w C. Tym razem byłem zmuszony zastosować język bascom, ponieważ nie programuje w C, a nie udało mi się znaleźć gotowego układu. W sieci odnalazłem natomiast kod emulatora konwertera ADC, układu DS2450, napisany w bascomie i odpowiednio go zmodyfikowałem.

Miałem kilka założeń:

  1. absolutnie niezbędna jest współpraca z OWFS pod linuxami oraz routerem z OWFS
  2. układ powinien pracować z OneWireViewer pod Windowsem (do celów debugowania)
  3. układ ma być prosty w konstrukcji, tani i niewielki

W kodzie programu możliwa jest zmiana ID emulowanego układu, włącznie z familyID. Oznacza to, że procesor (u mnie ATMega8) może udawać dowolny układ z rodziny 1wire – wystarczy jedynie wybrać odpowiedni slave-code, a następnie za pomocą dostępnych w sieci kalkulatorów CRC (np. tego) wyznaczyć 64bitowy ID.
Poniżej przykładowe IDs dla opisywanego DS2430 oraz dla termometru DS18B20. (należy wybrać wyłącznie jeden ID, a drugi lub kolejne wykomentować)

Myroms:
Data &H14 , &H69 , &H69 , &H69 , &H00 , &H00 , &H00 , &HBB  'ds2340a
'Data &H28 , &H66 , &H66 , &HBA , &H00 , &H00 , &H00 , &H68 'ds18b20

Komunikacja 1wire opiera się na jednobajtowych komendach, zazwyczaj zapisanych szesnastkowo, wysyłanych przez układ główny (master), po odebraniu których układ podrzędny (slave) wykonuje zadane czynności (np. pomiar temperatury) lub wysyła dane. Modyfikując źródło w moim projekcie można dopasować działanie emulowanego układu.

Przykładowo – emulowany jest u mnie układ DS2430A, czyli niewielka kostka zawierająca 256 bitów pamięci EEPROM oraz 64bitów pamięci jednokrotnego zapisu. O jego użyciu zadecydowało to, że zapis pamięci nie wymaga kopiowania do notatnika (scratchpad), a odczyt podawania stron pamięci, co ogromnie upraszcza kod a także umożliwia współpracę z programem OneWireViewer. Dodatkowo – dostępna jest komenda, która wyjściowo służy do sprawdzenia czy pamięć jednorazowa została już zapisana (READ APPLICATION REGISTER [C3h]). U mnie następuje wtedy uruchomienie konwersji na wszystkich czujnikach i2c. Dopiero komenda odczytu pamięci (READ MEMORY [F0h]) wysyła odczytane wyniki pomiarów do „bazy”. W poniższym kodzie widać dopisane odpowiednie stałe, które potem odsyłają program do konkretnych funkcji.

' Commands
Const Search_rom = &HF0
Const Skip_rom = &HCC
Const Match_rom = &H55
Const Read_rom = &H33
Const Writemem = &H55
Const Convert = &H3C
Const Read_mem = &HAA
Const Bootload = &HEE
Const Write_epr = &HE0
Const Convertt = &H44                                       
Const Readscratchpad = &HBE                                 
Const Recalle2 = &HB8
Const Read2430 = &HF0
Const Status = &HC3
If Bytedat = Status Then Goto Do_convert
If Bytedat = Read2430 Then Goto Wyslijdane

Chcąc zmodyfikować komendy, na które będzie odpowiadał układ należy we wskazanych powyżej miejscach dodać odpowiednie stałe, a następnie dopisać odpowiednie warunki w select case oraz procedury.

Wysyłanie kolejnych bajtów danych polega na naprzemiennych zmianach zawartości zmiennej bytedat a następnie uruchamianiu procedury sendbyte. Jako pierwszy bajt wysyłam hFF, ponieważ OneWireWiever go „nie widzi”.

Wyslijdane:
   Set Yellow
   Bytedat = &HFF
   Gosub Sendbyte
   Bytedat = Scratch(1)
   Gosub Sendbyte
   Bytedat = Scratch(2)
   Gosub Sendbyte
   Bytedat = Scratch(3)
   Gosub Sendbyte
   Bytedat = Scratch(4)
   Gosub Sendbyte
   Bytedat = Scratch(5)
   Gosub Sendbyte
   Bytedat = Scratch(6)
   Gosub Sendbyte
   Bytedat = Scratch(7)
   Gosub Sendbyte
   Bytedat = Scratch(8)
   Gosub Sendbyte
   Bytedat = Scratch(9)
   Gosub Sendbyte
   Bytedat = Scratch(10)
   Gosub Sendbyte
   Bytedat = Scratch(11)
   Gosub Sendbyte
   Bytedat = Scratch(12)
   Gosub Sendbyte
   Reset Yellow
   Print "send" 
Goto Mainloop

Procedura Do_convert jest uruchamiana w celu pobrania danych z czujników. Nie można tego zrobić bezpośrednio przed ich odczytem, ponieważ na ogół wymagają one kilku-kilkudziesięciu milisekund na konwersję. Dlatego też – najpierw uruchamiam konwersję, a po około 800ms pobieram najnowsze dane.

  1. UWAGA! Cały układ jest zasilany napięciem 3.3V. Należy upewnić się, że używany mikroprocesor będzie pracował z tym napięciem (ATMega8 występuje w dwóch odmianach – działającej w zakresach napięcia 4.5-5.5V oraz rozszerzonej 2.7-5.5V).
  2. Użyte złącze RJ11 1wire nie ma standardowego rozkładu wyprowadzeń
  3. Podczas programowania za pomocą np. USBasp nie należy zasilać układu z dwóch źródeł zasilania 5V. Należy wybrać – albo programator, albo magistrala 1wire.

Odpowiednio zaprogramowany układ jest widoczny w systemie OWFS i bez problemu udaje kostkę DS2430.

winscpwinscp2

I2c1wire
I2c1wire
i2c1wire.zip
120.9 KiB
103 Downloads
Szczegóły
'****************************************************************
'*  Name        : Mega 8 pressure to 1wire.BAS                  *
'*  Author      : Vladimir I. Yershov,                          *
'*  Modified by : Piotr Ostalecki                               *
'*  Date        : 21. 6.2014                                    *
'*  Version     : 1.1                                           *
'*  Notes       : Firmware for Tiny and Mega AVR to emulate     *
'*                Dallas DS2430                                 *
'*          :                                                   *
'****************************************************************

$regfile = "M8DEF.DAT"
$crystal = 8000000
$baud = 9600
Print "start systemu"

Dim Bug As Bit
Bug = 1

Config Timer0 = Timer , Prescale = 64

Config Portd.7 = Output
Yellow Alias Portd.7
Config Portd.6 = Output
Red Alias Portd.6

'zółta dioda - wysyłka danych
'czerwona - konwersja

Reset Yellow
Reset Red

$lib "i2c_twi.lbx"
Config Scl = Portc.5
Config Sda = Portc.4


Dim Pres_r As Byte , Pres_w As Byte
Dim P_msb As Byte , P_csb As Byte , P_lsb As Byte
Dim Pressure As Dword
Dim Tempx As Word
Dim Calc As Single
Dim Fract As Single

Dim Pr As Byte , Pw As Byte
Pr = &HC1
Pw = &HC0

Dim R As Byte , W As Byte
W = &H80
R = &H81

Dim Als_r As Byte , Als_w As Byte
Als_w = &H94
Als_r = &H95


I2cinit

I2crepstart
   'podaj adres urzadzenia
   I2cwbyte Pw
   If Err = 0 Then
      'Print "pressure sensor ok"
   Else
      'Print "pressure sensor error"
   End If
   'podaj adres rejestru
   I2cwbyte &H27
   I2cwbyte &B00100010
I2cstop
' Waitms 100

I2crepstart
   'podaj adres urzadzenia
   I2cwbyte Pw
   'podaj adres rejestru
   I2cwbyte &H26
   I2cwbyte &H38
I2cstop
 'Waitms 100

I2crepstart
   'podaj adres urzadzenia
   I2cwbyte Pw
   'podaj adres rejestru
   I2cwbyte &H26
   I2cwbyte &H39
I2cstop

I2cstart
   I2cwbyte Als_w
   I2cwbyte &H02
   I2cwbyte &B10000000
I2cstop

Const Dqpin = 2
Const Ipin = 0                                              ' value in DDRB for input
Const Opin = 1                                              ' value in DDRB for output

Timer Alias Tcnt0

'Print "konfiguracja 1wire"

Dq Alias Pind.dqpin

' Commands
Const Search_rom = &HF0
Const Skip_rom = &HCC
Const Match_rom = &H55
Const Read_rom = &H33
Const Writemem = &H55
Const Convert = &H3C
Const Read_mem = &HAA
Const Bootload = &HEE
Const Write_epr = &HE0
Const Convertt = &H44                                       'dodane ds18b20
Const Readscratchpad = &HBE                                 'dodane ds18b20
Const Recalle2 = &HB8
Const Read2430 = &HF0
Const Status = &HC3
' Timings

'150
Const Owpresent = 120
'  60us < OWPresent < 240us
Const Owpause = 40
'  15us < OWPause   < 60us
Const Owstrobe = 15
'  read Dq value after Owstrobe us
Const Owdata = 25
'  Valid output data for Owdata us

 Dim Suma As Byte

 Dim Licze As Byte                                          '  Valid output data for Owdata us                                         '20 '15                                           '12                  '7            12

' Timer Delays

Const T1reset = 60                                          'T1us * 490 Min Reset width
Const Timeout = 120                                         'T1us * 970 Max Reset width

' Allocate variables

Dim I As Byte
Dim B As Byte
Dim C As Byte

Dim Inmask As Byte
Dim Readout As Byte
Dim Addrlo As Byte
Dim Adcnum As Byte
Dim Addtemp As Byte

Dim Myrom(8) As Byte
Dim Mytemp(9) As Byte

Dim Scratch(12) As Byte

'wysyłane dane, inicjalizacja zmiennych
Scratch(1) = &HCC
Scratch(2) = &HCC
Scratch(3) = &HCC
Scratch(4) = &HCC
Scratch(5) = &HCC
Scratch(6) = &HCC
Scratch(7) = &HCC
Scratch(8) = &HCC
Scratch(9) = &HCC
Scratch(10) = &HCC
Scratch(11) = &HCC
Scratch(12) = &HCC

Dim Ee As Byte
Ee = 0

Dim Crc16_hi As Byte
Dim Crc16_lo As Byte

Dim Ram(32) As Byte
Dim Ramw(16) As Word                                        ' At                                     ' Ram(8) Overlay
Dim Ad_result As Word
Dim Bytedat As Byte
Dim Wreg As Byte

Dim Tstval As Byte
Dim Temp As Byte
Dim Templ As Byte
Dim Temph As Byte
Dim Tempw As Word At Templ Overlay

Dim Overresol As Byte
Dim Oversample As Byte
Dim Overcount As Byte
Dim Overshift As Byte
Dim Normshift As Byte

Dim Bitdat As Bit

         'Goto Getpres
         Enable Interrupts
         Enable Timer0
         'Enable Timer1
         On Timer0 Isr Nosave
         'On Timer1 Getpres

         Restore Myroms
         For Addrlo = 1 To 8
         Read B
         Myrom(addrlo) = B
         Next Addrlo

         Restore Mytemps
         For Addtemp = 1 To 9
         Read C
         Mytemp(addtemp) = C
         Next Addtemp

         Stop Timer0
                                     ' version info

         Waitms 500

         'Print "ready"
'-----------------------------------

Mainloop:
Waitreset:

    Disable Interrupts
    Timer = 0

Waitfall:

L1:
    sbis pind, DqPin
    rjmp L1
L2:
    sbic pind, DqPin
    rjmp L2
    Timer = 0
    Start Timer0

Rwaitrise:

L01:
    sbic pind, DqPin
    rjmp L01
L02:
    sbis pind, DqPin
    rjmp L02

    Stop Timer0

    If Timer < T1reset Then Goto Waitreset
    If Timer > Timeout Then Goto Waitreset

Sendpresense:

    Waitus Owpause
    Ddrd.dqpin = Opin
    Waitus Owpresent
    Ddrd.dqpin = Ipin
    Timer = 0
    Enable Interrupts

Readb:
    Gosub Readbyte
Readb1:
    If Bytedat = Match_rom Then Goto Matchrom
    If Bytedat = Read_rom Then Goto Readrom
    If Bytedat = Search_rom Then Goto Sendrom
    If Bytedat = Skip_rom Then Goto Funct
    If Bytedat = Convertt Then Goto Pomiarth
    If Bytedat = Status Then Goto Do_convert

   Goto Readb
End



Isr:
    Spl = &H5F
    Sph = 1

    If Dq = 0 Then
    Timer = T1reset

    Goto Rwaitrise
    Else
    Goto Waitreset
    End If

Return
'-------------------------------
Readrom:
       For B = 1 To 8
       Bytedat = Myrom(b)
       Gosub Sendbyte
       Next B
Goto Readb
'----------------------------------
Matchrom:
        For B = 1 To 8
        Gosub Readbyte
        If Bytedat <> Myrom(b) Then Goto Mainloop
        Next B
Funct:
        Gosub Readbyte

        If Bytedat = Recalle2 Then Goto Mainloop

        If Bytedat = Readscratchpad Then Goto Sendscratchpad

        If Bytedat = Convertt Then Goto Pomiarth

        If Bytedat = Convert Then Goto Conversion

        If Bytedat = Read_mem Then Goto Readmem

        If Bytedat = Writemem Then Goto Write_mem

        If Bytedat = Bootload Then Goto Fwupgrade

        If Bytedat = Read2430 Then Goto Wyslijdane



Goto Readb1
'----------------------------------------
Fwupgrade:
        Gosub Sendbyte
        jmp 0

Readmem:
        Crc16_lo = 0
        Crc16_hi = 0
        B = 0

        Gosub Crc_update                                    ' ByteDat = ReadMem

        Gosub Readbyte
        Addrlo = Bytedat
        Gosub Crc_update                                    ' ByteDat = AddrLo

        Gosub Readbyte
        Gosub Crc_update                                    ' ByteDat = AddrHi
Readloop:
        Bytedat = Ram(addrlo + 1)

        Gosub Sendbyte
        Gosub Crc_update

        Incr Addrlo
        Incr B

        If B = 8 Then Goto Exitreadmem
        Goto Readloop
Exitreadmem:
        B = 0

        Bytedat = Crc16_lo Xor &HFF
        Gosub Sendbyte
        Bytedat = Crc16_hi Xor &HFF
        Gosub Sendbyte

        Crc16_lo = 0
        Crc16_hi = 0

        If Addrlo < 31 Then Goto Readloop

Goto Mainloop

'----------------------------------------
Write_mem:
        Crc16_lo = 0 : Crc16_hi = 0

        Gosub Crc_update                                    'Bytedat = Writemem

        Gosub Readbyte
        Addrlo = Bytedat
        Gosub Crc_update                                    ' AddrLo

        Gosub Readbyte
        Gosub Crc_update                                    ' AddrLo

        Gosub Readbyte
        Ram(addrlo + 1) = Bytedat
        Gosub Crc_update                                    ' MemByte

        Bytedat = Crc16_lo Xor &HFF
        Gosub Sendbyte

        Bytedat = Crc16_hi Xor &HFF
        Gosub Sendbyte

        Bytedat = Ram(addrlo + 1)
        Gosub Sendbyte
' ====== END OF FIRST PASS ===========
 Writememloop:
        Incr Addrlo
            Crc16_hi = 0
            Crc16_lo = Addrlo                               ' low (Crc16) = Addrlo

            Gosub Readbyte
            Ram(addrlo + 1) = Bytedat
            Gosub Crc_update

            Bytedat = Crc16_lo Xor &HFF
            Gosub Sendbyte

            Bytedat = Crc16_hi Xor &HFF
            Gosub Sendbyte

            Bytedat = Ram(addrlo + 1)
            Gosub Sendbyte

         If Addrlo < 31 Then Goto Writememloop

Goto Mainloop

' =============
Conversion:
        Crc16_lo = 0 : Crc16_hi = 0
        Gosub Crc_update                                    'ByteDat = Convert

        Gosub Readbyte                                      'ByteDat = InMask
        Gosub Crc_update

        Gosub Readbyte                                      'ByteDat = ReadOut
        Gosub Crc_update

        Bytedat = Crc16_lo Xor &HFF
        Gosub Sendbyte

        Bytedat = Crc16_hi Xor &HFF
        Gosub Sendbyte

        Overresol = 12                                      ' Desired Oversample Resolution
        Overshift = Overresol - 10                          ' Shift Left After Oversampling
        Normshift = 6 - Overshift
        Oversample = 4 ^ Overshift


          For Adcnum = 1 To 4
             Ramw(adcnum) = 0
          Next Adcnum

          Start Adc
          For Overcount = 1 To Oversample
              For Adcnum = 1 To 4
              B = Adcnum - 1
              Ad_result = Getadc(b)
              Ramw(adcnum) = Ramw(adcnum) + Ad_result
              Next Adcnum
          Next Overcount
         For Adcnum = 1 To 4
              Shift Ramw(adcnum) , Right , Overshift
              Shift Ramw(adcnum) , Left , Normshift
         Next Adcnum

Exit_case:

        Stop Adc

Goto Mainloop
'======================================================
Crc_update:

        Wreg = Bytedat
        Wreg = Wreg Xor Crc16_lo
        Temp = Wreg
        Wreg = Crc16_hi
        Crc16_lo = Wreg
        Wreg = 0

        If Temp.0 = 1 Then Wreg = &HCC

        If Temp.1 = 1 Then Wreg = Wreg Xor &H8D

        If Temp.2 = 1 Then Wreg = Wreg Xor &H0F

        If Temp.3 = 1 Then Wreg = Wreg Xor &H0A

        Crc16_hi = Wreg
        Wreg = Wreg And &HF0
        Crc16_hi = Crc16_hi Xor Wreg
        Crc16_lo = Crc16_lo Xor Wreg
        Wreg = 0

        If Crc16_hi.3 = 1 Then Wreg = &HCC

        If Temp.4 = 1 Then Wreg = Wreg Xor &HCC

        If Temp.5 = 1 Then Wreg = Wreg Xor &HD8

        If Temp.6 = 1 Then Wreg = Wreg Xor &HF0

        If Temp.7 = 1 Then Wreg = Wreg Xor &HA0

        Crc16_hi = Crc16_hi Xor Wreg
        Wreg = 1

        If Crc16_hi.7 = 1 Then Crc16_lo = Crc16_lo Xor Wreg

Return
'---------------------------------
'================================
Readbyte:
         For I = 0 To 7

L11:
    sbis pind, DqPin
    rjmp L11
L12:
    sbic pind, DqPin
    rjmp L12
         Timer = 256 - T1reset
         Start Timer0
         Rotate Bytedat , Right
         Waitus Owstrobe
         Bytedat.7 = Dq
         Next I
         Stop Timer0
Return
'----------------------------------
Sendbyte:
       Adcnum = Bytedat
        For I = 0 To 7

L21:
    sbis pind, DqPin
    rjmp L21
L22:
    sbic pind, DqPin
    rjmp L22
           Timer = 256 - T1reset
           Start Timer0

           If Bytedat.0 = 0 Then Ddrd.dqpin = Opin
           Waitus Owdata
           Ddrd.dqpin = Ipin

           Rotate Bytedat , Right

        Next I
        Bytedat = Adcnum
        Stop Timer0
Return
'-----------------------------------
Sendrom:
'    Stop Timer0
    For I = 1 To 8
          Bytedat = Myrom(i)
      For B = 0 To 7
'----------------------------
Sendcbit1:

L31:
    sbis pind, DqPin                                        'wH
    rjmp L31
L32:
    sbic pind, DqPin                                        'wL
    rjmp L32

           If Bytedat.0 = 0 Then Ddrd.dqpin = Opin
           Waitus Owdata
           Ddrd.dqpin = Ipin
'----------------------------
Sendcbit2:

L41:
    sbis pind, DqPin
    rjmp L41
L42:
    sbic pind, DqPin
    rjmp L42

           If Bytedat.0 = 1 Then Ddrd.dqpin = Opin
           Waitus Owdata
           Ddrd.dqpin = Ipin

'--------------------------
Readcbit:

L51:
    sbis pind, DqPin
    rjmp L51
L52:
    sbic pind, DqPin
    rjmp L52

           Waitus Owstrobe

           Bitdat = Dq

'-------------------------
             If Bitdat <> Bytedat.0 Then Goto Mainloop
             Rotate Bytedat , Right
      Next B
    Next I

Goto Readb

Wyslijdane:
   Set Yellow
   Bytedat = &HFF
   Gosub Sendbyte
   Bytedat = Scratch(1)
   Gosub Sendbyte
   Bytedat = Scratch(2)
   Gosub Sendbyte
   Bytedat = Scratch(3)
   Gosub Sendbyte
   Bytedat = Scratch(4)
   Gosub Sendbyte
   Bytedat = Scratch(5)
   Gosub Sendbyte
   Bytedat = Scratch(6)
   Gosub Sendbyte
   Bytedat = Scratch(7)
   Gosub Sendbyte
   Bytedat = Scratch(8)
   Gosub Sendbyte
   Bytedat = Scratch(9)
   Gosub Sendbyte
   Bytedat = Scratch(10)
   Gosub Sendbyte
   Bytedat = Scratch(11)
   Gosub Sendbyte
   Bytedat = Scratch(12)
   Gosub Sendbyte
   Reset Yellow
   Print "send"

Goto Mainloop


Pomiarth:
Goto Mainloop

Do_convert:
   Set Red
   'MPL3115A2
   I2cstart
   'podaj adres urzadzenia
   I2cwbyte Pw
   'podaj adres rejestru
   I2cwbyte &H01
   I2cstart
   'podaj adres urzadzenia
   I2cwbyte Pr
   I2crbyte Scratch(1) , Ack
   'Pressure Data Out MSB
   I2crbyte Scratch(2) , Ack
   'Pressure Data Out CSB
   I2crbyte Scratch(3) , Ack
   'Pressure Data Out LSB
   I2crbyte Scratch(4) , Ack
   'Temperature Data Out MSB
   I2crbyte Scratch(5) , Ack
   'Temperature Data Out LSB
   I2crbyte Scratch(6) , Nack
   'Sensor Status Register
   I2cstop

   'Si7021
   I2cstart
   'konwersja RH
   I2cwbyte W
   I2cwbyte &HF5

   I2crepstart
   'oczekiwanie na gotowosc
   I2cwbyte R
     While Err = 1
     Waitms 1
     I2crepstart
     I2cwbyte R
     Wend
   'odczyt MSB i LSB
   I2crbyte Scratch(7) , Ack
   'Humidity Data Out MSB
   I2crbyte Scratch(8) , Nack
   'Humidity Data Out LSB

   I2cstart
   'odczyt temperatury
   I2cwbyte W
   I2cwbyte &HE0
   I2crepstart
   I2cwbyte R
   I2crbyte Scratch(9) , Ack
   'Si7021 temperature Data Out MSB
   I2crbyte Scratch(10) , Nack
   'Si7021 temperature Data Out LSB
   I2cstop


   'max44009
I2cstart
   'podaj adres urzadzenia
   I2cwbyte Als_w
   'podaj adres rejestru
   I2cwbyte &H03
   I2crepstart
   I2cwbyte Als_r
   I2crbyte Scratch(11) , Nack
   I2crepstart
   I2cwbyte Als_w
   I2cwbyte &H04
   I2crepstart
   I2cwbyte Als_r
   I2crbyte Scratch(12) , Nack


   Reset Red
   Print "convert"
Goto Mainloop

Sendscratchpad:
Goto Mainloop


End


Myroms:
Data &H14 , &H69 , &H69 , &H69 , &H00 , &H00 , &H00 , &HBB  'ds2340a
'Data &H28 , &H66 , &H66 , &HBA , &H00 , &H00 , &H00 , &H68 'ds18b20
Mytemps:
Data &H77 , &H01 , &H00 , &H00 , &H7F , &HFF , &H09 , &H10 , &H57
'       1      2      3      4      5      6      7      8    9crc
Udostępnij:Share on FacebookEmail this to someoneWykop!Share on Google+Print this pageShare on TumblrTweet about this on Twitter

Dodaj komentarz

Twój adres email nie zostanie opublikowany.