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

Atmega8 + eeprom 24c32 + Bascom = błędy w zapisie

rj1307 01 Kwi 2010 16:30 2840 8
REKLAMA
  • #1 7907603
    rj1307
    Poziom 15  
    Witam!

    Mam problem z prawidłowym zapisem danych do pamięci 24c32. Poniższy program teoretycznie powinien zapisać dane w 9 kolejnych bajtach, adres jest zwiększany o 10. Ale tak nie jest.

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    
    Config Sda = Portc.5
    Config Scl = Portc.4
    
    Dim Dana As Integer
    Dim Dana_zapisana As Integer
    Dim Adres As Word
    Dim Adr2 As Byte
    Dim Adr3 As Byte
    Dim Starszy As Byte
    Dim Mlodszy As Byte
    Dim O1 As Byte
    Dim O2 As Byte
    Dim O3 As Byte
    Dim O4 As Byte
    Dim O5 As Byte
    Dim O6 As Byte
    Dim O7 As Byte
    
    Cursor Off
    Cls
    
    
    For Adres = 0 To 100 Step 10
      Dana_zapisana = Adres
      Mlodszy = Low(dana_zapisana)
      Starszy = High(dana_zapisana)
      Adr2 = Adres / 256
      Adr3 = Adres Mod 256
    
      I2cstart
      I2cwbyte 160
      I2cwbyte Adr2
      I2cwbyte Adr3
      I2cwbyte Mlodszy
      I2cwbyte Starszy
      I2cwbyte 1
      I2cwbyte 2
      I2cwbyte 3
      I2cwbyte 4
      I2cwbyte 5
      I2cwbyte 6
      I2cwbyte 7
      I2cstop
      Waitms 10
    Next
    
    
    Do
    
    For Adres = 0 To 100 Step 10
      Adr2 = Adres / 256
      Adr3 = Adres Mod 256
    
      I2cstart
      I2cwbyte 160
      I2cwbyte Adr2
      I2cwbyte Adr3
      I2cstart
      I2cwbyte 161
      I2crbyte Mlodszy , Ack
      I2crbyte Starszy , Ack
      I2crbyte O1 , Ack
      I2crbyte O2 , Ack
      I2crbyte O3 , Ack
      I2crbyte O4 , Ack
      I2crbyte O5 , Ack
      I2crbyte O6 , Ack
      I2crbyte O7 , Nack
      I2cstop
    
      Dana = Makeint(mlodszy , Starszy)
    
      Locate 1 , 1
      Lcd "A: " ; Adres ; " D: " ; Dana
      Locate 2 , 1
      Lcd O1 ; " " ; O2 ; " " ; O3 ; " " ; O4 ; " " ; O5 ; " " ; O6 ; " " ; O7
      Wait 1
      Cls
    Next
    
    Loop
    End




    Program zwraca następujące dane:


    
     Adres  Dana    o1   o2  o3   o4  o5   o6   o7 
    
        10    10    1    2   3    4   5    6    7 
        20    20    1    2   3    4   5    6    7 
        30    30    3    4   5    6   7    8    9    'źle jes tu
        40    40    1    2   3    4   5    6    7 
        50    50    1    2   3    4   5    6    7 
        60    60    1    2   5    6   7    8    9    'tu
        70    70    1    2   3    4   5    6    7 
        80    80    1    2   3    4   5    6    7
        90    90    1    2   3    4   96   0    98   'i tu
        100   100   1    2   3    4   5    6    7 
    


    Jak widać, źle zapisuje adresy 30,60,90. Gdzie popełniam błąd?
    .
  • REKLAMA
  • #2 7907643
    tadzik85
    Poziom 38  
    Zły operator dzielenia. Dzielisz liczny rzeczywiste. Najlepiej wykorzystaj instrukcje LOW i HIGH
  • #3 7907741
    rj1307
    Poziom 15  
    Niestety, zmiana operatora dzielenia nic nie dało, zastosowanie High I Low także (troszkę inne "kwiatki" ale w tych samych adresach).

    
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    
    Config Sda = Portc.5
    Config Scl = Portc.4
    
    Dim Dana As Integer
    Dim Dana_zapisana As Integer
    Dim Adres As Word
    Dim Adr2 As Byte
    Dim Adr3 As Byte
    Dim Starszy As Byte
    Dim Mlodszy As Byte
    Dim O1 As Byte
    Dim O2 As Byte
    Dim O3 As Byte
    Dim O4 As Byte
    Dim O5 As Byte
    Dim O6 As Byte
    Dim O7 As Byte
    
    Cursor Off
    Cls
    
    
    For Adres = 0 To 100 Step 10
      Dana_zapisana = Adres
      Mlodszy = Low(dana_zapisana)
      Starszy = High(dana_zapisana)
    
      Adr2 = High(adres)
      Adr3 = Low(adres)
    
    
      I2cstart
      I2cwbyte 160
      I2cwbyte Adr2
      I2cwbyte Adr3
      I2cwbyte Mlodszy
      I2cwbyte Starszy
      I2cwbyte 1
      I2cwbyte 2
      I2cwbyte 3
      I2cwbyte 4
      I2cwbyte 5
      I2cwbyte 6
      I2cwbyte 7
      I2cstop
      Waitms 10
    Next
    
    
    Do
    
    For Adres = 0 To 100 Step 10
      Adr2 = High(adres)
      Adr3 = Low(adres)
    
      I2cstart
      I2cwbyte 160
      I2cwbyte Adr2
      I2cwbyte Adr3
      I2cstart
      I2cwbyte 161
      I2crbyte Mlodszy , Ack
      I2crbyte Starszy , Ack
      I2crbyte O1 , Ack
      I2crbyte O2 , Ack
      I2crbyte O3 , Ack
      I2crbyte O4 , Ack
      I2crbyte O5 , Ack
      I2crbyte O6 , Ack
      I2crbyte O7 , Nack
      I2cstop
    
      Dana = Makeint(mlodszy , Starszy)
    
      Locate 1 , 1
      Lcd "A: " ; Adres ; " D: " ; Dana
      Locate 2 , 1
      Lcd O1 ; " " ; O2 ; " " ; O3 ; " " ; O4 ; " " ; O5 ; " " ; O6 ; " " ; O7
      Wait 1
      Cls
    Next
    
    Loop
    End
    



    To odczytuje:

    
    
     Adres  Dana    o1   o2  o3   o4  o5   o6   o7 
    
        10    10    1    2   3    4   5    6    7 
        20    20    1    2   3    4   5    6    7 
        30    30    3    4   5    6   7    37   38   'źle jes tu 
        40    40    1    2   3    4   5    6    7 
        50    50    1    2   3    4   5    6    7 
        60    60    1    2   5    6   7    68   68    'tu 
        70    70    1    2   3    4   5    6    7 
        80    80    1    2   3    4   5    6    7 
        90    90    1    2   3    4   96   97   98   'i tu 
        100   100   1    2   3    4   5    6    7 
    
    
  • REKLAMA
  • #4 7907812
    tadzik85
    Poziom 38  
    Prędkość szyny I2C jak masz ustawioną?
  • #5 7908197
    rj1307
    Poziom 15  
    Próbowałem 200kHz, 100kHz, 50kHz. Za każdym razem efekt ten sam.
  • Pomocny post
    #6 7908564
    zumek
    Poziom 39  
    rj1307 napisał:
    Próbowałem 200kHz, 100kHz, 50kHz. Za każdym razem efekt ten sam.

    To może spróbuj zajrzeć do PDF-ka tej pamięci i zainteresuj się mechanizmem PAGE WRITE, bo to on jest źródłem Twoich kłopotów.
  • REKLAMA
  • #7 7908771
    rj1307
    Poziom 15  
    OK, jeśli dobrze rozumiem to chodzi o zapis 32 bajtów, czyli strony. Sprawdziłem program z zapisem od adresu 0 do 3200 z krokiem 32 i wszystko działa, ale w ten sposób tracę niepotrzebnie 23 bajty na każdą zapisaną stronę (ponieważ zapisuję 9). Czy jedynym sposobem jest zapis jednego bajtu, zwiększenie adresu o 1, zapis kolejnego bajtu, zwiększenie adresu o 1.....itd?
  • REKLAMA
  • #8 7908831
    tadzik85
    Poziom 38  
    Jest to wyjście, możesz również zrobić pewne zabezpieczenie, które będzie zawsze w odpowiednim momencie odczeka czas zapisu strony. Tzn gdy twoja partia danych wejdzie na 2 strony odpowiednio zostanie podzielona i wysłana do pamięci. Inną drogą jest zadbanie o odpowiednia alokacje danych w pamięci. Tak by żadna partia danych nie była dzielona pomiędzy strony.
  • #9 7911431
    rj1307
    Poziom 15  
    Dzięki za pomoc, temat zamykam.
REKLAMA