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

Dlaczego AT24C64 nie zapisuje poprawnie danych w Bascom?

jacynka84 29 Gru 2006 09:27 7455 18
REKLAMA
  • #1 3381650
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Witajcie , napisałem taki krótki kod aby sprawidzić czy moja kostka
    AT24C64 w ogóle działa , no i nie wiem czy coś źle napisałem
    (prawie na pewno), czy raczej jest coś nie tak z nią ,ew. ze mną.

    Zmienna eep zawiera liczbę - np. 233
    zapisuję ją do zewn. eepromu , potem odczytuję , ale niezależnie od zmiennej ,wyświetla 255 lub 0 - powiedzcie co jest nie tak.
    Schemat podłączenia standardowy.

      $regfile = "m32def.dat"
    $crystal = 11059200
    $lib "i2c.lbx"
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
      Config Adc = Single , Prescaler = Auto , Reference = Internal
      Start Adc
    
    Config Sda = Portc.1
    Config Scl = Portc.0
    Config I2cdelay = 100
    I2cinit
    
    Dim Eep As Byte
    
    Const Adrw = 416
    Const Adrr = 417
    
    Do
    
    Eep = 233
    
    I2cstart
    I2cwbyte Adrw
    I2cwbyte 1
    I2cwbyte Eep
    I2cstop
    
    Waitms 30
    
    I2cstart
    I2cwbyte Adrw
    I2cwbyte 1
    I2cstart
    I2cwbyte Adrr
    I2crbyte Eep , Nack
    I2cstop
    
       Cls
       Cursor Off
       Lcd "" ; Eep
    
    Waitms 100
    
    Loop  
  • REKLAMA
  • #2 3381747
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    witam
    juz dawno bascoma nie meczylem ale cos mi sie wydaje ze te adresy sa nie takie jak powinny byc
    Const Adrw = 416
    Const Adrr = 417
    Radze sie dobrze dokumentacji przyjrzeć. No i jeszcze sda i scl powinny byc rezystorami podciagniete do +, nalezy o tym pamietac

    tu jest dokumentacja http://www.atmel.com/atmel/acrobat/doc0336.pdf
  • #3 3381854
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    adres do zapisu
    adres do odczytu ,
    mam jeszcze do wyboru 160:161 ,ponadto podawałem równierz "ręcznie" te cyfry, są podciągnięte do 5V.
  • #4 3381874
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    jak na moj gust to powinno byc 160 i 161(no oczywiscie gdy nogi adresowe sa odpowiednio podlaczone-w tym przypadku chyba wszystkie 3 do masy). nie papmietam tylko czy dla kosci pamieci nie nalezalo jeszcze podac gdzie te dane sie maja w pamieci zapisac. Robilem kiedys cos podobnego to sprawdze ale to dopiero wieczorkiem jak w domu bede
    pozdrawiam
  • #5 3381945
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Spoko. dawałem też 160 i 161 ale to samo jest.
    zrobiłem skan tych adresów czy coś i wyszło że 160 161 i 416 417 .
    A jest jakas metoda programowa czy ta kostka pamięci jest widoczna dla uP ?
  • REKLAMA
  • #6 3382001
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    w bascomie to niestety tylko mozna cos stwierdzic skanujac adresy. Ale jak sie taki 160 odezwie tzn ze jest. jak dobrze pamietam jesli nie ma odbiornika na i2c to zwraca w kardej odczytanej liczbie 255. A jesli kosc sie odezwie i bedzie czysta to zwroci zero.
    A 416=160+256 wiec stad taka dziwna wartosc adresu
  • #7 3382022
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    A da się zapisywać ten zewn. eeprom instrukcjami Readeeprom i Writeeeprom ? Bo to chyba normalnie się do wew. uP używa? Cały czas szukam różnych rzeczy na ten temat i wszystko wygląda że mam dobrze - a nie jest.
    uP Zapisuje te zmienną do eppromu , potem mu wbijam ten sam kod lecz bez zapisywania zmiennej na nowo - tylko odczytanie , i wychodzi na to że w tej pamięci tej danej już nie ma...a powinna być ,prawda?
      $regfile = "m32def.dat"
    $crystal = 11059200
    $lib "i2c.lbx"
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
      Config Adc = Single , Prescaler = Auto , Reference = Internal
      Start Adc
    
    Config Sda = Portc.1
    Config Scl = Portc.0
    Config I2cdelay = 10
    I2cinit
    
    Config Portc = Output
            Portc = &B11111111
    
    Dim Eep As Byte
    
    Const Adrw = 160
    Const Adrr = 161
    
    Do
    
    
    Eep = 10
    
    I2cstart
    I2cwbyte Adrw
    I2cwbyte 1
    I2cwbyte Eep
    I2cstop
    
    Waitms 30
    
    I2cstart
    I2cwbyte Adrw
    I2cwbyte 1
    I2cstart
    I2cwbyte Adrr
    I2crbyte Eep
    I2cstop
    
    Waitms 100
    
    Cls
       Cursor Off
       Lcd "" ; Eep
    
    Waitms 100
    
    Loop  
    ten kod działa , ale tu zapis jest i odczyt.
  • #8 3382364
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    teraz to nie rozumiem, ten ostatni kod dziala czy tez nie? czy poprostu dziala u kogos innego? widze ze tu sa troche inne parametry do i2c . Jak pamietam to ja wogole nie zmienialem parametrow tansmisji tylko uzywalem domyslych i dzialalo. A tak poza tym nie ma zadnych problemow z programem? widze ze dziala w kolko troche szybko jak do odczytu danych z wyswietlacza.
  • #9 3383365
    szymtro
    Poziom 30  
    Posty: 1421
    Pomógł: 101
    Ocena: 59
    To jest pamieć c64 a więc adresowana dwoma bajtami a ty masz tam tylko jeden (i2cwbyte 1) a potrzeba zrobić dwa coś jak to:
    i2cstart
    i2cwbyte 160 '(lub 161 to jest adres sprzętowy na magistrali i2c)
    i2cwbyte &h00 'to jest msb adresu tzw softwareowego w pamieci
    i2cwbyte &h00 ' a to jest lsb tego co powyżej
    i2cwbyte zmienna_test ' a to jest twoja dana do zapisania
    i2cstop
    
    i2cstart
    i2cwbyte 160 '(albo 161 - zawsze mi sie myliło)
    i2cwbyte &h00 'msb adresu w pamieci
    i2cwbyte &h00  'lsb adresu w pamieci
    i2cstart 'repeated start - tak mozna
    i2cwbyte 161 (lub 160 - zawsze mis ie myliło = adres do odczytu)
    i2crbyte zmienna_inna 'twoja zmienna odtworzona
    i2cstop
  • #10 3383376
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Znaczy jak byś ty to zrobił ?
    Bo mi chodzi o to aby te zapisane dane nie znikały z eepromu po wyłączeniu zasilania oraz po Zmianie kodu uP, a wygląda na to że właśnie znikają.
    Tzn .
    Zapisuję jakąś zmienną Byte do eepromu kodem do uP z zapisem , potem zapisuję nowy Kod do uP z samą procedurą odczytu zawartości eepromu , ale wtedy już nie ma tej zawartości. dla czego tak sie dzieje ?
  • REKLAMA
  • #11 3383701
    szymtro
    Poziom 30  
    Posty: 1421
    Pomógł: 101
    Ocena: 59
    Poczekaj
    Z wypowiedzi zrozumiałem że chcesz zapisywac jakieś zmienne w pamieci zewnętrznej podłaczonej po i2c? czy sie gdzieś pomyliłem/nie doczytałem?

    Co do tej wewnętrznej pamieci eeprom w np tiny2313 czy M8 to trzeba sobie zmienić/zaprogramować odpowiedni fusebit - jest taki, eesave sie nazywa.
    Jak go nie ma to eeprom sie kasuje po komendzie flash erase.
    -----------------------------------------------------------------------------------------
    No to napisz jak zadziałało to co wkleiłem powyżej. Trzeba tam dodać ack i nack w odpowiednich miejscach.
  • #12 3383992
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Cytat:
    Z wypowiedzi zrozumiałem że chcesz zapisywac jakieś zmienne w pamieci zewnętrznej podłaczonej po i2c? czy sie gdzieś pomyliłem/nie doczytałem?

    Dokładnie to. Zmienne mają tam być Niezależnie od kodu w uP.
    Mają być wyświetlane poprzez odczyt zmiennej sięgając do pamięci zewnętrznej.
  • #13 3384298
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    Wlasnie kolega szymtro zwrocil slusznie uwage ze to jest duza pamiec o wiekszym adresie od standardowego. adres 160 do zapisu a 161 do odczytu. Daj znac jak proby z takim zapisem
  • #14 3385724
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Ale co z tą niezależnością od kodu - jak je odczytać z pamięci po zmianie kodu w uP?
  • #15 3386680
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    Ale w czym jest problem? Przeciez z tego co piszesz uzywasz pamieci szeregowej eeprom. Zeby do tej pamieci cos zapisac czy odczytac uzywasz jakiegos uP (nie podales jakiego) i magistrali i2c wiec podczas zmiany kodu programujesz tylko pamiec tego uP a nie eeprom. Dane poprawnie wgrane do pamieci eeprom nie maja prawa zniknac nawet jak ta pamiec z podstawki wyjmiesz. Moze dla jasnosci tematu dodaj schemat zeby wszystko bylo bardziej przejrzyste
  • #16 3387228
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    A jaki może być schemat - rezystory podciągające do + od SCL i SDA , i na Piny oznaczone SCL i SDA .
    Atmega32.

    Problem wygląda tak że -
    Daję kod z zapisem do eepromu zmiennej , (właśnie teraz np. zmienna jest w epp.
    Potem kasuję kod z uP i daję kod z odczytem z eepromu - i NIC - wyświetla 0 albo 255.
  • #17 3387487
    szymtro
    Poziom 30  
    Posty: 1421
    Pomógł: 101
    Ocena: 59
    Jeżeli masz prawidłowo zapis do i2c eepromu a nie jakieś tam przypadek że działa to masz ewidentnie źle napisany program.
    Skoro do tego pokazuje ci albo 0 albo 255 to już napewno masz coś nie tak. Skąd wiesz że ci sie dobrze zapisuje/odczytuje? sprawdzałeś to jakimś programatorem albo innym układem?

    Tak jak napisałem już wczesniej - jezeli używasz tego co podałeś na samym poczatku to napewno ci nie zapisze do pamięci a przy najmniej nie do tej pamieci.
    Kod do zapisu(przykład):
    dim ala as byte
    ala=&h97
    cls
    i2cstart
    i2cwbyte 160
    i2cwbyte &h00' soft msb address (00.1F)
    i2cwbyte &h00 'soft lsb address (00..FF)
    i2cwbyte ala
    i2cstop
    lcdhex "Zapis: ";ala
    do:loop

    Kod do odczytu(przykład):
    dim ela as byte
    ela=&h00
    cls
    i2cstart
    i2cwbyte 160
    i2cwbyte &h00 'soft msb address (00..1F)
    i2cwbyte &h00 'soft lsb address (00..FF)
    i2cstart
    i2cwbyte 161
    i2crbyte ela,nack
    i2cstop
    lcdhex "Odczyt: ";ela
    do:loop

    Bez urazy ale weź najpierw jakąś najmniejszą pamięc (24c02) i poćwicz na niej przykłądy MOL z edw - jak dasz radę z tym to pamieci z serii c32 i większe przestana być dla ciebie problemem(po przejżeniu datasheet oczywiscie)
  • REKLAMA
  • #18 3387531
    Yca
    Poziom 20  
    Posty: 541
    Pomógł: 9
    Ocena: 28
    1. jesli wyswietla "0 albo 255" to musi byc jakis probleb natury sprzetowej lub zlego adresowania. Z zasady powinien wyswietlac 0 jesli pamiec pusta i odpowiada, a 255 da gdyby nie bylo pamieci.
    2.Nie masz innego ukladu z magistrala i2c zeby sprawdzic czy sama komunikacja od strony procesora i skladnia funkcji jest ok?
    3. nie prosciej by bylo juz napisac jeden kod, do tego jakies przyciski zeby robic zapis odczyt bez przeprogramowywania uP? tutaj jest kawalek mojego programu-procedura zapisu i odczytu, ktore dziala z pamiecia 24c04
     Zapisz:
     I2cstart
     I2cwbyte 168
     I2cwbyte 1
     For I = 1 To 15
     I2cwbyte T(i)
     Next                                                       
     I2cstop
     Return
    
     Czytaj:
     I2cstart
     I2cwbyte 168
     I2cwbyte 1
     I2cstart
     I2cwbyte 169
     For I = 1 To 14
     I2crbyte T(i) , Ack
     Next
     I2crbyte T(15) , Nack
     I2cstop
     Return

    procedurki te obsluguja kolejno 15 bajtow pamieci tak do zapisu jak i do odczytu
    4.Dodam jeszcze ze ja pracowalem na Bascom 8051 a z tego co wiem avr bedzie sie troche roznil
  • #19 3399879
    jacynka84
    Poziom 26  
    Posty: 1170
    Pomógł: 13
    Ocena: 29
    Mniejsza o to jak są wywoływane procedury ,
    Ten kod działa , ciekawe że nie bardzo wiem dzlaczego
    wcześniej nie działał - zmieniłem tylko I2cdelay z 10 na 5

     
    $regfile = "m32def.dat"
    $crystal = 11059200
    $lib "i2c.lbx"
    $lib "i2c_twi.lbx"
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
    Config Scl = Portc.0
    Config Sda = Portc.1
    Config I2cdelay = 10
    I2cinit
    
    Dim Zps As Byte
    Dim Odc As Byte
    Zps = 12
    
     Do
    
     Cls
     Lcd "Zapis"                                                '
     Wait 1
    
    Zps = 12
    
    I2cinit
    I2cstart
    I2cwbyte 160
    I2cwbyte 1
    I2cwbyte 1
    I2cwbyte Zps
    I2cstop
    
    Wait 3
    Cls
    Lcd "Waiting..."
    
    Wait 1
    
    I2cinit
    I2cstart
    I2cwbyte 160
    I2cwbyte 1
    I2cwbyte 1
    I2cwbyte 161
    I2cstart
    I2crbyte Odc , Nack
    I2cstop
    
    Waitms 30
    
    Cls
       Cursor Off
       Locate 1 , 3
       Lcd Hex(odc)
    
     Waitms 100
    
       End
       Loop
     


    Ale przy tym kodzie jasno wydaje Adresy

      $regfile = "m32def.dat"
    $crystal = 11059200
    $lib "i2c.lbx"
    $lib "i2c_twi.lbx"
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
    Config Scl = Portc.0
    Config Sda = Portc.1
    Config I2cdelay = 10
    I2cinit
    
    Dim I As Word
    
    Do
    
    
    Cls
    Lcd "Trwa odczyt:"
    Wait 1
    
    For I = 1 To 500
    
    I2cstart                                                    'warunek startu
    I2cwbyte I                                                  'wyťlij adres uk¦adu
    I2cstop                                                     'warunek stopu
    Waitms 10
    
    If Err = 0 Then
    Cls
    Lcd "Adres:" ; I
    Wait 2
    End If
    
    Next I
    
    Loop  

    teraz kominuję jak zapisać text do eepromu , i cyfry większe od 255.

Podsumowanie tematu

✨ Dyskusja dotyczy problemu z zapisem i odczytem danych w zewnętrznej pamięci EEPROM AT24C64 za pomocą Bascom i magistrali I2C na mikrokontrolerze Atmega32. Głównym problemem jest to, że zapisywane wartości (np. 233) po odczycie zwracają 0 lub 255, co wskazuje na błędne adresowanie lub nieprawidłową komunikację. Użytkownik stosował różne adresy I2C (160/161, 416/417), jednak prawidłowe dla AT24C64 są 160 (zapis) i 161 (odczyt), przy czym adresowanie pamięci wymaga podania dwubajtowego adresu wewnętrznego (MSB i LSB), a nie pojedynczego bajtu. Konieczne jest więc wysłanie dwóch bajtów adresu pamięci przed danymi. Wskazano także na konieczność stosowania rezystorów podciągających na liniach SDA i SCL do +5V. Problemy z zapisem mogą wynikać z nieprawidłowego protokołu I2C, zbyt dużego opóźnienia I2cdelay lub braku obsługi potwierdzeń (ACK/NACK). Po poprawnym zaimplementowaniu protokołu, w tym dwubajtowego adresowania i odpowiednich opóźnień, zapis i odczyt danych z AT24C64 działa poprawnie i dane pozostają w pamięci niezależnie od zmiany kodu mikrokontrolera. Zalecane jest testowanie komunikacji skanowaniem adresów I2C oraz stosowanie powtarzanego startu (repeated start) przy odczycie.
Wygenerowane przez model językowy.
REKLAMA