- ;
- ; Routines I2C V1.0
- ;
- ; O.R 04/2003
- ;-----------------------------------------------------------------------------------------
- ;
- ;
- ; Cette routine nécessite :
- ; - Les deux macros : SDA_IN et SDA_OUT
- ; - Les variables : I2C_flag, I2C_DATA, I
- ; - Le fichier : Q4mhz.asm
- ;
- ;
-
-
- I2C_INIT:
- SDA_OUT ;SDA en sortie
- bsf SDA ;SDA a 1
- bsf SCL ;SCL a 1
-
- return
-
- I2C_START: ;SDA_OUT
- ;SDA=1 SCL=1
- bsf SCL ;SCL a 1
- bsf SDA ;SDA a 1
- bcf SDA ;SDA a 0
-
- return
-
- I2C_STOP: ;SDA_OUT
- ;SDA=X SCL=0
- bcf SDA ;SDA a 0
- bsf SCL ;SCL a 1
- bsf SDA ;SDA a 1
-
- return
-
- I2C_SLAVE_ACK: ;SDA_OUT
- ;SDA=X SCL=0
- bcf SCL ;SCL a 0
- SDA_IN ;SDA en entrée
- CALL Tempo_11us
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- btfsc SDA ;Si 1 ecriture d'un flag d'erreur
- call NO_ACK
- bcf SCL ;SCL a 0
- CALL Tempo_11us
-
- SDA_OUT ;SDA en sortie
-
- return
-
- I2C_MASTER_ACK: ;SDA_IN
- ;SDA=X SCL=0
- bcf SCL ;SCL a 0
- SDA_OUT ;SDA en sortie
- bcf SDA ;SDA a 0
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- bcf SCL ;SCL a 0
- CALL Tempo_11us
- bsf SDA ;SDA a 1
-
- return
-
- I2C_MASTER_NACK: ;SDA_IN
- ;SDA=X SCL=0
- bcf SCL ;SCL a 0
- SDA_OUT ;SDA en sortie
- bsf SDA ;SDA a 1
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- bcf SCL ;SCL a 0
- CALL Tempo_11us
- bcf SDA ;SDA a 0
-
- return
-
- I2C_SEND_BYTE:
- movwf I2C_DATA ;w contient les data a envoyer
- movlw d'8'
- movwf I
- Next_data_s:
- decf I,f
- bcf SCL ;SCL a 0
- CALL Tempo_11us
- rlf I2C_DATA,f ;Rotation a gauche bit(I) dans la carry
- btfsc carry ;Si I=1
- bsf SDA ;SDA a 1
- btfss carry ;Si I=0
- bcf SDA ;SDA a 0
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- incf I,f
- decfsz I,f ;Si I!=0
- goto Next_data_s
-
- bcf SCL ;SCL a 0
- CALL Tempo_11us
-
- call I2C_SLAVE_ACK
-
- return
-
- I2C_RECEIVE_BYTE:
- movlw d'8'
- movwf I
- clrf I2C_DATA
- SDA_IN ;SDA en entrée
- Next_data_r:
- decf I,f
- bcf SCL ;SCL a 0
- CALL Tempo_11us
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- btfsc SDA ;Si SDA=1
- bsf carry
- btfss SDA ;Si SDA=0
- bcf carry
-
- rlf I2C_DATA,f ;décallage à gauche et met la carry dans le LSB
-
- incf I,f
- decfsz I,f ;Si I!=0
- goto Next_data_r
-
- bcf SCL ;SCL a 0
- CALL Tempo_11us
-
- call I2C_MASTER_ACK
-
- return
-
- I2C_RECEIVE_BYTE_LAST:
- movlw d'8'
- movwf I
- SDA_IN ;SDA en entrée
- Next_data_rl:
- decf I,f
- bcf SCL ;SCL a 0
- CALL Tempo_11us
- bsf SCL ;SCL a 1
- CALL Tempo_11us
- btfsc SDA ;Si SDA=1
- bsf carry
- btfss SDA ;Si SDA=0
- bcf carry
-
- rlf I2C_DATA,f ;décallage à gauche et met la carry dans le LSB
-
- incf I,f
- decfsz I,f ;Si I!=0
- goto Next_data_rl
-
- bcf SCL ;SCL a 0
- CALL Tempo_11us
-
- call I2C_MASTER_NACK
-
- return
-
-
- ;-----------------------------------------------------------------------------------------
- ; I2C_flag
- ; 0: NO_ACK
- ; 1:
- ; 2:
- ; 3:
- ; 4:
- ; 5:
- ; 6:
- ; 7:
- ;
-
-
- NO_ACK:
- bsf I2C_flag,0 ;Pas d'ack de l'esclave -> problème de comm
-
- return
-
;
; Routines I2C V1.0
;
; O.R 04/2003
;-----------------------------------------------------------------------------------------
;
;
; Cette routine nécessite :
; - Les deux macros : SDA_IN et SDA_OUT
; - Les variables : I2C_flag, I2C_DATA, I
; - Le fichier : Q4mhz.asm
;
;
I2C_INIT:
SDA_OUT ;SDA en sortie
bsf SDA ;SDA a 1
bsf SCL ;SCL a 1
return
I2C_START: ;SDA_OUT
;SDA=1 SCL=1
bsf SCL ;SCL a 1
bsf SDA ;SDA a 1
bcf SDA ;SDA a 0
return
I2C_STOP: ;SDA_OUT
;SDA=X SCL=0
bcf SDA ;SDA a 0
bsf SCL ;SCL a 1
bsf SDA ;SDA a 1
return
I2C_SLAVE_ACK: ;SDA_OUT
;SDA=X SCL=0
bcf SCL ;SCL a 0
SDA_IN ;SDA en entrée
CALL Tempo_11us
bsf SCL ;SCL a 1
CALL Tempo_11us
btfsc SDA ;Si 1 ecriture d'un flag d'erreur
call NO_ACK
bcf SCL ;SCL a 0
CALL Tempo_11us
SDA_OUT ;SDA en sortie
return
I2C_MASTER_ACK: ;SDA_IN
;SDA=X SCL=0
bcf SCL ;SCL a 0
SDA_OUT ;SDA en sortie
bcf SDA ;SDA a 0
bsf SCL ;SCL a 1
CALL Tempo_11us
bcf SCL ;SCL a 0
CALL Tempo_11us
bsf SDA ;SDA a 1
return
I2C_MASTER_NACK: ;SDA_IN
;SDA=X SCL=0
bcf SCL ;SCL a 0
SDA_OUT ;SDA en sortie
bsf SDA ;SDA a 1
bsf SCL ;SCL a 1
CALL Tempo_11us
bcf SCL ;SCL a 0
CALL Tempo_11us
bcf SDA ;SDA a 0
return
I2C_SEND_BYTE:
movwf I2C_DATA ;w contient les data a envoyer
movlw d'8'
movwf I
Next_data_s:
decf I,f
bcf SCL ;SCL a 0
CALL Tempo_11us
rlf I2C_DATA,f ;Rotation a gauche bit(I) dans la carry
btfsc carry ;Si I=1
bsf SDA ;SDA a 1
btfss carry ;Si I=0
bcf SDA ;SDA a 0
bsf SCL ;SCL a 1
CALL Tempo_11us
incf I,f
decfsz I,f ;Si I!=0
goto Next_data_s
bcf SCL ;SCL a 0
CALL Tempo_11us
call I2C_SLAVE_ACK
return
I2C_RECEIVE_BYTE:
movlw d'8'
movwf I
clrf I2C_DATA
SDA_IN ;SDA en entrée
Next_data_r:
decf I,f
bcf SCL ;SCL a 0
CALL Tempo_11us
bsf SCL ;SCL a 1
CALL Tempo_11us
btfsc SDA ;Si SDA=1
bsf carry
btfss SDA ;Si SDA=0
bcf carry
rlf I2C_DATA,f ;décallage à gauche et met la carry dans le LSB
incf I,f
decfsz I,f ;Si I!=0
goto Next_data_r
bcf SCL ;SCL a 0
CALL Tempo_11us
call I2C_MASTER_ACK
return
I2C_RECEIVE_BYTE_LAST:
movlw d'8'
movwf I
SDA_IN ;SDA en entrée
Next_data_rl:
decf I,f
bcf SCL ;SCL a 0
CALL Tempo_11us
bsf SCL ;SCL a 1
CALL Tempo_11us
btfsc SDA ;Si SDA=1
bsf carry
btfss SDA ;Si SDA=0
bcf carry
rlf I2C_DATA,f ;décallage à gauche et met la carry dans le LSB
incf I,f
decfsz I,f ;Si I!=0
goto Next_data_rl
bcf SCL ;SCL a 0
CALL Tempo_11us
call I2C_MASTER_NACK
return
;-----------------------------------------------------------------------------------------
; I2C_flag
; 0: NO_ACK
; 1:
; 2:
; 3:
; 4:
; 5:
; 6:
; 7:
;
NO_ACK:
bsf I2C_flag,0 ;Pas d'ack de l'esclave -> problème de comm
return