Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

HOW TO INTERFACE RTC DS1307 WITH PIC MICROCONTROLLER.

Status
Not open for further replies.
**broken link removed**

connection of I2C is standardized among IC that support this function.
The difference in coding is only the address length. Usually RTC use only 1 byte address, while EEPROM requires 2 bytes
 
It is a very standard interface, but it can be tricky. Here is a section of a working program.

Hope it helps
kent

Code:
	#define I2C_M_SPEED_100K                                 ;
;***********************************************;
; Baud Rate Genarator Reload value              ;
;***********************************************;    
	;I2C_M_SPEED_100K 
_QUOTIENT    EQU    CLOCK_FREQ / (4 * .100000)-1
_REMAINDER   EQU    CLOCK_FREQ % (4 * .100000)  ;
        #if     _REMAINDER != 0                 ;
_I2C_M_BAUD_COUNT    EQU     _QUOTIENT + 1      ; _I2C_MBAUDCOUNT is nearest to ((fosc/4)/I2C_MSPEED)-1,
        #else   ;_REMAINDER = 0                 ; which has to be written in SSPADD.
_I2C_M_BAUD_COUNT    EQU    _QUOTIENT           ; _I2C_MBAUDCOUNT = ((fosc/4)/I2C_MSPEED)-1, which has to be written in SSPADD.
        #endif                                 	; which has to be written in SSPADD.
;-----------------------------------------------;
        #if     _I2C_M_BAUD_COUNT > 255         ;
        ERROR "At this System frequency, the given I2C frequency is not attainable."
        #endif                                  ;
        #if     _I2C_M_BAUD_COUNT < 2           ;
        ERROR "At this System frequency, the given I2C frequency is not attainable."
        #endif                                  ;





;******************************************************************************	
I2C_INIT                                    ;
	movlw   0x028							; Enable MSSP module and Master mode
	movwf   SSPCON1                         ;
	movlw   _I2C_M_BAUD_COUNT				;
	movwf   SSPADD                          ; Loading SSPADD with baudrate generator
	RETURN                                 	;

I2C_SEND                                    ;
	CALL    I2C_WAIT                        ;
	BSF     SSPCON2,SEN                     ; Send START bit
	CALL    I2C_WAIT                       	; Wait till bus becomes Idle
	MOVLW   0x0D0							; SlaveAddress(with write bit)
	CALL    I2C_PUT                      	; Send to buf
	TSTFSZ	WREG
	NOP			;GOTO	I2C_SEND_ERROR					; Error, restart	
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT                      	; Wait till bus becomes Idle

	MOVLW   0x000							; Location Address_HI
	CALL    I2C_PUT                      	;
	TSTFSZ	WREG
	NOP			;GOTO	I2C_SEND_ERROR					; Error, restart
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT                       	; Wait till bus becomes Idle

	BCF		SEC,7							; Enable RTC
	BSF		HOUR,6
	MOVF	SEC,W							; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	MIN,W							; Load W 
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	HOUR,W							; Load W 
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	DAY,W							; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	DATE,W							; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	MONTH,W							; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	YEAR,W							; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	MOVF	I2C_CNTRL,W						; Load W
	CALL	I2C_SEND_DATA_BYTE				; Send The Byte
	BSF     SSPCON2,PEN                     ; Send STOP bit
	BSF		INTCON,GIE
	RETURN
I2C_SEND_DATA_BYTE
	CALL    I2C_PUT                      	;
	TSTFSZ	WREG
	NOP			;GOTO	I2C_SEND_ERROR					; Error, restart
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT						; Wait till bus becomes Idle
	RETURN
	
I2C_SEND_ERROR
	MOVLW	0x000							; Line 1 LOW
	MOVWF	LCD_CUR_ADDR_L					; SET Line 1 LOW
	MOVLW	0x000							; Line 1 HIGH
	MOVWF	LCD_CUR_ADDR_H					; Set Line 1 HIGH
	MOVLW  	0x04C
	MOVWF	LCD_CUR_DIR
	CALL	LCD_SET_ADDR					; Move cursor to 
	MOVLW	0x042
	CALL 	SEND_LCD_CMD					; Send MWRITE Command
	MOVLW	HIGH (MSG_60)           		; "ERROR"
	MOVWF	TABLE_INDEX_HI
    MOVLW	LOW (MSG_60)
    MOVWF	TABLE_INDEX_LO
	CALL	PUT_MSG							; Put on display
	GOTO	I2C_SEND
	
	
I2C_RECEIVE                                	;
	BCF		INTCON,GIE
	BSF     SSPCON2,SEN                     ; Send START bit
	CALL    I2C_WAIT                       	; Wait till bus becomes Idle
	MOVLW   0x0D0							; SlaveAddress(with write bit)
	CALL    I2C_PUT                      	;
	TSTFSZ	WREG
	NOP			;GOTO	I2C_RX_ERROR					; Error, restart
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT                     	; Wait till bus becomes Idle

	MOVLW   0x000                           ; Send LocationAddress_Hi
	CALL    I2C_PUT                      	;
	TSTFSZ	WREG
	NOP			;GOTO	I2C_RX_ERROR					; Error, restart
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT                       	; Wait till bus becomes Idle

	BSF     SSPCON2,RSEN                    ; Send RepeatedSTART bit
	CALL    I2C_WAIT                      	; Wait till bus becomes Idle
	movlw   0x0D1							; Send SlaveAddress(with read bit)
	CALL    I2C_PUT                      	;
	TSTFSZ	WREG
	NOP			;GOTO	I2C_RX_ERROR					; Error, restart
	CALL    I2C_ACK_RECV            		; Check whether Ack received
	CALL    I2C_WAIT                       	; Wait till bus becomes Idle

	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	SEC								; Load SEC
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	MIN								; Load MIN
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	HOUR							; Load HOUR
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	DAY								; Load DAY
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	DATE							; Load DATE
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	MONTH							; Load MONTH
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	YEAR							; Load YEAR
	CALL    SEND_I2C_ACK                    ; Send Ack
	CALL	I2C_RX_DATA_BYTE				; RECV The Byte
	MOVWF	I2C_CNTRL						; Load I2C_CNTRL
	CALL    SEND_I2C_NOACK                  ; Send NoAck if all 16 bytes received
	BSF     SSPCON2,PEN                     ; Send STOP bit
	CALL    I2C_WAIT						; Wait till bus becomes Idle
	BSF		INTCON,GIE
	RETURN
I2C_RX_DATA_BYTE
	BSF     SSPCON2,RCEN                    ; Enable the receiver, Cleared by hardw
	CALL    I2C_WAIT_TILL_RDY          		; Wait till Data is ready
	MOVF    SSPBUF,W                      	; Read received value in W
	RETURN

I2C_RX_ERROR
	MOVLW	0x000							; Line 1 LOW
	MOVWF	LCD_CUR_ADDR_L					; SET Line 1 LOW
	MOVLW	0x001							; Line 1 HIGH
	MOVWF	LCD_CUR_ADDR_H					; Set Line 1 HIGH
	MOVLW  	0x04C
	MOVWF	LCD_CUR_DIR
	CALL	LCD_SET_ADDR					; Move cursor to 
	MOVLW	0x042
	CALL 	SEND_LCD_CMD					; Send MWRITE Command
	MOVLW	HIGH (MSG_60)           		; "ERROR"
	MOVWF	TABLE_INDEX_HI
    MOVLW	LOW (MSG_60)
    MOVWF	TABLE_INDEX_LO
	CALL	PUT_MSG							; Put on display
	GOTO	I2C_RECEIVE

I2C_WAIT_TILL_RDY                         	; Wait till Data is Ready
	BTFSS   SSPSTAT,BF                      ; Checks transmission/reception in progress
	GOTO	I2C_WAIT_TILL_RDY          		;
	RETURN                                  ;

I2C_PUT                                     ;
	MOVWF   SSPBUF                          ; Load Buffer
	BTFSS   SSPCON1,WCOL                    ; Check for collision
	RETLW   0x000							; No Collision, Return
	BCF     SSPCON1,WCOL                    ; Collision, retrn with restart code
	RETLW   0x001							; Indicates Write Collision Error

SEND_I2C_ACK                                ;
	BCF     SSPCON2,ACKDT                   ;
	BSF     SSPCON2,ACKEN                   ; Acknowledge
	CALL    I2C_WAIT                        ; Wait till bus becomes Idle
	RETURN

SEND_I2C_NOACK                             	;
	BSF     SSPCON2,ACKDT                   ;
	BSF     SSPCON2,ACKEN                   ; NoAcknowledge
	CALL    I2C_WAIT						; Wait till bus becomes Idle
	RETURN
	                                        ;
I2C_ACK_RECV                           
	BTFSC	SSPCON2,ACKSTAT                 ;
	GOTO	I2C_NoAckErr                    ; Indicates No Acknowledge received
	RETURN

I2C_NoAckErr								; Slave Error, No Ack
	BSF     SSPCON2,PEN						; Free the Bus if NoAck is received from Slave
	MOVLW	0x000							; Line 1 LOW
	MOVWF	LCD_CUR_ADDR_L					; SET Line 1 LOW
	MOVLW	0x000							; Line 1 HIGH
	MOVWF	LCD_CUR_ADDR_H					; Set Line 1 HIGH
	MOVLW  	0x04C
	MOVWF	LCD_CUR_DIR
	CALL	LCD_SET_ADDR					; Move cursor to 
	MOVLW	0x042
	CALL 	SEND_LCD_CMD					; Send MWRITE Command
	MOVLW	HIGH (MSG_60)           		; "ERROR"
	MOVWF	TABLE_INDEX_HI
    MOVLW	LOW (MSG_60)
    MOVWF	TABLE_INDEX_LO
	CALL	PUT_MSG							; Put on display
	GOTO	MAIN_SCREEN

I2C_WAIT                                    ; Wait till I2C_ Bus is Idle
	CALL	I2C_IS_IDLE                   	;
	TSTFSZ	WREG                            ;
	GOTO	I2C_WAIT						; Not Ready, Loop again
	RETURN                                  ;

I2C_IS_IDLE
	movf    SSPCON2,W                       ;
	andlw   01fh                            ; Checks SEN,PEN,RSEN,RCEN,ACKEN
	btfss   STATUS,Z                        ;
	retlw   0x005							; Indicates Bus is not Idle
	btfsc   SSPSTAT,2						; Checks transmission in progress
	retlw   0x005							; Indicates Bus is not Idle
	retlw   0x000							; Indicates Bus is Idle

;******************************************************************************
 
Almost forgot.
Code:
CBLOCK	0x000
		YEAR
		MONTH
		DATE
		DAY
		HOUR
		MIN
		SEC
		I2C_CNTRL
		ENDC

Look on you data sheet for the ports, and other setup for I2C.
Also, read up on interfacing to EEPROM, it is almost the same.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top