Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega32][Bascom] Zapis/odczyt EEPROM 24C02 I2C

Elektronik_Kraków 20 Mar 2011 21:58 5542 19
  • #1
    Elektronik_Kraków
    Level 13  
    Witam
    Chciałbym zapisywać liczby z zakresu 200 - 400 w pamięci EEPROM 24C02.
    Mam zestaw EVB4.3 i tam pamięć ma nogi A1, A2 do +5V, A0 do GND.

    Na początek chciałem ustalić, czy dobrze obliczyłem adres - korzystając z Datasheet'a - strona 11
    1 0 1 0 A2 A1 A0 R/W R/W R- 0, W -1

    1 0 1 0 1 1 0 0 odczyt 172
    1 0 1 0 1 1 0 1 zapis 173


    Czy organizacja pamięci wygląda mniej więcej tak ?
    0000 0001 0002 0003 0004 0005 0006 0007
    0008 0009 0010 0011 0012 0013 0014 0015
    czyli jeśli w kodzie programu po adresie zapisu podajemy adres komórki 1 to będzie 0001 i od niego rozpocznie się zapis ?

    Teraz do rzeczy kod - tymczasowo wyzwalam zapis i odczyt ręcznie:
    Code: basic4gl
    Log in, to see the code


    Wartość zmiennej T_min dałem na LCD.
    Odczytując zawartość EEPROM ( ręcznie lub przed pętlą Do - Loop ) otrzymuję jakieś dziwne wartości -1, -10 ( na początku, gdy nie stosowałem podziału było ciągle 255 )
    Kamery 3D Time of Flight - zastosowania w przemyśle. Darmowe szkolenie 16.12.2021r. g. 10.00 Zarejestruj się
  • #2
    asembler
    Level 32  
    Zakres 200-400 to mieci sie w 8 bitach nie wiem dlaczego zapisujesz w 2 bajtach.
  • #4
    Elektronik_Kraków
    Level 13  
    A masz inicjację I2C ?

    Fredy
    tzn chodzi Ci o:
    Code:

    '********************* Konfiguracja magistrali I2C
    Config I2cdelay = 5                                         ' domyślnie tryb Slow
    Config Sda = Portc.1
    Config Scl = Portc.0

    to mam bo robiłem już zegar z PCF8583


    asembler
    Początkowo próbowałem robić to tak:
    Code: asm
    Log in, to see the code

    wtedy miałem odczyt 255
    Dlaczego T_min i T_max, bo chciałem za jednym zamachem zapisać dwie wartości
  • #5
    Fredy
    Level 27  
    Jest taka instrukcją I2CINIT - sprawdź ją w Helpie.
    Czy masz podpięte rezystory 4K7 pod sda i scl ?

    Sprawdź jak zachowa sie pamięć jak odczytasz tylko 1 bajt, może problem polega a tym że robisz 2 zapisy i 2 odczyty od razu.
    Czy nie masz pomylonego sda i scl - częsty błąd?
  • #6
    Elektronik_Kraków
    Level 13  
    Rezystory są już dane na płytce, zresztą zegar na PCF działa bez zarzutu ( no może trochę śpieszy, ale to kwestia kondensatora przy kwarcu )

    sprawdziłem połączenia - nóżki 5 czyli SDA ( 24C02 i PCF8583 ) są podłączone do 23 nogi uC, czyli PC1-SDA. Podobnie z SCL.

    Teraz zrobiłem tak, że odczyt jest po włączeniu/resecie ( przed pętlą główna ), a zapis po wyjściu z menu ustawień. Nie wiem czy to właściwe, czy nie jest tak, że się "gryzie" odczyt z zapisem.

    Nie wiem, czemu, ale w momencie włączenia I2C ( tzn wersja bez EEPROM działa OK ), menu zaczyna głupieć i samo np. wychodzi, zanim zakończę ustawianie.

    Jest też program do przeszukiwania I2C i wykrył 160/161 ( PCF) oraz 172/173 ( 24C02 ).

    Sprawdzam tak, że wchodzę w menu i zmieniam na jakąś inna niż 255 wychodzę ( powinien być zapis). Robię reset i znowu jest 255.

    Może podam cały kod:
    Code: vb
    Log in, to see the code

    zauważyłem jeszcze błąd - brak konfiguracji PA.7, czyli ENTER/zapis. Poprawiłem, ale nic się nie zmieniło - po resecie dalej 255.
  • #7
    asembler
    Level 32  
    A czekasz aż kostka skonczy zapis do komórki?
  • #8
    Elektronik_Kraków
    Level 13  
    Tzn. nie resetuje od razu po wyjściu z menu. Czekam kilka sekund.

    Może oprócz Waitms
    Code: vb
    Log in, to see the code


    dać jeszcze drugi Waitms przy wyjściu z menu ?
    Code: vb
    Log in, to see the code
  • #9
    asembler
    Level 32  
    Raczej chodziło mi o odstep kilku mS pomiedzy zapisem do kolejnych komorek.
    Dodatkowo sprawdz czy nie przekraczasz dopuszczalnego f dla tych ukladów co jest bardzo czestym błedem, a przy szybkich procesorach typu AVR bardzo łatow przekroczyc. Tam moze byc jedna z wartosci stosowanyc 100,400kHz lub 1Mhz.
  • #10
    Elektronik_Kraków
    Level 13  
    ustawiłem I2CDelay = 10 czyli 100 KHz
    dałem też więcej ms w podprogramie zapisu

    Mógłbyś sprawdzić, czy zmienne są właściwego typu ?
    Wszędzie w przykładach zapisywana zmienna jest typu Byte, a ja używam Integer, Byte nie przepuści powyżej 255 ( czyli u mnie temp 25,5 ).

    Jak robiłem dzielenie przed zapisem i łączenie przy odczycie to wyniki były inne i czasem się zmieniały - było -1, czasem -10.
  • #11
    asembler
    Level 32  
    Wracając do sprawy tego dzielenie i łaczenia.
    Nie wystarczy odjąc 200 i liczbe zapisac w zakresie 0d 0 do 200 a przy odczecie dopiero dodac te 200?
  • #12
    Elektronik_Kraków
    Level 13  
    Mógłbyś podać przykład ?
    Czy chodzi o coś takiego?

    Code: vb
    Log in, to see the code


    Czy mógłbyś wesprzeć mnie odrobiną teorii, odpowiadając na pierwszą część mojego pierwszego pytania - odnośnie organizacji pamięci ?
    Chciałem też zrobić woltomierz na PCF8591, ale widzę, że I2C to ciężki temat.
  • Helpful post
    #13
    asembler
    Level 32  
    No coś takiego.
    A przy odczycie Tt1 = T_min + 200 i sprawa załatwiona.
  • Helpful post
    #14
    Fredy
    Level 27  
    A nie zrobiłeś tego odwrotnie:

    Const Adres_o = 172
    Const Adres_z = 173

    spróbuj zamienić ,czyli:

    Const Adres_o = 173
    Const Adres_z = 172
  • #15
    Elektronik_Kraków
    Level 13  
    Co do adresów, to na elektrodzie znalazłem, że niższy ma być do odczytu, a wyższy do zapisu. W helpie jest przykład i tam jest niższy do zapisu, wyższy do odczytu.
    Sprawdzę wieczorem.
  • #16
    Elektronik_Kraków
    Level 13  
    Zamieniłem adresy i jest OK.
    Niestety zmienna musi być typu Byte ( próba zapisu typu Integer o wartości 266- po odczycie wyświetla 5 ), czyli zostaje pomysł z dodawaniem jest konieczny, ale się sprawdza, chyba, że ktoś ma inny.
  • #17
    Fredy
    Level 27  
    Oczywiście że w tej pamięci możesz zapisywać tylko pojedyńcze bajty. Jeśli chcesz zapisać większe liczby to musisz je rozbić na bajty, zapisać a potem po odbiorze posklejać.
    W Twoim przypadku jeśli masz zakres od 200 do 400 to oczywistą rzeczą jest zapis liczby pomnijeszonej o 200 a potem dodanie 200 po odczycie.
  • #18
    Elektronik_Kraków
    Level 13  
    żeby nie zakładać nowego tematu - to mam pytanie odnośnie tego kodu, który wyżej podawałem.

    Code: vb
    Log in, to see the code


    ten kod działa ( sygnalizuje buzerem i mignięciem jednego z kolorów podświetlania ), ale po dołożeniu drugiego czujnika i sterowania drugim wyjściem, czyli dołożeniu dwóch warunków

    Code: vb
    Log in, to see the code


    już nie działa, anie dla pierwszego, ani dla drugiego czujnika - próbowałem zastąpić flagami, ale to nic nie pomogło.

    I jeszcze pytanie odnośnie EEPROM. Jesli używam jednej pamięci w rożnych układach i nie chcę, żeby się skasowała, a raczej nadpisała, to jak powinien wyglądać zapis, w przypadku, gdy w tym układzie termostatu wykorzystam 4 komórki ?
  • #19
    Fredy
    Level 27  
    Jak dokładasz drugi czujnik pod I2C to musisz inaczej go zaadresować, czyli wejścia adresowe musisz inaczej podłączyć. Wtedy każdy z nich będzie miał swój inny adres. Odczyt każdego z nich musi wiązać się najpierw z zaadresowaniem właściwego czujnika.Najprawdopodobniej w układzie wyżej masz 2 czujniki o tym samym adresie.
    Dane zapisujesz sobie jak chcesz, musisz sam zapewnić porządek.
    Bascom fanie radzi sobie z eepromem który umieszczony jest w procku, wtedy traktuje je jako zwykłe zmienne. Nie musisz się zastanawiać pod jakim adresem jest zmienna.
    Zewnętrzny eeprom musisz sam zorganizować adresowo.
  • #20
    Elektronik_Kraków
    Level 13  
    Pisząc o adresowaniu nie masz na myśli ID czujnika, bo każdy DS18B20 ma unikatowy ID. Czujniki są na jednej linii, ale odczyt jest prawidłowy. Jeśli dobrze Cię rozumiem, to chodzi o to, aby mu bardziej "doprecyzować", który czujnik ma reagować na którą temp. Co prawda myślałem, że wykona proste porównanie wartości T1 z T_max i T2 z T2_max.
    Możesz mi poradzić, jak "ugryźć" temat ? - do tej pory tylko odczytywałem temperaturę ( max z trzech sztuk DS ) i nie miałem problemu z kolejnością, każdy zawsze był wyświetlany w tym samym miejscu.

    Co od pamięci EEPROM to chodziło mi o to:
    pamięć jest 8-bitowa

    0000 0001 0002 0003 0004 0005 0006 0007
    0008 0009 0010 0011 0012 0013 0014 0015
    0016 0017 0018 0019 0020 0021 0022 0023

    zapisując:
    Code: vb
    Log in, to see the code


    cyfra 1 oznacza adres w pamięci od którego zacznie się zapis, czyli w tym przypadku ( 4 zmienne ) zapisze cztery kolejne komórki ?
    0001 0002 0003 0004
    czyli chcą nie kolidować z tymi zapisami, mogę w innym projekcie dać zapis od komórki 5 ?
    Oczywiście to może trochę niepoważne, bo taniej wyjdzie mieć kilka pamięci EEPROM.