Zápis do externí EEPROMky

Dobrý den

chtěl bych se zeptat jestli někdo nesetkal se zápisem do externí EEPROMKY konkrétně typ 24C512.Nejlépe PICem 16F877A.

Děkuji

Sice s toudle pamětí konkrétně ne, ale dělal jsem z 24C64. Spíš napiš, v čem vidíš problém, jestli v implementaci I2C nebo implementaci komunikačního protokolu a jestli chceš použít I2C softwarový nebo použít hardwarový.

Zkoušel jsem použít program z těchto stránek sprut.de/electronic/pic/grund/i2c.htm#fluss.

S tím že něco zapíšu a př přečtení se mi výsledek zobrazí na 4 diodách co mám k dispozici.Ale nevím,kde mam momentálně chybu jestli už při zápisu nebo př čtení.
I2C.asm (3.9 KB)

To máš na 20Mhz? Jestli jo, tak do SSPADD dej .11

Zkoušel jsem a výsledek furt stejný.Jestli to nějak pomůže tak jsem zjistil,že program dojede až do konce.Takže buď špatně zapisuju nebo čtu nebo něco jiného.

:arrow_right: administrator: příspěvek byl upraven
Předchozí příspěvky se necitují.

Tak už to víceméně funguje.Zápis probíhá bez problému,ale u čtení jsem narazil na zajímavou věc.Když mám ten kód takhle

        movfw   SSPBUF         
        movwf   PORTB     	 
        call    i2c_off                

tak se jeden bajt přečte v pořádku ale program projede znovu podprogramy a tam se nějak zacyklí.Když tamm ale dám zarážku

        movfw   SSPBUF         
        movwf   PORTB     	 
        call    i2c_off  
        goto  $    

tak jako bz se celý systém zbláznil(výstupy se začnou z ničehonic nastavovat a nulovat),ale když to uložím místo na port do proměnné tak problém zmizí což je zajímavé.

A ještě jeden dotaz nevíte jak probíhá adresování dat u větších pamětí.Protože zbůsob adresace co mám v kódu je jen pro 65536 bajtů nebo se mýlím ? Díky za odpovědi
I2Cv3.asm (4.26 KB)

V tom programu máš jednu zásadní chybu. Program jede postupně od 0x00 až do konce CTENI I2C a tam se zamotá na return bez předchozího voláni call. Pak dojde k resetu.

Program, jako takovej, by měl, aspoň já to tak dělám, někde začít, u PIC 0x00, skočit na inicializaci, pak třeba nastavení proměnných a pak by měl následovat hlavní program, který jede většinou pořád dokola a z důvodu nějakých událostí skáče do podprogramů a na přerušení na 0x04.

Tvému programu chybí hlavní smyčka z které by program četl a zapisoval do EEPROM a s daty pak něco udělal.

Adresa je sice 65535, ale za adresou je block select bit, takže 2x 65535.
Block.JPG

Díky za rychlou odpověď,ale že to znovu projede podprogramy to vím.Můj problém je jiný když za I2C_of dam cyklus zaražku nebo nějakou operaci tak se mi to naprosto zblázní ledky začnou blikat rtelátka spínat a děje se to jenom když překopíruju SSBUF na PORTB a nebo když tam nedam zarážku a necham to projet znova ty podprogramy.

A u té adresy asi každý myslíme něco jiného.Ja jsme potřeboval vědět jakým způsebem vybírám adresu buňky,neboť ten můj způsob se mi nezdá jako přílioš vhodný pro veliké paměti.

Ty data z EEPROM používáš na co? Ono to totiž tak rychle resetuje, že se nediv, že se to zlázní. :smiley: Tím, že překopíruješ data z SSBUF potvrdíš dokončení operace. Pak to dojede na konec a nasleduje reset. Pokud tam dáš GOTO $, tak se to na tom zastaví.

Jinej zbůsob není. (doufám :blush: ) Adresa + (u mě block) + R/W, vyšší adresa, pak nižžší adresa a data. Mám tady megovou pamět a je to stejné jak u tebe, akorát vybírám jestli prvních 65535 nebo těch druhých.

Jenže můj problém je přesně opačný :slight_smile: .Bláznit to začne když tam tu zarážku dám.Když tam není tak sice vidím vloženou hodnotu,ale ja potřebuju přečíst celou paměť takže bez zarážky,cyklu je to nepoužitelné.

V čem to vidiš? Ty data z EEPROM používáš na co?

Ve výsledku se to má odesílat po USARTu,ale teď to posílám na PORTB na kterém mám připojeny ledky pro vizuální kontrolu.

[code];čtení I2C
;Stelle EEPROM auf Speicher-Adresse 3 ein***********
call i2c_on ; Bus aktiv

    movlw   H'A0'           ; 1010 0000
    call    i2c_tx          ; 24C04 zum Schreiben adressieren

    movlw   0x00            ; high Teil der Adresse
    call    i2c_tx
    movlw   0x03            ; low Teil der  Adresse
    call    i2c_tx

    call    i2c_off         ; Bus freigeben 

;Lesen des aktuellen Bytes aus 24C04***********
call i2c_on ; Bus aktiv

    movlw   H'A1'           ; 1010 0001
    call    i2c_tx          ; 24C04 zum Lesen adressieren

    call    i2c_rx
    movfw   SSPBUF          ; I2C Empfangsregister auslesen
    movwf   PORTB     	  ; Byte in Speicherzelle Datenpuffer retten
    call    i2c_off         ; Bus freigeben[/code]

Po tomhle ti program skočí do podprogramu

;***I2C UNTERPROGRAMME************************************************************ ; ; I2C-Bus im Master-Mode übernehmen i2c_on bcf PIR1, SSPIF ; SSPIF Bit löschen bsf STATUS, RP0 bsf SSPCON2, SEN ; Bus Übernahme anweisen bcf STATUS, RP0 goto i2c_warte
A to je ta chyba.

8x tohle a bude reset

Musíš si ten program trochu uspořádat!

Ja vím ,že je to špatně ale takhle mi to správnou hodnotu ukáže.

Když tam le dám tu zarážku

;čtení I2C
;**Stelle EEPROM auf Speicher-Adresse 3 ein*************
        call    i2c_on          ; Bus aktiv

        movlw   H'A0'           ; 1010 0000
        call    i2c_tx          ; 24C04 zum Schreiben adressieren

        movlw   0x00            ; high Teil der Adresse
        call    i2c_tx
        movlw   0x03            ; low Teil der  Adresse
        call    i2c_tx

        call    i2c_off         ; Bus freigeben
;**Lesen des aktuellen Bytes aus 24C04*************
        call    i2c_on          ; Bus aktiv

        movlw   H'A1'           ; 1010 0001
        call    i2c_tx          ; 24C04 zum Lesen adressieren

        call    i2c_rx
        movfw   SSPBUF          ; I2C Empfangsregister auslesen
        movwf   PORTB          ; Byte in Speicherzelle Datenpuffer retten
        call    i2c_off         ; Bus freigeben
        goto   $
         ......
         

tak nastane ten popisovaný problém.Ne při tom jak to skáče (a nemá) do podprogrmu.A dělá to když ten SSBUF převedu na ten PORT když ho uložím do proměnné tak to nědělá.

A k té adrese, není to nějak málo.Když si to vezmu tak to mám ± nejakých 130 000 adres a pokud je jedna adresa bajt tak to je pořád jenom nějakých 130 kB.Nebo se pletu ?

00000000 00000011 - 0x0003 .Čteš a zapisuješ pořád do jedné a te samé.

Potřebuješ jen jednu adresu? Nebo teda kde bereš data, co jsou v EEPROM? Z tou** zarážkou ** je to divný, ta by program měla zastavit na goto $.

Teď jo nebo jsem začal se zápisem a čtením jedné buňky ať vím jestli to vůbec funguje.Ale když jsem tam dal zarážku nebo zapisoval cyklicky tak mi to prostě blblo,blbne.

Program by měl mít nějakou hlavní smyčku, třeba MAIN, ze ktere za určitých událostí vykonávají podprogramy. A to je i READ_I2C a WRITE_I2C. A mezi nimi třeba můžeš obsluhovat USART nebo PORTB, nebo cokoliv jiného. Ale vždy ze z toho podprogramu musíš nějak vrátit. Pokud voláš CALL, tak RETURNem, pokud voláš GOTO READ_I2C, tak se vrátiš třeba GOTO MAIN do hlavní smyčky.

Ale nemůžeš to mít tak jak to máš teď, aby se program zacyklil, protože jede postupně až k podprogramům.

Tak problém vyřešen :smiley: .Stačilo dát jen mezi čtení a zápis dát spožďovací smyčku a bylo bez problému.Honzo díky za rady a rychlé reakce.

Pro zájemce přikládám zdrojový kód
I2Cv3.asm (4.57 KB)

jump call zapis call wait call cteni call wait goto $
Kdyby jsi to tam dal hned, tak by to fungovalo hned. možná i bez wait