MMSP i2c module; pic16f1824 and 24LC64 EEPROM

Status
Not open for further replies.

Steve311

Member
Hi All, I am using a pic16f1824 and 24lc64 eeprom with the MMSP i2c hardware within the pic.
I have the EEPROM all programmed with a hex file (done through pickit2 software), and I am simply trying to sample read a few address locations within the EEPROM and output them to a hyperterminal (the hyperterminal portion of the program works perfectly fine). I seem to be stuck at the i2c start command and reading the SSP1IF bit within the PIR1 register to see if the first operation, start command, has completed...

This is my first time using the MSSP module and the pic16f1824 so it might be something simple (I previously used a pic16f684 and did the i2c routines all in software)..

I have 2.2k ohm pull-ups on SDA and SCL lines, and I have A2, A1 and A0 on the EEPROM all addressed properly...

Below is my .asm. For a test point within my code, I chose to output a "0x56" to the hyperterminal, and do a continuous loop there so I can step through my program...so As you will notice, under "ByteRead", I call out that routine right after the "Start_Command". I do not get the desired output to the hyperterminal, so I know the i2c bus is getting hung up right at the start command...

Any help? Thanks!

Code:
;Define Constant Working Register Variables 
	cblock 0x20
	i2c_Transmit_Byte
	i2c_Received_Byte
	transmit_byte_rs232
	bit_counter_rs232
	delay_counter
	osc_counter
	pw_counter
	pw_counter1
	datao
	poll_counter

	endc
;.......................................................................................................................
;.......................................................................................................................
;Define Global Deifnitions:	
I2C_PORT	equ		PORTC
I2C_TRIS	equ		TRISC
Write_eeprom equ	0xA0
Read_eeprom	 equ	0xA1
#define		SDA	 	2
#define		SCL 	3
	
;.......................................................................................................................
;.......................................................................................................................
START_PROGRAM
	
Start_Loop


;Initalize i2c communication bus for the uC, Accelerometer and EEPROM. Use MSSP i2c hardware within uC. 
	 
	banksel	SSP1CON2
	
	call	i2c_initialize
	call	ByteRead
	movf	i2c_Received_Byte, w
	call	Transmit_RS_232
done
	goto	done



;---------------------------------------------------------------------------------------
;i2c routines
Start_Command	
    bcf     PIR1,SSP1IF          			; Clear SSP interrupt flag
    bsf     SSP1CON2,SEN          			; Generate Start condition
Start_Bit_Wait
    btfss   PIR1,SSP1IF          			; Check if operation completed
    goto    Start_Bit_Wait       			; If not, keep checking
    return

Repeat_Start_Command
    bcf     PIR1,SSP1IF          			; Clear SSP interrupt flag
    bsf     SSP1CON2,RSEN        			; Generate Restart condition
Repeated_Start_Bit_Wait
    btfss   PIR1,SSP1IF          			; Check if operation completed
    goto    Repeated_Start_Bit_Wait        ; If not, keep checking
    return

Stop_Command
    bcf     PIR1,SSP1IF          ; Clear SSP interrupt flag
    bsf     SSP1CON2,PEN         ; Generate Stop condition
Stop_Bit_Wait
    btfss   PIR1,SSP1IF          ; Check if operation completed
	goto	Stop_Bit_Wait       ; If not, keep checking
    return

;Data transmit routine.
;---------------------------------------------------------------------------------------
i2c_Tx_Byte
    bcf     PIR1,SSP1IF          		; Clear SSP interrupt flag
    movf    i2c_Transmit_Byte, w             ; Copy datao to WREG
    movwf   SSP1BUF              		; Write byte out to device
i2c_Tx_Byte_Wait
    btfss   PIR1,SSP1IF          		; Check if operation completed
	goto	i2c_Tx_Byte_Wait           		; If not, keep checking
;   btfsc   SSPCON2,ACKSTAT     		; Check if ACK bit was received
;   goto	_Error           		; This executes if no ACK received  
    return


;---------------------------------------------------------------------------------------
;Data received routine. 
i2c_Rx_Byte
    bcf     PIR1,SSP1IF          ; Clear SSP interrupt flag
    bsf     SSP1CON2,RCEN        ; Initiate reception of byte
i2c_Rx_Byte_Wait
    btfss   PIR1,SSP1IF          ; Check if operation completed
	goto	i2c_Rx_Byte_Wait            ; If not, keep checking
    movf    SSP1BUF,W            ; Copy byte to WREG
    movwf   i2c_Received_Byte               ; Copy working reg
    bcf     PIR1,SSP1IF          ; Clear SSP interrupt flag
    bsf     SSP1CON2,ACKEN       ; Generate ACK/NO ACK bit    
i2c_Rx_Byte_Wait2
    btfss   PIR1,SSP1IF          ; Check if operation completed
    bra     i2c_Rx_Byte_Wait2           ; If not, keep checking
    return

;i2c Bus initalization
i2c_initialize
	banksel	SSP1STAT
	movlw	0xff
	movwf	TRISC			;Sets Port C to all inputs
	clrf	SSP1STAT 		; Disable SMBus Inputs
	bsf		SSP1STAT,SMP 	; Disable slew rate control
    movlw   0x18            
    movwf   SSPADD          ; Setup 100 kHz i2c clock
    movlw   b'00101000'
    movwf   SSP1CON         ; Enable SSP, select I2C Master mode
    clrf    SSP1CON2         ; Clear control bits
    bcf     PIR1,SSP1IF     ; Clear SSP interrupt flag
    bcf     PIR2,BCL1IF      ; Clear Bit Collision flag
	return

;---------------------------------------------------------------------------------------
;Byte Read i2c routine. 
ByteRead
	banksel	SSP1STAT
    call   	Start_Command             ; Generate Start condition

	movlw	0x56
	call	Transmit_RS_232
done4
	goto	done4

                                ; Send control byte
    movlw   Write_eeprom          ; Load control byte for write
    movwf   datao               ; Copy to datao for output
    call    i2c_Tx_Byte             ; Send control byte to device



                                ; Send word address high byte
    movlw   0x00                ; Load 0x5A for word address
    movwf   datao               ; Copy to datao for output
    call    i2c_Tx_Byte             ; Send high byte to device

                                ; Send word address low byte
    movlw   0x02              ; Load 0x00 for word address
    movwf   datao               ; Copy to datao for output
    call    i2c_Tx_Byte             ; Send word address to device

    call	Repeat_Start_Command ; Generate Restart condition

                                ; Send control byte
    movlw   Read_eeprom         ; Load control byte for read
    movwf   datao               ; Copy to datao for output
    call	i2c_Tx_Byte         ; Send control byte to device

                                ; Read data byte
    bsf     SSP1CON2,ACKDT       ; Select to send NO ACK bit
    call   	i2c_Rx_Byte         ; Read data byte from device

    call	Stop_Command        ; Generate Stop condition

  	return


;---------------------------------------------------------------------------------------
;Acknowledge Polling used for i2c time-out.
i2c_Poll
    movlw   0x20
    movwf   poll_counter            ;Set Delay
polling
    call	Start_Command            ; Generate start bit
    movlw   Write_eeprom          ; Now send the control byte
    movwf   datao               ; Copy control byte to buffer
    call    i2c_Tx_Byte             ; Output control byte to device
    btfss   SSP1CON2,ACKSTAT     ; Was the ACK bit low?
    goto    exitpoll            ; If yes, stop polling
                                ; If no, check if polled 40 times
    decfsz  poll_counter,F           ; Is poll counter down to zero?
    goto    polling             ; If no, poll again
;   bra     TimedOut            ; If yes, part didn't respond
                                ; in time, so take action
exitpoll
    call   	Stop_Command               ; Generate stop bit
    return

;---------------------------------------------------------------------------------------
;Bit Delay used for RS-232 and Hyperterminal
bit_delay
	movlw	0x16
	movwf	delay_counter
bit_wait
	nop
	decfsz  delay_counter, f
	goto	bit_wait
	return
;---------------------------------------------------------------------------------------
;Oscilliator delay to ensure stability when changing frequency.
Osc_Stablize
	movlw	0x0F
	movwf	osc_counter
Osc_Wait
	nop
	nop
	nop
	decfsz	osc_counter, f
	goto	Osc_Wait
	return

;---------------------------------------------------------------------------------------
;Sub routines for PIC to Hyperterminal	
;****SENDS INVERSE LOGIC TO PROLIFIC RS-232 TO USE CONVERTER
Transmit_RS_232	
	banksel	PORTC
	movwf	transmit_byte_rs232		;moves W to transmit_byte, 
;	bsf		STATUS, RP0
	banksel	OSCCON
	movlw	0x6A
	movwf	OSCCON					;load 4MHz internal oscillator
	movlw	0x00
	movwf	TRISC
	movlw	0x00
	movwf	TRISA
;	bcf		STATUS, RP0
	banksel	PORTC
	call	Osc_Stablize
	bcf		PORTC, 5
	movlw	0x08		
	movwf	bit_counter_rs232		;sets 8 bits to send out
	bsf		PORTC, 5
	call	bit_delay
Send_Serial_Loop_RS232
	rrf		transmit_byte_rs232, f		;Send one bit
	btfss 	STATUS,	 C
	bsf		PORTC, 5
	btfsc	STATUS,  C
	bcf		PORTC, 5
	call	bit_delay
	decfsz	bit_counter_rs232, f		;Tests if all done
	goto	Send_Serial_Loop_RS232
	bcf		PORTC, 5
	call	bit_delay
	call	bit_delay
	clrf	transmit_byte_rs232
	clrf	bit_counter_rs232
;	bsf		STATUS, RP0
	banksel	OSCCON
	movlw	0x02						;load 31.25kHz (LF)
	movwf	OSCCON
;	bcf		STATUS, RP0
	banksel	PORTC
	return
;---------------------------------------------------------------------------------------
;Sleep Routine
Sleep_Routine
	movlw	0x07	
	movwf	WDTCON
	sleep
	movlw	0x00	
	movwf	WDTCON
	return


	end
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…