嗨,我用I2C解决问题的小贡献:在PIC18F450主控和从机RTC DS1307.RB0和RB1之间进行I2C
通信的汇编代码是SDA和SCL线,不要忘记在两条线路上加上上拉电阻1-4、7K。
以上来自于百度翻译
以下为原文
Hi,
my little contribu
tion to solving problems with I2C:
tested assembly code for I2C communication between master PIC18F4550 and slave RTC DS1307.
RB0 and RB1 are SDA and SCL lines, do not forget to put pull-up resistors 1-4,7k on both lines.
;RTC DS1307:
#define SDA PORTB,0 ;SDA for DS1307
#define SCL PORTB,1 ;SCL fot DS1307
;******************************************************************************
; DS1307 RTC SUBROUTINES *******
;******************************************************************************
INIT_I2C ;MASTER MODE initialization for I2C port:
movlw d'19' ;Baud Rate Generator for 8MHz & 100kHz = d'19'
movwf SSPADD ; I2C
movlw B'11000000' ;
movwf SSPSTAT
movlw b'00101000' ;master mode
movwf SSPCON1
movlw b'00000000' ;
movwf SSPCON2 ; I2C
call WRITE_CONTROL_REG
call WRITE_CH_0 ;to enable internal oscilator
return
;**********************************************************************
WRITE_CONTROL_REG ;write new value to control register:
call START_BIT
movlw h'D0' ;I2C address of DS1307
call WRITE_I2C ; I2C
movlw h'07' ;control register address
call WRITE_I2C
movlw b'10010000' ;new value of control register
call WRITE_I2C ; I2C
call STOP_BIT
return
;**********************************************************************
WRITE_CH_0 ;write 0 to CH-bit in addr. 00 to new DS1307
call READ_TIME_DS1307
btfss SECOND,7
return
call START_BIT
movlw h'D0' ;I2C address of DS1307
call WRITE_I2C ; I2C
movlw h'00' ;address 00 of seconds
call WRITE_I2C
movlw b'00000000' ;new value to seconds register
call WRITE_I2C
call STOP_BIT ; I2C
return
;**********************************************************************
READ_TIME_DS1307 ;read all time registers from DS1307
;set register pointer to 0:
call START_BIT ;
movlw h'D0' ;I2C address of DS1307
call WRITE_I2C
movlw 0x00 ;start address
call WRITE_I2C
call STOP_BIT
;read all data from DS1307:
call START_BIT
movlw 0xD1 ;I2C address of DS1307 + READ bit
call WRITE_I2C
RX_SEC
call READ_I2C ; I2C
movwf SECOND ;save seconds
RX_MIN
call READ_I2C
movwf MINUTE ;save minutes
RX_HOUR
call READ_I2C
movwf HOUR ;save hours
RX_DAY
call READ_I2C ; I2C
movwf DAY ;save day
RX_DATE
call READ_I2C
movwf DATE ;save date
RX_MONTH
call READ_I2C ; I2C
movwf MONTH ;save month
RX_YEAR
call LAST_READ_I2C
movwf YEAR ;save year
call STOP_BIT
return
;*********************************
WRITE_TO_DS1307 ;write new time values to DS1307:
call START_BIT
movlw h'D0' ;I2C address of DS1307
call WRITE_I2C ; I2C
movlw h'01' ;first register address
call WRITE_I2C
movlw b'01000110' ;new BCD minute value
call WRITE_I2C ; I2C
movlw b'00100000' ;new BCD hour value
call WRITE_I2C ; I2C
;....
;....
call STOP_BIT
return
;******************************************************************************
;send 1 byte through I2C:
WRITE_I2C
movwf SSPBUF ; I2C
call WAIT_MSSP
retlw h'00'
;*********************************
;receive 1 byte through I2C + ACK:
READ_I2C
btfsc SSPSTAT,2
goto READ_I2C ; I2C
bsf SSPCON2,RCEN
call WAIT_MSSP
bcf PIR1,SSPIF ; I2C
call ACK_BIT
movf SSPBUF,W ; I2C
return
;*********************************
;receive last byte through I2C + NACK:
LAST_READ_I2C
btfsc SSPSTAT,2
goto LAST_READ_I2C ; I2C
bsf SSPCON2,RCEN
call WAIT_MSSP
bcf PIR1,SSPIF
call NACK_BIT ; I2C
movf SSPBUF,W
return
;*********************************
START_BIT
bsf SSPCON2,SEN
call WAIT_MSSP ; I2C
retlw h'00'
;*********************************
STOP_BIT
bsf SSPCON2,PEN
call WAIT_MSSP ; I2C
retlw h'00'
;*********************************
ACK_BIT
bcf SSPCON2,ACKDT
bsf SSPCON2,ACKEN
call WAIT_MSSP ; I2C
retlw h'00'
;*********************************
NACK_BIT
bsf SSPCON2,ACKDT
bsf SSPCON2,ACKEN
call WAIT_MSSP ; I2C
retlw h'00'
;*********************************
WAIT_MSSP
btfss PIR1,SSPIF ; I2C
goto WAIT_MSSP
bcf PIR1,SSPIF
retlw h'00'
;******************************************************************************