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

[mega8][BASCOM]Jak zapisać i odczytać dane z 24Cxx ?

monty_p 02 Lip 2008 18:05 17618 143
Najlepsze odpowiedzi

How can I store a DS1990A serial number and a one-byte value in a 24Cxx EEPROM in BASCOM, then search for that serial number and update its value?

Najprościej zapisz każdy rekord jako 4 bajty numeru DS1990A + 1 bajt danych, a liczbę wpisów trzymaj w pierwszych komórkach EEPROM (albo w wewnętrznym ERAM) i przy wyszukiwaniu przechodź pętlą po wszystkich rekordach, porównując bajt po bajcie [#5314490] [#5319904] [#5326391] Do zapisu/odczytu używaj zwykłego I2C: `I2cstart`, adres układu, potem adres komórki i dane; dla 24C32–24C512 adres komórki jest 16-bitowy, więc rozbij go na `High(adres)` i `Low(adres)`, a dla 24C16 adresowanie działa inaczej, bo część bitów adresu siedzi w bajcie kontrolnym [#5336054] [#5368601] [#5422500] Jeśli adres może przekroczyć 255, zmienna adresu musi być typu `Word`, nie `Byte`, bo inaczej zaczynają się dziwne skoki typu `10255` [#5400342] [#5422500] W BASCOMie nie musisz niczego konwertować na HEX do zapisu — wartość `&HDA` to po prostu bajt 218 i tak samo zapisze się do EEPROM-u [#5319260] Dla Twojego projektu sensowniejsza od karty SD jest właśnie zewnętrzna pamięć I2C, bo uprości sprzęt i program, a record lookup można zrobić prostą pętlą po zapisanych wpisach [#5314384] [#5314490] [#5322207]
Wygenerowane przez model językowy.
REKLAMA
  • Pomocny post
    #61 5319904
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Przejrzystosc w kodzie przede wszystkim. :D Pozniej latwiej jest zlokalizowac ewentualne bledy i samo poruszanie sie w kodzie jest znacznie latwiejsze. W kazdym razie wracajac do tematu to ja osobiscie nie lubie etykiet wiec wolalbym to rozwiazac np. w ten sposob:

    Sub Czytaj_id_klucza()
      'tutaj wstawiasz kod odczytu
    End Sub


    i pozniej tylko:

    Call Czytaj_id_klucza()


    Deklaracje tablic juz znasz, a zapis do pamieci w petli mozesz zrobic np. tak:

    Dim Key_id(8) As Byte
    Dim I As Byte
    
    {...}
    
    For I = 1 To 4
      Zapis_do_eproma(Key_id(i) , i)
    Next I
    
    {...}


    Teraz zadanie dla ciebie:
    Zadeklaruj kolejna zmienna np. o nazwie "ilosc_kluczy" i wartosc tej zmiennej bedziesz zwiekszac za kazdym razem, gdy dodasz ID klucza do pamieci. W powyzszym przykladzie 4 bajty zawierajace ID klucza beda zawsze zapisywane pod adresami od 1 - 4 w pamieci eeprom. Wiec wykorzystujac zmienna "ilosc_kluczy" zmodyfikuj ten kod tak zeby kolejne ID zostalo zapisane pod adresem 5-9 i kolejne pod nastepnymi itd.

    Pozdrawiam!
  • REKLAMA
  • #62 5322028
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Udało się :)
    Nie wszystko ale dla mnie to już osiągnięcie. Zaczynam to łapać :)
    Zapisuje i odczytuje cały klucz w pamięci <hura>

    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.6 , Rs = Portb.7
    Config Lcd = 16 * 1a
    
    Config Scl = Portd.0
    Config Sda = Portd.1
    
    Config Pind.6 = Input                                       'linia PD6 jako wejściowa [zapis]
    Config Pind.7 = Input                                       'linia PD7 jako wejściowa [odczyt]
    Config 1wire = Portd.5
    
    S1 Alias Pind.6                                             'przypisanie nazwie Pind.6 nazwy S1
    S2 Alias Pind.7                                             'przypisanie nazwie Pind.7 nazwy S2
    
    Set Portd.6                                                 'dołączenie do linii PD6 rezystora podciągającego
    Set Portd.7                                                 'dołączenie do linii PD7 rezystora podciągającego
    
    Const Adres_zapisu = 160                                    'adres zapisu pamieci eeprom na I2C
    Const Adres_odczytu = 161                                   'adres odczytu pamieci eeprom na I2C
    
    Declare Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
    Declare Sub Odczyt_z_eproma(byval Adres_komorki As Byte)
    Declare Sub Id_klucza()
    
    Dim Key_id(8) As Byte
    Dim A As Byte
    Dim B As Byte
    Dim Wartosc As Byte
    
    Cursor Off
       Cls
       Lcd "START PROGRAMU"
       Wait 2
    Do
    
    
       Call Id_klucza
    
      If S1 = 0 Then                                            'jeśli przyciśnięty S1, to
        Waitms 25                                               'opóźnienie dla eliminacji drgań styków
    
        If S1 = 0 Then                                          'sprawdzenie ponownie, czy przycisk S1 dalej jest naciśniety, jeśli tak, to..
    
          Cls
          Lcd "Zapis"
          Wait 1
    
          For A = 1 To 4
             Call Zapis_do_eproma(a , Key_id(a))
          Next A
    
          Lcd " - OK"
          Waitms 500
        End If                                                  'koniec warunków
      End If
    
      If S2 = 0 Then                                            'jeśli przyciśnięty S2, to
        Waitms 25                                               'opóźnienie dla eliminacji drgań styków
    
        If S2 = 0 Then                                          'sprawdzenie ponownie, czy przycisk S2 dalej jest naciśniety, jeśli tak, to..
    
    
          Cls
          Lcd "Odczyt"
          Wait 1
          Cls
    
          For A = 1 To 4
             Call Odczyt_z_eproma(a)
             Lcd Hex(wartosc)
          Next A
    
            Wait 1
        End If                                                  'koniec warunków
      End If
    Loop
    
    End
    
    Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cwbyte Wartosc
        I2cstop
    
        Waitms 10
      End If
    End Sub
    
    Sub Odczyt_z_eproma(byval Adres_komorki As Byte)
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Wartosc , Nack
        I2cstop
      End If
    End Sub
    
    Sub Id_klucza()
    
       Reset Portd.5
       Waitms 25
       1wreset
       Set Portd.5
       Waitms 25
    
       If Err = 0 Then
    
          Key_id(1) = 1wsearchfirst()
    
          If Key_id(8) = Crc8(key_id(1) , 7) Then
             Cls
             Lcd "ID: "
    
             For B = 1 To 4
                Lcd Hex(key_id(b))
             Next B
    
          End If
    
       Waitms 100
       Else
          Cls
          Lcd "Brak Pastylki"
          Waitms 100
       End If
    End Sub
    


    Teraz próbuję "ILOSC_KLUCZY" i zapis w kolejnych rekordach a nie w kółko w tych samych

    a jak zrobić, żeby można było zapisać więcej niż 255 kluczy?
    wiadomo - pojedyncza komórka przyjmuje wartości od 0-255.

    dodać do ilości kluczy drugą komórkę i mieć 255*255 możliwości? :D
  • #64 5322042
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Tak się zastanawiam, czy nie lepiej było by zmienić tytułu tego TEMATU. Tytuł jest już mało aktualny. Nie wiecie czy się tak da zmienić tytuł??

    Dodano po 6 [minuty]:

    Balu napisał:
    Chyba więcej niż 64 klucze? Skoro każdy zajmuje 4 bajty?:>



    Tym razem wiem co mówię :)

    gdybym wygospodarował pierwszą komórkę i przyporządkowywał jej aktualny numer WOLNEGO rekordu w pamięci, to mam max 255 wpisów.
    Program by sam liczył, która to komórka w pamięci.

    Np. w pierwszej komórce mam wartość 35.
    program odczytuje pierwszą komórkę i już wie, że pierwsza wolna komórka, na której można zapisać nowy klucz, to:
    1+(35*5) :)
    (1) - pierwsza komórka w pamięci
    (*5) - bo każdy klucz zajmuje 4 bajty+ 1 na dodatkowe dane dot klucza
    (35) - bo w pamięci zapisane jest już 34 zbiory po 5 bajtów

    Tak czy nie??
  • REKLAMA
  • REKLAMA
  • #66 5322095
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    No właśnie pisząc odpowiedź na twojego ostatniego posta rozjaśniło mi się :D

    pierwsza komórka to aktualna wartość a druga to wartosc 00 lub 01 (bo więcej niż 500 wpisów nie przewiduję)

    Więc:
    Jeżeli pierwsza komórka osiągnie wartość 255, to jest zerowana i automatycznie w drugiej komórce wstawiana jest wartość 01.

    i teraz... Jeżeli druga komórka = 01, to wartość pierwszej komórki = wartość pierwszej komórki +255 :)

    tak to ma być ??
  • #68 5322109
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Tak, oczywiście.

    ...czy pierwsza komórka w pamięci ma adres 0 czy 1 ?
  • #70 5322134
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    ..i jak zadeklarować zmienną "Ile_wpisow", jezeli zmienna ta może osiągnąć większą wartość niż 255 ?? Integer ?
  • #71 5322142
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Cytat:

    Elementary Data Types


    • Bit (1/8 byte). A bit can hold only the value 0 or 1. A group of 8 bits is called a byte.
    • Byte (1 byte). Bytes are stores as unsigned 8-bit binary numbers ranging in value from 0 to 255.
    • Integer (two bytes). Integers are stored as signed sixteen-bit binary numbers ranging in value from -32,768 to +32,767.
    • Word (two bytes). Words are stored as unsigned sixteen-bit binary numbers ranging in value from 0 to 65535.
    • Long (four bytes). Longs are stored as signed 32-bit binary numbers ranging in value from -2147483648 to 2147483647.
    • Single. Singles are stored as signed 32 bit binary numbers. Ranging in value from 1.5 x 10^–45 to 3.4 x 10^38
    • Double. Doubles are stored as signed 64 bit binary numbers. Ranging in value from 5.0 x 10^–324 to 1.7 x 10^308
    • String (up to 254 bytes). Strings are stored as bytes and are terminated with a 0-byte. A string dimensioned with a length of 10 bytes will occupy 11 bytes.
  • REKLAMA
  • #72 5322196
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    ...a czy mogę prosić o gotowca przynajmniej w kwestii wyszukiwania wpisów w pamięci??
    <Prosi> :)
  • #73 5322207
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Myślę, że tak
    coś na styl:
    zakładam, że w 0 i 1 komórce masz liczbę kluczy, MSB w 1 komórce, LSB w młodszej, dane zaczynają się od 4 komórki

    w id(4) tablica zawierająca klucz aktualny

    sub szukaj:
    znalazl=0
    for i = 0 to liczba_kluczy
    mult=i*mult
    mult=mult+4 'tutaj masz aktualny adres pierwszej kom pamieci

    for z=0 to 3 do
    readeeprom id_old(z), mult
    incr mult
    next z
    'tutaj niby odczytana pierwszy klucz, no to test
    if id_old(0)=id(0) then if id_old(1)=id(1) then if... itd...
    jak znalazł to co tam chcesz, to ustaw flage znalazl=1

    next i
    if znalazl=0 then dopisz nowy klucz else inkrementuj co tam chciałeś...

    end sub.

    Ostrzegam pseudo kod ale powinno wyglądać coś na ten deseń.

    Dodano po 47 [sekundy]:

    oczywiście liczba kluczy wcześniej odczytana:)
    No i działa to do 255 komórek pamięci, jak chcesz więcej rozszerz sobie odpowiednio:)
  • #74 5322212
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    BARDZO Dziękuję. Zaoszczędziłeś mi kolejną dobę dłubania :D
  • #76 5322632
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Widze chlopaki, ze nie proznujecie! :D

    :arrow: Balu: http://zbeegin.republika.pl/bashelp/ - help do Bascom'a online. Twoje modlitwy zostaly wysluchane 8)
    :arrow: monty_p: Zeby zmienic tytul, ktory faktycznie nie jest juz za bardzo aktualny, kliknij w pierwszym poscie na ZMIEN i pozniej do gory, gdzie masz tytul popraw go wg uznania.
    Ciekawi mnie czy juz skleciles wszystko w calosc, lacznie z kodem Balu. Wklej to co juz masz i pochwal sie jak to dziala :D

    A monty_p i jeszcze jedna sprawa:
    Cytat:
    ...czy pierwsza komórka w pamięci ma adres 0 czy 1 ?


    Pamietasz jak pokazywalem Tobie przykladowa organizacje pamieci eeprom?

    [adres:00][ilosc_rekordow]
    [adres:01][dane_klucza]
    [adres:02][dane_klucza]
    [adres:03][dane_klucza]
    [adres:04][dane_klucza]
    [adres:05][dane_klucza]
    [adres:06][dane_klucza]
    [adres:07][dane_klucza]
    [adres:08][dane_klucza]
    [adres:09][dodatkowe_dane]
    [adres:0A][dane_klucza]
    [adres:0B][dane_klucza]
    [adres:0C][dane_klucza]
    [adres:0D][dane_klucza]
    [adres:0E][dane_klucza]
    [adres:0F][dane_klucza]
    [adres:10][dane_klucza]
    [adres:11][dane_klucza]
    [adres:12][dodatkowe_dane]
    {...}


    No to tu masz odpowiedz :D

    Pozdro!
  • #77 5323703
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Kodem pochwalę się wieczorem.
    W tej chwili wróciłem z roboty i mam chwilowo dosyć :D
    Cały dzień spędziłem w pełnym słońcu.

    ...powoli czuję, jak mi się skóra na plecach ściąga :|


    Pozdrawiam

    Dodano po 2 [godziny] 33 [minuty]:

    Coś mi nie chce przejść :(

    Chcę zrobić SUB, w którym będzie liczone, który numer komórki ( w epromie) jest wolny.

    
    Sub Wolna_komorka()
    
       W_komorka = 3 +(ilosc_wpisow * 5)
    
    End Sub
    


    Wartość "ilosc_wpisow" jest ustalana na samym poczatku programu. Jak kompiluję, to wyskakuje cały czas błąd:
    
    Error: 242 Source variable does not match the target variable [0|3 +(ilosc_wpisow * 5)]
    


    Czyli to jakiś błąd w zmiennych??

    Dodano po 2 [minuty]:

    ...a gdyby był potrzebny SUB, w którym odczytuje się komórki w epromie, celem odczytania ilości wpisów.

    
    Sub Ile_wpisow()
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte 1
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Zawartosc_komorki_1 , Nack
        I2cstop
      End If
    
      Waitms 50
    
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte 2
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Zawartosc_komorki_2 , Nack
        I2cstop
      End If
    
      Waitms 50
    
      If Zawartosc_komorki_1 = 1 Then
       Ilosc_wpisow = 256 + Zawartosc_komorki_2
      Else
       Ilosc_wpisow = Zawartosc_komorki_2
      End If
    
    
    End Sub
    

    z tym, że ta część kodu jest OK, bo na LCD jest wyświetlana taka wartość, jaką wpisałem pod te komórki w epromie

    Dodano po 9 [minuty]:

    aaa i jeszcze jedno. Jak zrobić, żeby zmienna nie przechowywała żadnych danych?

    Chodzi mi o to, żeby np wyczyścić tablice i inne dane z SUB programów. :)
  • Pomocny post
    #78 5324321
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Wiec tak... zamiast pisac Sub'a ktory oblicza numer wolnej komorki mozesz zrobic to w funkcji. Funkcja wykona otrzebne obliczenia i zwroci numer wolnej komorki pamieci. Choc nie wiem czy do tego jest potrzebne pisanie Sub'a lub funkcji ale jesli chcesz...

    Function wolna_komorka() As Byte
      'tutaj wykonujesz potrzebne obliczenia
    
       wolna_komorka = 'tutaj zmienna z numerem wolnej komorki
    End Function


    Czyscic tablice z danych mozesz zrobic np. tak:

    Dim Key_id(8) As Byte
    
    {...}
    
    Sub czysc_tablice()
      Local x As Byte
    
      For x = 1 To 4
        key_id(x) = 0
      Next B
    End Sub


    po wywolaniu:

    Call czysc_tablice()


    kazdy element tablicy bedzie rowny '0', czyli tablica nie bedzie zawierala zadnych danych.
  • #79 5325342
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Cytat:


    Sub Wolna_komorka()

    W_komorka = 3 +(ilosc_wpisow * 5)

    End Sub

    Ja bym spróbował rozbić na dwie linie:P
    Bascupa nie toleruje dwóch operacji w jednej linii:)
  • #80 5325353
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    hehe, tak właśnie zrobiłem. Poszło bez problemu :)
    Dziwny ten pseudo BASIC :D :P
  • #82 5325557
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Omowienia wymaga jeszcze ten fragment:

    Sub Ile_wpisow()
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte 1
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Zawartosc_komorki_1 , Nack
        I2cstop
      End If
    
      Waitms 50
    
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte 2
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Zawartosc_komorki_2 , Nack
        I2cstop
      End If
    
      Waitms 50
    
      If Zawartosc_komorki_1 = 1 Then
       Ilosc_wpisow = 256 + Zawartosc_komorki_2
      Else
       Ilosc_wpisow = Zawartosc_komorki_2
      End If
    
    End Sub


    Skoro juz masz funkcje, a wlasciwie Sub'y do zapisu i odczytu eeprom'a to nie powielaj kodu w ten sposob bo niepotrzebnie zapelniasz uC. Przerobilem troche zapis, ktory wraz z odczytem wyglada teraz tak:

    Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cwbyte Wartosc
        I2cstop
    
        Waitms 10
      End If
    End Sub
    
    Function Odczyt_z_eproma(byval Adres_komorki As Byte) As Byte
      Local odczytany_bajt As Byte
    
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte odczytany_bajt , Nack
        I2cstop
      End If
    
      Odczyt_z_eproma = odczytany_bajt
    End Function


    Przyklad uzycia:

    zmienna = Odczyt_z_eproma(adres_w_pamieci)


    I poprawiony Twoj fragment:

    Dim Zawartosc_komorki_1 As Byte , Zawartosc_komorki_2 As Byte
    
    {...}
    
    Zawartosc_komorki_1 = Odczyt_z_eproma(0)
    Zawartosc_komorki_2 = Odczyt_z_eproma(1)


    Poprawiajac ten zapis:

    Sub Wolna_komorka()
       W_komorka = 3 +(ilosc_wpisow * 5)
    End Sub


    na ten:

    Sub Wolna_komorka()
       W_komorka = Ilosc_wpisow * 5  ' oblicz (ilosc_wpisow * 5) i wynik zapisz do "w_komorka"
       W_komorka = W_komorka + 3     ' zwieksz wartosc zmiennej "w_komorka" o 3
    End Sub


    pozbedziesz sie bledu. Wynika to z niedoskonalosci Bascom'a. Nie potrafi on obliczac bardziej zlozonych dzialan tak jak np. C, wiec kazde obliczenie trzeba robic osobno.

    Ale widze, ze w trakcie pisania tego postu juz to zrobiles wiec troche sie spoznilem :D
  • #83 5325841
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    No...
    program WSTĘPNIE działa.
    NIE odnajduje mi kluczy w epromie, nie poruszam się po programie tak jak bym chciał, ale to jak się wyśpię :P

    Oto cały kod programu:
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.6 , Rs = Portb.7
    Config Lcd = 16 * 1a
    
    Config Scl = Portd.0
    Config Sda = Portd.1
    
    Config Pind.6 = Input
    Config Pind.7 = Input
    Config Pinc.0 = Input
    Config Pinc.1 = Input
    Config 1wire = Portd.5
    
    S1 Alias Pind.6
    S2 Alias Pind.7
    S3 Alias Pinc.0
    S4 Alias Pinc.1
    
    Set Portd.6
    Set Portd.7
    Set Portc.0
    Set Portc.1
    
    
    Const Adres_zapisu = 160
    Const Adres_odczytu = 161
    
    '*****************************************************************************
    
    Declare Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
    Declare Function Odczyt_z_eproma(byval Adres_komorki As Byte) As Byte
    Declare Sub Id_klucza()
    Declare Sub Ile_wpisow()
    Declare Sub Szukaj_id()
    Declare Sub Dodatkowe_info(byval Adres_kom_dodatkowe_info As Byte)
    
    
    
    Dim Key_id(8) As Byte
    Dim A As Byte
    Dim Adres_wr As Byte
    Dim Ilosc_wpisow As Integer
    Dim Znalazl As Byte
    Dim Id(4) As Byte
    
    
    Cursor Off
    
    Cls
    Lcd "START PROGRAMU"
    Wait 2
    Cls
    Lcd "Wpisy - "
    Call Ile_wpisow()
    Lcd Ilosc_wpisow
    Wait 2
    
    Do
    
      Call Id_klucza()
    
      If S2 = 0 Then                                            'ZAPISZ / SZUKAJ
        Waitms 25
    
        If S2 = 0 Then
    
          Cls
          Lcd "Szukam..."
          Waitms 500
          Call Szukaj_id()
    
        End If
      End If
    Loop
    
    End
    
    '***********************-= PODPROGRAMY =-*************************
    
    Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cwbyte Wartosc
        I2cstop
    
        Waitms 10
      End If
    End Sub
    
    Function Odczyt_z_eproma(byval Adres_komorki As Byte) As Byte
    
    'PRZYKLAD WYKORZYSTANIA:
    'zmienna = Odczyt_z_eproma(adres_w_pamieci)
    
      Local Odczytany_bajt As Byte
    
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Odczytany_bajt , Nack
        I2cstop
      End If
    
      Odczyt_z_eproma = Odczytany_bajt
    End Function
    
    Sub Ile_wpisow()
    
       Local Zawartosc_komorki_1 As Byte , Zawartosc_komorki_2 As Byte
    
       Zawartosc_komorki_1 = Odczyt_z_eproma(0)
       Zawartosc_komorki_2 = Odczyt_z_eproma(1)
    
      If Zawartosc_komorki_1 = 1 Then
       Ilosc_wpisow = 256 + Zawartosc_komorki_2
      Else
       Ilosc_wpisow = Zawartosc_komorki_2
      End If
    
    
    End Sub
    
    Sub Id_klucza()
    
       Local Temp_b As Byte
    
       Reset Portd.5
       Waitms 25
       1wreset
       Set Portd.5
       Waitms 25
    
       If Err = 0 Then
    
          Key_id(1) = 1wsearchfirst()
    
          If Key_id(8) = Crc8(key_id(1) , 7) Then
             Cls
             Lcd "ID: "
    
             For Temp_b = 1 To 4
                Lcd Hex(key_id(temp_b))
             Next Temp_b
    
          End If
    
       Waitms 100
       Else
          Cls
          Lcd "Brak Pastylki"
          Waitms 100
       End If
    End Sub
    
    Sub Szukaj_id()
    
       Local Temp_a As Byte
       Local Temp_b As Byte
       Local Temp_c As Byte
       Local Temp_d As Byte
       Local Temp_e As Byte
       Local Temp_f As Byte
       Local Wolna_komorka As Byte
    
    
    
       Call Ile_wpisow()
       'Ilosc_wpisow
    
    
       Znalazl = 0
       Adres_wr = 2
    
       For Temp_d = 0 To Ilosc_wpisow
          For Temp_c = 1 To 4
    
             Id(temp_c) = Odczyt_z_eproma(adres_wr)
    
             Incr Adres_wr
    
          Next Temp_c
    
          Incr Adres_wr                                         
    
          If Key_id(1) = Id(1) Then
             If Key_id(2) = Id(2) Then
                If Key_id(3) = Id(3) Then
                   If Key_id(4) = Id(4) Then
    
                      Znalazl = 1
    
                      Cls
                      Lcd "jest: ";
                      For Temp_b = 1 To 4
                         Lcd Hex(key_id(temp_b))
                      Next Temp_b
    
                      Wait 1
    
                   End If
                End If
             End If
          End If
    
       Next Temp_d
    
       If Znalazl = 0 Then
    
          Cls
          Lcd "Nie znalazlem"
          Waitms 500
    
          Call Ile_wpisow
    
          Wolna_komorka = Ilosc_wpisow * 5
          Wolna_komorka = Wolna_komorka + 3
    
          For Temp_e = 1 To 4
    
             Call Zapis_do_eproma(wolna_komorka , Key_id(temp_e))
             Incr Wolna_komorka
    
          Next Temp_e
    
          Temp_f = Ilosc_wpisow
          Temp_f = Temp_f + 1
          Call Zapis_do_eproma(1 , Temp_f)
    
          'DODAĆ PRZEŁADOWANIE $01 GDY OSIĄGNIE 255
    
          Cls
          Lcd "Dodano"
          Waitms 500
    
          Call Dodatkowe_info(adres_wr)
    
       Else
    
          'ZNALEZIONO, Odczyt wartosci podpietej pod klucz
          Call Dodatkowe_info(adres_wr)
       End If
    
    End Sub
    
    Sub Dodatkowe_info(byval Adres_kom_dodatkowe_info As Byte)
    
       Local Adres_info As Byte
    
       Adres_info = Odczyt_z_eproma(adres_kom_dodatkowe_info)
    
       Do
    
          Cls
          Lcd "PUNKTY: ";
          Lcd Adres_info
          Waitms 500
    
    
          If S1 = 0 Then                                        'ANULUJ
             Waitms 25
    
             If S1 = 0 Then
    
               Goto Edycja_anuluj
    
             End If
    
          End If
    
          If S2 = 0 Then                                        'ZAPISZ
             Waitms 25
    
             If S2 = 0 Then
    
                Goto Edycja_zapisz
    
             End If
    
          End If
    
          If S3 = 0 Then                                        'PLUS
             Waitms 25
    
             If S3 = 0 Then
    
                Incr Adres_info
    
             End If
    
          End If
    
          If S4 = 0 Then                                        'MINUS
             Waitms 25
    
             If S4 = 0 Then
    
                Decr Adres_info
    
             End If
    
          End If
       Loop
    
       Edycja_zapisz:
    
          Call Zapis_do_eproma(adres_kom_dodatkowe_info , Adres_info)
    
       Edycja_anuluj:
    
    End Sub
    '*****************************************************************
    


    :)
    ...pozdrawiam tych, którzy właśnie się budzą :D
  • Pomocny post
    #84 5326391
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Wyszukiwanie ID klucza w pamieci eeprom mozesz rozwiazac np. w ten sposob: odczytane ID klucza [aktualnie przylozonego do czytnika], porownujesz w petli, ktora jest wykonywana tyle razy, ile masz zapisane w zmiennej "ilosc_kluczy". Czyli w owej petli odczytujesz klucz po kluczu z eeprom'u i porownujesz z ID wlasnie odczytanym. Jesli klucz znaleziono to osoba ma uprawnienie zeby np. wejsc do budynku, natomiast jesli klucz nie zostal znaleziony to wyswietlasz komunikat o braku dostepu.
    Dodawanie kluczy robisz np. po wcisnieciu przycisku i np. przylozeniu klucza "master" - wg uznania. Ale tutaj rowniez podczas dodawiania musisz sprawdzac wszystkie klucze z pamieci eeprom, zeby nie dublowac ID klucza w eeprom'ie bo niepotrzebnie bedziesz tracil cenne miejsce.

    Jak cos nie jest jasne to pisz...
  • #85 5326792
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Jasne!!

    nie potrzebnie wydziwiałem z czymś takim:

    
    If Key_id(1) = Id(1) Then
             If Key_id(2) = Id(2) Then
                If Key_id(3) = Id(3) Then
                   If Key_id(4) = Id(4) Then
    
                      Znalazl = 1
    
                      Cls
                      Lcd "jest: ";
                      For Temp_b = 1 To 4
                         Lcd Hex(key_id(temp_b))
                      Next Temp_b
    
                      Wait 1
    
                   End If
                End If
             End If
          End If 
    


    tablica i tak juz jest zadeklarowana, zrobie to w jednej petli i bedzie GIT !!

    Mozna normalnie porównywać tablice??
    
    if key_id(4) = id(4) then
        'DOSTĘP OK
    else
        'BRAK DOSTĘPU
    end if
    


    :D
  • #86 5326933
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Oczywiscie, ze mozesz to zrobic w ten sposob:

    if key_id(4) = id(4) then
        'DOSTĘP OK
    else
        'BRAK DOSTĘPU
    end if


    ale wtedy porownujesz tylko czwarty element obu tablic, a nie cala tablice, choc pewnie chciales tu tylko wstawic przyklad... :D
    Napisalem prosta funkce [bez parametrow]:

    Dim D As Byte
    
    {...}
    
    Function porownaj_klucze() As Byte
      Local Ilosc_bajtow_klucza_ok As Byte
    
      Ilosc_bajtow_klucza_ok = 0
    
      For D = 1 To 4
        if key_id(D) = id(D) then
          Incr Ilosc_bajtow_klucza_ok
        End If
      Next D
    
      Porownaj_klucze = Ilosc_bajtow_klucza_ok
    End Function


    Jesli oba klucze sa identyczne funkcja zwraca wartosc '4', jesli klucze sa rozne wartosc zwracana jest <> od '4'.
    Przyklad uzycia wraz z odczytem i sprawdzaniem wszystkich kluczy z eeprom'a:

    'odczytaj klucz przylozony do czytnika
    
    'petla od 1 do ilosc_kluczy
    'w petli:
    
    ' odczytaj ID klucza z pamieci eeprom
    
    ' if porownaj_klucze() = 4 then
    '   klucz zgadza sie ze wzorcem z pamieci eeprom
    '   mozesz w tym miejscu np. ustawic flage i pozniej w programie dowolnie to wykorzystac
    
    '   Exit For 'mozesz rowniez dodac wyjscie z petli. Bo po co sprawdzac dalej, jesli juz znalezlismy nasz klucz w pamieci
    ' End If
    
    'tutaj dalsze dzialanie programu np. wyswietlenie "klucz poprawny" / "klucz odrzucony!"


    tak by to moglo wygladac wg mnie 8)
  • #87 5329266
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    HEH...

    Noc jest chyba najlepszym czasem, na nadrobienie czasu straconego w dzień :D

    Posiedziałem i wysiedziałem. Oto gotowy program. Działa dokładnie tak, jak chcę:

    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.6 , Rs = Portb.7
    Config Lcd = 16 * 1a
    
    Config Scl = Portd.0
    Config Sda = Portd.1
    
    Config Pind.6 = Input
    Config Pind.7 = Input
    Config Pinc.0 = Input
    Config Pinc.1 = Input
    Config 1wire = Portd.5
    
    S1 Alias Pind.6                                             'Anuluj
    S2 Alias Pind.7                                             'Zapisz
    S3 Alias Pinc.0                                             'PLUS
    S4 Alias Pinc.1                                             'MINUS
    
    Set Portd.6
    Set Portd.7
    Set Portc.0
    Set Portc.1
    
    
    Const Adres_zapisu = 160
    Const Adres_odczytu = 161
    
    '*****************************************************************************
    
    Declare Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
    Declare Function Odczyt_z_eproma(byval Adres_komorki As Byte) As Byte
    Declare Sub Dodatkowe_info(byval Adres_kom_dodatkowe_info As Byte)
    Declare Function Porownaj_klucze() As Byte
    Declare Sub Id_klucza()
    Declare Sub Szukaj_id()
    
    
    Dim Key_id(8) As Byte
    Dim A As Byte
    Dim Temp_x As Byte
    Dim Adres_wr As Byte
    Dim Id(4) As Byte
    
    Cursor Off
    
    Cls
    Lcd "START PROGRAMU"
    Wait 2
    Cls
    Lcd "Wpisy - "
    Lcd Odczyt_z_eproma(2)
    
    Wait 1
    
    Do
    
      Call Id_klucza()
    
    Loop
    
    End
    
    '***********************-= PODPROGRAMY =-*************************
    
    Sub Zapis_do_eproma(byval Adres_komorki As Byte , Byval Wartosc As Byte)
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cwbyte Wartosc
        I2cstop
    
        Waitms 10
      End If
    End Sub
    
    '*************************************************************
    
    Function Odczyt_z_eproma(byval Adres_komorki As Byte) As Byte
    
      Local Odczytany_bajt As Byte
    
      I2cstart
      I2cwbyte Adres_zapisu
    
      If Err = 0 Then
        I2cwbyte Adres_komorki
        I2cstart
        I2cwbyte Adres_odczytu
        I2crbyte Odczytany_bajt , Nack
        I2cstop
      End If
    
      Odczyt_z_eproma = Odczytany_bajt
    End Function
    
    '*************************************************************
    
    Sub Id_klucza()
    
       Local Temp_b As Byte
    
       Reset Portd.5
       Waitms 25
       1wreset
       Set Portd.5
       Waitms 25
    
       If Err = 0 Then
    
          1wwrite &H33
    
          Key_id(1) = 1wread(8)
    
          If Key_id(8) = Crc8(key_id(1) , 7) Then
             Cls
             Lcd "ID: "
    
             For Temp_b = 1 To 4
                Lcd Hex(key_id(temp_b))
             Next Temp_b
    
             Wait 1
    
          End If
    
          If S2 = 0 Then                                        'ZAPISZ
             Waitms 25
    
             If S2 = 0 Then
    
                Call Szukaj_id()
    
             End If
          End If
       Else
          Cls
          Lcd "Brak Pastylki"
          Waitms 100
       End If
    End Sub
    
    '*************************************************************
    
    Function Porownaj_klucze() As Byte
    
      Local Ilosc_bajtow_klucza_ok As Byte
    
      Ilosc_bajtow_klucza_ok = 0
    
      For Temp_x = 1 To 4
    
       Cls
       Lcd Key_id(temp_x)
       Lcd " - "
       Lcd Id(temp_x)
       Waitms 500
    
       If Key_id(temp_x) = Id(temp_x) Then
          Incr Ilosc_bajtow_klucza_ok
       End If
    
      Next Temp_x
    
      Porownaj_klucze = Ilosc_bajtow_klucza_ok
    
    End Function
    
    '*************************************************************
    
    Sub Szukaj_id()
    
       Local Temp_a As Byte
       Local Temp_c As Byte
       Local Temp_d As Byte
       Local Temp_e As Byte
       Local Temp_f As Byte
       Local Wolna_komorka As Byte
       Local Znalazl As Byte
       Local Ilosc_wpisow As Byte
    
       Znalazl = 0
       Adres_wr = 3
    
       For Temp_d = 1 To Odczyt_z_eproma(2)
    
          For Temp_c = 1 To 4
    
             Id(temp_c) = Odczyt_z_eproma(adres_wr)
             Incr Adres_wr
    
          Next Temp_c
    
          Incr Adres_wr
    
          If Porownaj_klucze() = 4 Then
    
             Znalazl = 1
    
             Exit For
    
          End If
    
       Next Temp_d
    
       If Znalazl = 0 Then
    
          Cls
          Lcd "Nie znalazlem"
          Wait 1
    
          Ilosc_wpisow = Odczyt_z_eproma(2)
    
          Wolna_komorka = Ilosc_wpisow * 5
          Wolna_komorka = Wolna_komorka + 3
    
          For Temp_e = 1 To 4
    
             Call Zapis_do_eproma(wolna_komorka , Key_id(temp_e))
             Incr Wolna_komorka
    
          Next Temp_e
    
          Temp_f = Ilosc_wpisow
          Temp_f = Temp_f + 1
          Call Zapis_do_eproma(2 , Temp_f)
    
          Cls
          Lcd "Dodano"
          Wait 1
    
          Call Dodatkowe_info(adres_wr)
    
       Else
    
          Decr Adres_wr
    
          Cls
          Lcd "ZNALEZIONO"
          Wait 1
    
          Call Dodatkowe_info(adres_wr)
       End If
    
    End Sub
    
    '*************************************************************
    
    Sub Dodatkowe_info(byval Adres_kom_dodatkowe_info As Byte)
    
       Local Adres_info As Byte
       Local Temp_b As Byte
    
       Adres_info = Odczyt_z_eproma(adres_kom_dodatkowe_info)
    
       Do
    
          Cls
          Lcd "PUNKTY: ";
          Lcd Adres_info
          Waitms 500
    
    
          If S1 = 0 Then                                        'ANULUJ
             Waitms 25
    
             If S1 = 0 Then
    
               Goto Edycja_anuluj
    
             End If
    
          End If
    
          If S2 = 0 Then                                        'ZAPISZ
             Waitms 25
    
             If S2 = 0 Then
    
                Goto Edycja_zapisz
    
             End If
    
          End If
    
          If S3 = 0 Then                                        'PLUS
             Waitms 25
    
             If S3 = 0 Then
    
                Incr Adres_info
    
             End If
    
          End If
    
          If S4 = 0 Then                                        'MINUS
             Waitms 25
    
             If S4 = 0 Then
    
                Decr Adres_info
    
             End If
    
          End If
       Loop
    
       Edycja_zapisz:
    
          Call Zapis_do_eproma(adres_kom_dodatkowe_info , Adres_info)
    
          Cls
          Lcd "SaVe: ";
    
          For Temp_b = 1 To 4
    
             Lcd Hex(key_id(temp_b))
             Next Temp_b
    
          Wait 1
    
       Edycja_anuluj:
    
    End Sub
    '*****************************************************************
    


    Będę musiał go jeszcze przetestować jak kupię z 200x DS1990A. Wolę nie wiedzieć co się zacznie znowu krzaczyć, gdy niektóre wartości takie jak "Wolna_komorka" przekroczą zadeklarowany BYTE :) A na pewno to zrobią gdy licznik zapisanych IDów przekroczy wartość 51 :)

    (52*5)+3=263 :) Odpocznę chwilę od tego programu i dorobię tą funkcję, która po przepełnieniu $01 zwiększa wartość o 1 w $00 :)
    Poza tym, trzeba tylko oczyścić kod z tymczasowych wpisów (np wyświetlanie danych na LCD -żebym wiedział co się dzieje :D )

    no i pewnie kupię LCD 2x16. Wtedy lekko przerobię kod tak, żeby po przyłożeniu pastylki, pokazał jej SN, poinformował, że szuka jej w pamięci i jeżeli tam jest, żeby wyświetlił od razu dodatkowe INFO na temat tego SNa.

    Na tym etapie DZIĘKUJĘ Wam bardzo, koledzy JmL(TM) i Balu. Bez was by mi nie wyszło :)
  • #88 5333513
    JmL(TM)
    Poziom 24  
    Posty: 804
    Pomógł: 44
    Ocena: 12
    Nie ma sprawy. Polecam sie na przyszlosc! :D
    Najwazniejsze, ze osiagnales zamierzony cel. Dodanie kodu do obslugi wiekszej ilosci kluczy to naprawde juz przyslowiowa "bulka z maslem".

    A jesli masz zamiar uzyc az tak sporej liczby kluczy to zastanawiam sie czy nie lepiej byloby zmienic troche ten projekt lub uwzglednic to w nastepnym, mianowicie uzycie kard RFiD unique. Sa w podobnej cenie, a moze nawet tansze od kluczy Dallas'a. Na allegro za okolo 30zl mozesz kupic gotowy modul, ktory odczytuje karte i wysyla po RS'ie jej numer. Zasade dodawania, zapisu i sprawdzania juz znasz wiec bedzie to latwe do zrobienia. W kazdym razie wybor wciaz nalezy do Ciebie...

    Pozdrawiam!
  • #89 5333749
    monty_p
    Poziom 18  
    Posty: 377
    Pomógł: 1
    Ocena: 26
    Heh... Gdybym znalazł wcześniej RFiD to bym to zrobił :D Bo na takiej karcie można nawet wizytówkę strzelić a na breloczku z dallasem to najwyżej klucz można powiesić :)

    Dodano po 21 [minuty]:

    ...w takim razie jeszcze jedno pytanie:

    Jeżeli chcę zapisać komórkę nr 1024 to piszę:
    Zapis_do_eproma(1024 , Wartosc)

    ????

    ...to, że to integer a nie byte wiem :)
    Tylko czy takie adresowanie jest poprawne?

Podsumowanie tematu

✨ Dyskusja dotyczyła implementacji zapisu i odczytu danych z pamięci EEPROM serii 24Cxx (głównie 24C16 i 24C64) za pomocą mikrokontrolera Atmega8 (oraz później Atmega32) programowanego w BASCOM AVR. Autor początkowo planował zapis na kartę SD/MMC, ale zrezygnował na rzecz pamięci szeregowej I2C. Omówiono kwestie podłączenia pamięci do magistrali I2C, adresowania pamięci (w tym różnice między 24C16 a większymi 24C32-512), oraz organizacji danych w pamięci EEPROM, gdzie każdy rekord składa się z 4 bajtów numeru seryjnego klucza Dallas DS1990A oraz dodatkowego bajtu informacji. Przedstawiono przykładowe fragmenty kodu w BASCOM do zapisu i odczytu bajtów, obsługi magistrali I2C, oraz porównywania odczytanych kluczy z zapisanymi w pamięci. Poruszono też temat ograniczeń BASCOMa, zalecając naukę C i asemblera dla bardziej rozbudowanych projektów. W dyskusji pojawiły się wskazówki dotyczące adresowania pamięci 24C16, wykorzystania funkcji High() i Low() do rozbicia adresu 16-bitowego na bajty, oraz organizacji pamięci z licznikiem ilości zapisanych rekordów. Autor uzyskał działający program, który odczytuje numer seryjny z klucza Dallas, wyszukuje go w pamięci EEPROM i w razie braku zapisuje nowy rekord, wyświetlając ilość zapisanych kluczy na LCD. Poruszono również kwestie sprzętowe, takie jak zasilanie pamięci 3,3V, stabilizatory AMS1117 i LM317, oraz programatory AVR (w tym STK500). Dyskusja zakończyła się sukcesem autora, który podziękował za pomoc i potwierdził spełnienie założeń projektu.
Wygenerowane przez model językowy.
REKLAMA