Microchip
直播中

张秀华

7年用户 160经验值
私信 关注
[问答]

I2C通信:18F4550和DS1307 RTC

嗨,我用I2C解决问题的小贡献:在PIC18F450主控和从机RTC DS1307.RB0和RB1之间进行I2C通信的汇编代码是SDA和SCL线,不要忘记在两条线路上加上上拉电阻1-4、7K。

以上来自于百度翻译


      以下为原文

    Hi,
my little contribution 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'
;******************************************************************************

回帖(1)

吴键洪

2018-11-28 16:47:49
谢谢你的贡献。在每次写之后检查ACK位是个好主意,尤其是当你发送从地址时。

以上来自于百度翻译


      以下为原文

    Thanks for contributing.
It would be a good idea to check the ACK bit after each write, particularly when you send the slave address.
 
举报

更多回帖

发帖
×
20
完善资料,
赚取积分