Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[16f84a][basic/asm] Protokół i^2c

mikmas 08 Nov 2010 01:23 1211 5
  • #1
    mikmas
    Level 18  
    Muszę zrobić idiotycznie prosty układ odczytujący/zapisujący dane z/do at24cXX (testuję na 04). W programatorze wszystko działa, jednak po podłączeniu do pica - ni wuja :/. Napisałem na szybko prosty symulator wyjść SCL i SDA:
    [16f84a][basic/asm] Protokół i^2c
    Adres pamięci to 10100001b
    Nie dostaję bitu ack (ustawiony jest ciągle na 1). Odległość między kolejnymi bitami na wyjściach to 1ms. Oto kawałek kodu:
    Inicjacja (wysłanie adresu+sprawdzenie ACK)
    I2C_START
    F2_000009 equ $ ; in [I2C.BAS] LOW SDPIN
    	Bcf PORTB,5
    	Bsf STATUS,5
    ram_bank = 1
    	Bcf TRISB,5
    F2_000010 equ $ ; in [I2C.BAS] LOW SCPIN
    	Bcf STATUS,5
    ram_bank = 0
    	Bcf PORTB,4
    	Bsf STATUS,5
    ram_bank = 1
    	Bcf TRISB,4
    F2_000011 equ $ ; in [I2C.BAS] SDA_BYTE=I2C_ADDR
    	Bcf STATUS,5
    ram_bank = 0
    	Movfw I2C_ADDR
    	Movwf SDA_BYTE
    F2_000012 equ $ ; in [I2C.BAS] GOSUB I2C_SENDBYTE
    	Call I2C_SENDBYTE
    F2_000013 equ $ ; in [I2C.BAS] GOSUB I2C_ACK
    	Call I2C_ACK
    F2_000014 equ $ ; in [I2C.BAS] IF ACK_SUCCESS=1 THEN RETURN
    	Btfss _B#VR1,1
    	Goto bc@ll2
    	Return

    Wysłanie bajtu:
    I2C_SENDBYTE
    F2_000028 equ $ ; in [I2C.BAS] BITSHIFT=%10000000
    	Movlw 128
    	Movwf BITSHIFT
    F2_000029 equ $ ; in [I2C.BAS] REPEAT
    bc@ll3
    ; Start of Inline Code.
    movfw SDA_BYTE
    andwf BITSHIFT
    btfsc STATUS,2
    goto if0
    ; End of Inline Code.
    F2_000036 equ $ ; in [I2C.BAS] SDA_VALUE=1
    	Bsf _B#VR1,0
    F2_000037 equ $ ; in [I2C.BAS] GOTO IFEXIT
    	Goto IFEXIT
    IF0
    F2_000039 equ $ ; in [I2C.BAS] SDA_VALUE=0
    	Bcf _B#VR1,0
    IFEXIT
    F2_000041 equ $ ; in [I2C.BAS] GOSUB I2C_SENDBIT
    	Call I2C_SENDBIT
    F2_000042 equ $ ; in [I2C.BAS] BITSHIFT=BITSHIFT >> 1
    	Clrc
    	Rrf BITSHIFT,F
    F2_000043 equ $ ; in [I2C.BAS] UNTIL BITSHIFT=0
    	Movfw BITSHIFT
    	Btfss STATUS,2
    	Goto bc@ll3
    bc@ll4
    F2_000044 equ $ ; in [I2C.BAS] RETURN
    	Return

    Wysłanie bitu:
    I2C_SENDBIT
    F2_000020 equ $ ; in [I2C.BAS] SDPIN=SDA_VALUE
    ; Bit_Bit _B#VR1,0,PORTB,5
    	Bsf PORTB,5
    	Btfss _B#VR1,0
    	Bcf PORTB,5
    F2_000021 equ $ ; in [I2C.BAS] DELAYMS 1
    	Movlw 1
    	Call dl@ms
    F2_000022 equ $ ; in [I2C.BAS] SCPIN=1
    	Bsf PORTB,4
    F2_000023 equ $ ; in [I2C.BAS] DELAYMS 1
    	Movlw 1
    	Call dl@ms
    F2_000024 equ $ ; in [I2C.BAS] SCPIN=0
    	Bcf PORTB,4
    F2_000025 equ $ ; in [I2C.BAS] RETURN
    	Return

    Wiem, że na pewno było dużo takich tematów, ale nie mogę sobie poradzić z tym :(. Proszę pomóżcie[/img]
  • #2
    viayner
    Level 42  
    Witam,
    Wyglada mi na zle zainicjowana transmisje. Nie wglebialem sie w kod bardzo ale czy ustawiles wszystkie linje w odpowiednim kierunku ?
    A tak przy opkazji czy podciagnales obie linje rezystorami jak zaleca standard I2C ?
    Tak na poczatek moze zajzyj na www.mikroe.com tam jest picbasic - demo kod do 1k ale dziala i sa proste przyklady zarowno w picbasicu jak i asm.
    Pozdrawiam
  • #3
    mikmas
    Level 18  
    Symulator uwzględnia także kierunek transmisji (nie ustawi fizycznego stanu wysokiego, gdy nie ma wyjścia i nie sczyta, jak nie ustawię na wejście).Rezystory oczywiście są. Looknę za jakieś 2 godziny na tą stronkę, dzięki! Kurde taki prosty protokół i tyle problemów -.-
  • #4
    mikmas
    Level 18  
    Spróbowałem na picbasicu i - tak dla odmiany - nie działa. Spłodziłem coś takiego:
    DPIN    var     PORTB.5
    CPIN    var     PORTB.4
    BREAD      var     byte
    I var byte
    
    LED VAR PORTA.2
    ACTIONBUTTON VAR PORTB.0
    FEED VAR PORTB.3
    'DECLARE XTAL=8
    
    BLINKTIME var byte
    
    HIGH FEED
    INPUT ACTIONBUTTON
    
    WHILE 1=1
    	BLINKTIME=BLINKTIME+1
    	PAUSE 1
    	IF BLINKTIME=255 THEN TOGGLE LED
    	IF ACTIONBUTTON=1 THEN GOSUB ACTION
    WEND
    
    ACTION:
    	LOW LED
    	LOW FEED
    	PAUSE 1000
    	For I = 0 To 15
    		I2CREAD DPIN,CPIN,$A0,I,[BREAD]
    		WRITE I,BREAD
    		PAUSE 50
    	Next I
    	HIGH LED
    	HIGH FEED
    RETURN

    FEED to wyjście na tranzystor (masa - włącz eeprom, + - wyłącz). Podłączenia sprawdzałem milion+1 razy, eeprom jest w 100% sprawny. Po odczytaniu zawartości wew. eeproma mam 16 znaków 0x20 (w eepromie zapisałem zdanie, także to na pewno nie są same spacje :P). Błagam pomóżcie, bo już wiążę kabel od internetu pod sufitem z zamiarem powieszenia się! Tak durnie prosty projekt i nie mogę zrobić :/
  • #6
    mikmas
    Level 18  
    Działa. Dzięki wielkie