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!
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