Problemet är att det inte verkar fungera alls, får bara tillbaka 0xFF. Antingen är det fel på skrivrutinen eller läsrutinen. Lägger upp hela koden. Jag har provat att lägga till lite kod till funktionen "ACK" som efter klockpulsen (SCL = från 1 till 0) kollar om SDA är låg eller inte och den var inte låg en enda gång under hela skriv eller läsningen (obs denna kodbit är borta i denna koden). Så det verkar vara något knas med skrivningen, om jag nu inte har missförstått hur man kollar om man fått ack eller inte.
Många kakor till den som klarar ut felet.
Kod: Markera allt
list p=16F628A ; list directive to define processor
#include <p16F628A.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
;Config
__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _HS_OSC
;Interupt
INT CODE 0x0004
goto Intr
;Reset
RST CODE 0x0000
goto Init
;Variablar
UDATA
;Delade variablar
UDATA_SHR
COUNT1 RES 1
COUNT2 RES 1
COUNT3 RES 1
TEMP RES 1
EEPROM_ADR_H RES 1
EEPROM_ADR_L RES 1
EEPROM_DEV RES 1
EEPROM_DATA RES 1
Intr CODE
Intr
retfie
CODE
Init
;Define
#Define PORT_SDA PORTA,0
#Define PORT_SCL PORTA,1
#Define TRIS_SDA TRISA,0
#Define TRIS_SCL TRISA,1
;Stänger av analoga funktioner
BANKSEL PORTA
clrf PORTA
BANKSEL CMCON
movlw 0x07
movwf CMCON
;Sätter variablar
clrf COUNT1
clrf COUNT2
clrf COUNT3
clrf TEMP
clrf EEPROM_ADR_H
clrf EEPROM_ADR_L
clrf EEPROM_DEV
clrf EEPROM_DATA
;Sätter portar
BANKSEL TRISA
clrf TRISA
clrf TRISB
BANKSEL PORTA
clrf PORTA
clrf PORTB
;Testloop, skickar ett värde till eepromet och läser sedan av samma värde från eepromet och lägger på PORTB
Start
movlw 0x45
movwf EEPROM_ADR_H
movlw 0x3A
movwf EEPROM_ADR_L
movlw .0
movwf EEPROM_DEV
movlw b'10010110'
call Rand_write
movlw 0x45
movwf EEPROM_ADR_H
movlw 0x3A
movwf EEPROM_ADR_L
movlw .0
movwf EEPROM_DEV
movlw b'10010110'
call Rand_read
BANKSEL PORTB
movf TEMP,W
movwf PORTB
hej
goto hej
Rand_read ;Läser innehållet på adressen EEPROM_ADR_H/EEPROM_ADR_L från minne nr. EEPROM_DEV och sparar i W-reg
call EEPROM_Start ;Utför start condition
bcf STATUS,C ;skapa första byten (1010ABC0) A,B,C är EEPROM_DEV, sista nollan är för write
rlf EEPROM_DEV,F
movlw b'10100000'
addwf EEPROM_DEV,W
call Send_byte ;skickar första byten
call ACK ;acknowledge
movf EEPROM_ADR_H,W ;skickar adressbitar 15-8
call Send_byte
call ACK
movf EEPROM_ADR_L,W ;skickar adressbitar 7-0
call Send_byte
call ACK
call EEPROM_Start
bsf STATUS,C ;skapa första byten (1010ABC1) A,B,C är EEPROM_DEV, sista ettan är för read
rlf EEPROM_DEV,F
movlw b'10100000'
addwf EEPROM_DEV,W
call Send_byte ;Skickar device select
call ACK
call Read_byte
call NOACK
call EEPROM_Stop
return
Read_byte ;Läser en byte och sparar i W-reg
movlw .8
movwf COUNT3 ;loopvariabel
Read_byte_0
call SDA_H ;Gör SDA till en input
call SCL_H
BANKSEL PORTA
btfss PORT_SDA
goto Read_0
goto Read_1
Read_0
bcf STATUS,C
rlf TEMP,F
goto Read_count
Read_1
bsf STATUS,C
rlf TEMP,F
goto Read_count
Read_count
call SCL_L
decfsz COUNT3,F ;kör loopen 8 gånger för att läsa en byte
goto Read_byte_0
movf TEMP,W ;loopen är klar, sparar svaret i W-reg
return
Rand_write ;Skriver innehållet i W-reg på adress EEPROM_ADR_H/EEPROM_ADR_L till minne nr. EEPROM_DEV
movwf EEPROM_DATA ;sparar W-reg i en temporär variabel.
call EEPROM_Start ;Utför start condition
bcf STATUS,C ;skapa första byten (1010ABC0) A,B,C är EEPROM_DEV, sista nollan är för write
rlf EEPROM_DEV,F
movlw b'10100000'
addwf EEPROM_DEV,W
call Send_byte ;skickar första byten
call ACK ;acknowledge
movf EEPROM_ADR_H,W ;skickar adressbitar 15-8
call Send_byte
call ACK
movf EEPROM_ADR_L,W ;skickar adressbitar 7-0
call Send_byte
call ACK
movf EEPROM_DATA,W ;skickar databyten
call Send_byte
call ACK
call Delay_long ;väntar 10ms för intern writecykel
return
Send_byte ;Skickar innehållet i W-reg till det externa eepromet
movwf TEMP
movlw .8
movwf COUNT3 ;loopvariabel
Send_byte_0
rlf TEMP,F ;flyttar ut högsta byten och kollar om den är 1 eller 0
btfss STATUS,C
goto Send_0
goto Send_1
Send_0 ;klocka ut en nolla till eepromet
call SDA_L
call SCL_H
call SCL_L
goto Send_count
Send_1 ;klocka ut en nolla till eepromet
call SDA_H
call SCL_H
call SCL_L
goto Send_count
Send_count
decfsz COUNT3,F ;kör loopen 8 gånger för att skicka en byte
goto Send_byte_0
return
EEPROM_Start ;SDA 1-0 medan SCL = 1
call SCL_L ;Säkerhetsåtgärd ifall SCL råkar vara 1
call SDA_H
call SCL_H
call SDA_L
call SCL_L
return
EEPROM_Stop ;SDA 0-1 medan SCL = 1
call SDA_L
call SCL_H
call SDA_H
call SCL_L
return
SDA_H ;SDA = input
BANKSEL TRISA
bsf TRIS_SDA
call Delay_short
return
SDA_L ;SDA = output (0)
BANKSEL PORTA
bcf PORT_SDA
BANKSEL TRISA
bcf TRIS_SDA
call Delay_short
return
SCL_H ;SCL = input
BANKSEL TRISA
bsf TRIS_SCL
call Delay_short
return
SCL_L ;SDA = output (0)
BANKSEL PORTA
bcf PORT_SCL
BANKSEL TRISA
bcf TRIS_SCL
call Delay_short
return
ACK ;klockar ut en acknowledge
call SDA_H
call SCL_H
call SCL_L
return
NOACK ;klockar ut en acknowledge
call SDA_L
call SCL_H
call SCL_L
return
Delay_short
;46 cycles
movlw 0x2F
movwf COUNT1
Delay_short_0
decfsz COUNT1, f
goto Delay_short_0
;4 cycles (including call)
return
Delay_long
;249993 cycles
movlw 0x4E
movwf COUNT1
movlw 0xC4
movwf COUNT2
Delay_long_0
decfsz COUNT1, f
goto $+2
decfsz COUNT2, f
goto Delay_long_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
end