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

Procedura obsługi magistrali I2C do procka ADuC841

LIZARD 11 Sie 2006 15:19 1869 4
REKLAMA
  • #1 2905767
    LIZARD
    Poziom 13  
    Posty: 69
    Pomógł: 3
    Ocena: 6
    Witam

    Poszukuję przykładowych procedur obsługi magistrali I2C do procka ADuC841. Najlepiej zeby to były procedurki napisane w assemblerze. Robię sterownik LCD graficznego na tym własnie procku i potrzebuję dołączyć do układu pamięć szeregową AT24C128. Wszystkie lini9e mam już zajęte więc pozostaje mi tylko podłączenie pamięci do sprzętowej szyny I2C (Odpada programowa realizacja interfejsu).
    Gdyby ktoś już miał procedurki do komunikacji z pamięcią szeregową AT24C128 przez I2C to bardzo bym prosił o udostępnienie.

    POzdrawiam
  • REKLAMA
  • #2 2943627
    LIZARD
    Poziom 13  
    Posty: 69
    Pomógł: 3
    Ocena: 6
    Widze ze wielkiego "ruchu" przy tymtemacie nie ma :) poczytalem troszke note katalogową i zrealizowałem przykładowe procedurki do obsługi pamięci AT24C128. Wyprowadzenia A0,A1,A2 pamięci podłączyłem do masy a więc adres tego układu jest 1010000xB.
    PAmięć podłącvzyłem do lini SCLOCK i SDATA procesora ADuC841. Do linii włączyłem rezystory podciągające do Vcc (wartości 4k7).
    Procedura zapisu bajtu do pamięci działa (Pamięć generuje bit potwierdzenia), Sprawdziłęm to w ten sposób ze jak podam zły adres układu (dla przykładu 10100010) to procek ustawia mi flagę błędu a jak podam prawidłowy adres to procek wysyła bajt bez zgłaszani abłędu.
    Problem w tym ze nie mogę odczytać z pamięci niczego. NIe wiem czy procedura napisana jest źle czy moze robie coś nie tak. POniżej zamieszczam fragmenty kodu progremu z opisem. Gdyby ktoś mógł się przyjżeć temu to byłbym wdzięczny za każdą pomoc.

    ;****************************************************
    ; deklaracje zmiennych i ustawienia początkowe rejestrów
    ;****************************************************
    BITCNT DATA 034H ;LICZNIK BITÓW
    BYTECNT DATA 030H ;LICZNIK BAJTÓW
    SLAVE_DEV_ADD DATA 032H ;ADRES SLAVE
    EE_WRD_ADD1 DATA 033H ;STARSZY BAJT WORD ADRESU
    EE_WRD_ADD2 DATA 034H ;MŁODSZY BAJT WORD ADRESU
    I2C_DATA_OUT DATA 035H ;TU UMIESZCZANE SA DANE DO NADANIA LUB ODEBRANE Z I2C
    I2C_DATA_IN DATA 036H ;TU UMIESZCZANE SĄ DANE ODEBRANE Z I2C
    ERROR BIT F1 ;INFO O BLEDZIE TRANSMISJI

    org 100h
    start:
    CLR NOACK

    MOV I2CCON,#0A8H ;tryb MASTER
    CLR SPE ;SPI-OFF I2C-ON


    MOV SLAVE_DEV_ADD,#10100000B ;ADRES PAMIĘCI EEPROM

    ;**************************************************************
    ; PROCEDURY
    ;**************************************************************

    DELAY:
    NOP
    NOP
    NOP
    NOP
    RET

    ;***************************************************************
    ;SENDSTOP: WYSYŁA BIT STOPU
    ;***************************************************************

    BITSTOP:
    SETB MDE ;USTAWIA SDATA JAKO LINIĘ WYJŚCIOWĄ
    CLR MDO ;PRZYGOTUJ SDATA NA BIT STOPU
    SETB MCO ;USTAW SCLOCK NA RZYJĘCIE STOPU
    ACALL DELAY
    SETB MDO ;BIT STOPU
    CLR BUSY ;ZWOLNIENIE MAGISTRALI
    RET


    ;***********************************************************************
    ;BITSTART: WYSYŁA BIT STARTU A NASTĘPNIE DEVICE_ADRES URZĄDZENIA SLAVE
    ;***********************************************************************
    BITSTART:
    SETB BUSY ;ZGŁOŚ ZAJĘTOŚC SZYNY
    SETB MDE ;USTAW SDATA JAKO LINIĘ WYJŚCIOWĄ
    CLR NOACK
    CLR ERROR
    JNB MCO,POMIN
    JNB MDO,POMIN
    CLR MDO ;GENERUJ BIT STARTU
    ACALL DELAY
    CLR MCO ;ROZPOCZNIJ NADAWANIE
    POMIN:

    MOV A,SLAVE_DEV_ADD
    ACALL SENDBYTE
    RET



    ;******************************************************************
    ;SENDBYTE: WYSYŁA NA MAGISTRALE BAJT DANYCH KTORY POBIERA Z ACC
    ;NISZCZY ACC I C!!!
    ;******************************************************************


    SENDBYTE:
    MOV BITCNT,#8 ;8 BITÓW TO JEDEN BAJT
    SETB MDE ;USTAW SDATA JAKO WYJŚCIOWĄ
    CLR MDO
    CLR MCO
    LOOP_I2C:
    RLC A ;POBIERZ JEDEN BIT
    MOV MDO,C ;WYSTAW BIT NA SDATA
    SETB MCO ;GENERUJ ZEGAR DLA BITU
    CLR MCO ;...
    DJNZ BITCNT,LOOP_I2C
    CLR MDE ;USTAW SDATA NA INPUT
    SETB MCO ;GENERUJ ZEGAR DLA BITU POTWIERDZENIA
    JNB MDI,NEXT ;SPRAWDZ BIT POTWIERDZENIA
    SETB NOACK ;BRAK POTWIERDZENIA
    NEXT:
    CLR MCO
    RET
    ;*************************************************************************************
    ;WRITE_BYTE_EE: REALIZUJE ZAPIS JEDNEGO BAJTU DANYCH DO PAMIĘCI AT24C128
    ; DEVICE_ADRES POBIERANY JEST Z SLAVE_DEV_ADD A WORD_ADRES Z EE_WRD_ADD1 I EE_WRD_ADD2
    ;DANE POBIERANE SĄ Z I2C_DATA_OUT
    ;*************************************************************************************

    WRITE_BYTE_EE:
    ACALL BITSTART ;rozpocznij transmisję i wyslij adres układu
    JB NOACK,END_WR ;jesli brac ACK to zakoncz
    MOV A,EE_WRD_ADD1 ;pierwszy bajt subbadresu
    ACALL SENDBYTE
    JB NOACK,END_WR
    MOV A,EE_WRD_ADD2 ;drugi bajt subbadresu
    ACALL SENDBYTE
    MOV A,I2C_DATA_OUT ;bajt danych
    ACALL SENDBYTE
    END_WR:
    ACALL BITSTOP ;zakoncz nadawanie
    JNB NOACK,END_WR1
    SETB ERROR
    END_WR1:
    RET

    ;***********************************************************************************
    ;RCVBYTE: ZAPISUJE BAJT DANYCH ODEBRANY Z I2C
    ; DANE ODEBRANE UMIESZCZONE SĄ W I2C_DATA_IN
    ;***********************************************************************************

    RCVBYTE:
    MOV BITCNT,#8
    CLR MDE ;USTAW LINIĘ SDATA DO ODBIORU DANYCH
    CLR MCO
    LOOPR:
    SETB MCO ;GENERUJ SYGNAŁ ZEGARA
    CLR MCO
    MOV C,MDI ;ODBIERZ BIT DANYCH
    RLC A ; I ZAPISZ GO W ACC
    DJNZ BITCNT,LOOPR
    MOV I2C_DATA_IN,A ;ZAPISZ ODEBRANY BAJT DANYCH W I2C_DATA_IN
    SETB MDE ;PRZYGOTUJ LINIĘ SDATA NA NADANIE BITU POTWIERDZENIA


    SACK:
    CLR MDO
    SETB MCO
    ACALL DELAY
    CLR MCO
    CLR MDE
    RET


    ;**************************************************************************************
    ;READ_BYTE_EE: ODCZYTUJE BAJT DANYCH Z ZEWNĘTRZEN PAMIĘCI EEPROM
    ;ADRESY ZNAJDUJĘ SIĘ W BUFORACH SLAVE_DEV_ADD, EE_WRD_ADD1, EE_WRD_ADD2
    ;DANE ZAPAMIĘTANE SĄ W I2C_DATA_IN
    ;**************************************************************************************


    READ_BYTE_EE:
    ACALL BITSTART ;adresuj układ do zapisu
    JB NOACK,RD_END
    MOV A,EE_WRD_ADD1 ;pierwszy bajt subadresu
    ACALL SENDBYTE
    JB NOACK,RD_END
    MOV A,EE_WRD_ADD2 ;drugi bajt subadresu
    ACALL SENDBYTE
    JB NOACK,RD_END
    MOV A,SLAVE_DEV_ADD
    INC A ;zmien ostatbi bit dev_adresu ukłądu (ustaw apmięć w tryb odczytu danych)
    ACALL SENDBYTE JB NOACK,RD_END
    ACALL RCVBYTE ;;rozpocznij odbieranie danych


    RD_END:
    ACALL BITSTOP
    JNB NOACK,RD_END1
    SETB ERROR
    RD_END1:
    RET


    ;***********************************************************************************
    ;RCVBYTE: ZAPISUJE BAJT DANYCH ODEBRANY Z I2C
    ; DANE ODEBRANE UMIESZCZONE SĄ W I2C_DATA_IN
    ;***********************************************************************************

    RCVBYTE:
    MOV BITCNT,#8
    CLR MDE ;USTAW LINIĘ SDATA DO ODBIORU DANYCH
    CLR MCO
    LOOPR:
    SETB MCO ;GENERUJ SYGNAŁ ZEGARA
    CLR MCO
    MOV C,MDI ;ODBIERZ BIT DANYCH
    RLC A ; I ZAPISZ GO W ACC
    DJNZ BITCNT,LOOPR
    MOV I2C_DATA_IN,A ;ZAPISZ ODEBRANY BAJT DANYCH W I2C_DATA_IN
    SETB MDE ;PRZYGOTUJ LINIĘ SDATA NA NADANIE BITU POTWIERDZENIA


    SACK:
    CLR MDO
    SETB MCO
    ACALL DELAY
    CLR MCO
    CLR MDE
    RET





    W wyn iku wykonania powyższych procedur udaje mi się dokonać zapisu natomiast po odczycie w rejestrze I2c_DATA_IN nie mam tego samego bajtu jaki był w rejestrze I2C_DATA_OUT. Oczywiście zdresuję ta samą komorkę pamięci w obu przypoadkach.
  • REKLAMA
  • #3 2961971
    LIZARD
    Poziom 13  
    Posty: 69
    Pomógł: 3
    Ocena: 6
    CZy ktos moze popatrzec na ten kawałęk kodu zamieszczony powyzej i ewentualnie mi pomóc??
  • REKLAMA
  • #4 2962375
    filip_gd
    Poziom 12  
    Posty: 103
    Pomógł: 1
    Ocena: 2
    Nie ogłądałem kodu
    Ale z tego co pamiętam adres ukłądu do czytania jest inny niż do zapisywania.
    pozdr
  • #5 2964470
    LIZARD
    Poziom 13  
    Posty: 69
    Pomógł: 3
    Ocena: 6
    Dzięki za zainteresowanie. Faktycznie adres układu jest inny do czytania niż do zapisywania i różni się ostatnim bitem. Jezeli ostatni bit adresu jest zerem to ukłąd adresowany jest do zapisu a jezeli jedynką to układ adresowany jest do odczytu. Ale to akurat uwzględniłem w procedurze odczytu , jest tam w poewnym miejscu inkrementacja akumulatora który zawiera adres układu (po inkrementacji zmienia się ostratni bit z zera na jeden) a więc jest wszystko tak jak powinno.
    POzdrawiam
REKLAMA