#include <p16f877a.inc>
__config 3f39
;RTC DS1307
cmd_byte RES 1
Main
BANKSEL TRISC ; initialize MSSP module
bsf TRISC,3 ; configure PORTC<3> as input
bsf TRISC,4 ; configure PORTC<4> as input
clrf TRISD ; make PORTB an output
banksel PORTD
CLRF PORTD
;################################################################################
;# STEP 1: Set the slew rate and baud rate for 100 MHZ operation
;################################################################################
BANKSEL SSPSTAT ; ### point to correct BANK for SSPSTAT
bsf SSPSTAT,SMP ; ### Set for Standard speed slew rate
movlw b'1101'
movwf SSPADD ; set the address of the slave device
;################################################################################
;# STEP 2: Configure MSSP as I2C master with Internal (Fosc/4) Clock source and
;# enable SDA and SCL pins to operate in I2C mode (SSPCON)
;################################################################################
BANKSEL SSPCON
bsf SSPCON,SSPM3 ; ### set to I2C master mode with Fosc/4
bsf SSPCON,SSPEN ; ### Enable SDA and SCL for I2C
BANKSEL SSPCON2 ; ensure SSPCON2 is cleared
clrf SSPCON2
;-----------------------------------
; Put '0000001' into variable cmd_byte.
; This is the read commnd that will be sent to the RTC
BANKSEL cmd_byte
movlw 0x05 ; config register command byte
movwf cmd_byte
;-----------------------------------
; MAIN PROGRAM LOOP
;-----------------------------------
Loop
;################################################################################
;# STEP 3: Initiate an I2C "START condition" and test for when it completes
;################################################################################
BANKSEL SSPCON2 ; switch to bank containing SSPCON2
bsf SSPCON2,SEN ; ### Initiate a START condition
btfsc SSPCON2,SEN ; ### Test if it is finished?
goto $-1 ; If not, re-execute previous instruction
;-----------------------------------
movlw B'11010000' ; send address of RTC w/0 in the LSB
BANKSEL SSPBUF ; send RTC ADDRESS (write)
movwf SSPBUF
btfsc SSPSTAT,R_W ; wait for write to complete
goto $-1
;-----------------------------------
BANKSEL SSPCON2 ; Wait for ACK from RTC
btfsc SSPCON2,ACKSTAT ; ack?
goto $-1
;-----------------------------------
BANKSEL cmd_byte ; send the READ command
movf cmd_byte,W ; send COMMAND byte (config)
BANKSEL SSPBUF
movwf SSPBUF
movlw 0x00
BANKSEL SSPCON2
sublw 0x00
btfss STATUS,Z
goto $-4
btfsc SSPSTAT,R_W
goto $-1
;-----------------------------------
BANKSEL SSPCON2 ; get ACK from RTC
btfsc SSPCON2,ACKSTAT ; ack?
goto $-1
bsf SSPCON2,RSEN ; resend START condition
btfsc SSPCON2,RSEN ; send repeated start
goto $-1
movlw B'11010000' ; send RTC ADDRESS
BANKSEL SSPBUF ; with READ bit set
movwf SSPBUF
movlw 0x00
BANKSEL SSPCON2
andwf SSPCON2,w
sublw 0x00
btfss STATUS,Z
goto $-4
btfsc SSPSTAT,R_W
goto $-1
;-----------------------------------
BANKSEL SSPCON2 ; get ACK from RTC
btfsc SSPCON2,ACKSTAT ; ack?
goto $-1
bsf SSPCON2,RCEN ; receive RTC
btfsc SSPCON2,RCEN ; enable receive mode
goto $-1
BANKSEL SSPBUF ; retrieve RTC reg
movf SSPBUF,w ; put measured TIME into WREG
;-----------------------------------
NACK
BANKSEL SSPCON2 ; send NOT-ACK condition
bsf SSPCON2,ACKDT
bsf SSPCON2,ACKEN
btfsc SSPCON2,ACKEN
goto $-1
STOP
bsf SSPCON2,PEN ; send stop condition
btfsc SSPCON2,PEN
goto $-1
;-----------------------------------
BANKSEL PORTD ; send LSB of temp data to PORTB
movwf PORTD
nop
goto Loop
;-----------------------------------
END ; directive telling MPASM that code is done