Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] problem in my pic assembly code (interfacing i2c eeprom)

Status
Not open for further replies.

pratzz

Member level 5
Joined
Jun 15, 2012
Messages
83
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,288
Activity points
1,781
Code:
list p=16F877a
#include <p16F877a.inc>
errorlevel -302
__config _XT_OSC & _WDT_OFF & _LVP_OFF
;-------------------------------------------
; SPECIAL FUNCTION REGISTERS
;-------------------------------------------
indf	    	equ 00
tmr0	    	equ 01
pcl	   	        equ 02
status	      	equ 03
fsr	   	        equ 04
portb	     	equ 06
portc           equ 07
portd	     	equ 08
pclath	     	equ 0Ah
pir1            equ 0ch
pir2            equ 0dh
sspcon          equ 14h
adcon1	    	equ 1Fh	; other bank
sspcon2         equ 11h
sspadd          equ 13h
sspstat         equ 14h

;-------------------------------------------
; GENERAL PURPOSE REGISTERS
;-------------------------------------------
		CBLOCK 20h
count
count1
dat
disp
pollcnt
		ENDC
;-------------------------------------------
; PORTC	bits
;-------------------------------------------
  SCK 	equ 3
  SDI 	equ 4
  SDO 	equ 5
  CS 	equ 7
;-------------------------------------------
; PORTB	bits
;-------------------------------------------
rs		equ 0
rw		equ 1
en		equ 2
;-------------------------------------------
;*******************Macro definitions*****************************
WRITE_ADDR  equ     b'10100000' ; Control byte for write operations
READ_ADDR   equ     b'10100001' ; Control byte for read operations
;----- PIR1 Bits ----------------------------------------------------------

PSPIF                        EQU     H'0007'
ADIF                         EQU     H'0006'
RCIF                         EQU     H'0005'
TXIF                         EQU     H'0004'
SSPIF                        EQU     H'0003'
CCP1IF                       EQU     H'0002'
TMR2IF                       EQU     H'0001'
TMR1IF                       EQU     H'0000'

;----- PIR2 Bits ----------------------------------------------------------

CMIF                         EQU     H'0006'
EEIF                         EQU     H'0004'
BCLIF                        EQU     H'0003'
CCP2IF                       EQU     H'0000'

;----- SSPCON Bits --------------------------------------------------------

WCOL                         EQU     H'0007'
SSPOV                        EQU     H'0006'
SSPEN                        EQU     H'0005'
CKP                          EQU     H'0004'
SSPM3                        EQU     H'0003'
SSPM2                        EQU     H'0002'
SSPM1                        EQU     H'0001'
SSPM0                        EQU     H'0000'

;----- SSPCON2 Bits --------------------------------------------------------

GCEN                         EQU     H'0007'
ACKSTAT                      EQU     H'0006'
ACKDT                        EQU     H'0005'
ACKEN                        EQU     H'0004'
RCEN                         EQU     H'0003'
PEN                          EQU     H'0002'
RSEN                         EQU     H'0001'
SEN                          EQU     H'0000'

;----- SSPSTAT Bits -------------------------------------------------------

SMP                          EQU     H'0007'
CKE                          EQU     H'0006'
D                            EQU     H'0005'
I2C_DATA                     EQU     H'0005'
NOT_A                        EQU     H'0005'
NOT_ADDRESS                  EQU     H'0005'
D_A                          EQU     H'0005'
DATA_ADDRESS                 EQU     H'0005'
P                            EQU     H'0004'
I2C_STOP                     EQU     H'0004'
S                            EQU     H'0003'
I2C_START                    EQU     H'0003'
R                            EQU     H'0002'
I2C_READ                     EQU     H'0002'
NOT_W                        EQU     H'0002'
NOT_WRITE                    EQU     H'0002'
R_W                          EQU     H'0002'
READ_WRITE                   EQU     H'0002'
UA                           EQU     H'0001'
BF                           EQU     H'0000'
;----- STATUS Bits --------------------------------------------------------

IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'

 ;--------------------------------------------------------------------

		ORG 0
		clrf status
		movlw 00
		movwf pclath
		goto start
;-------------------------------------------
		org 04
		retfie

;-----------------------------------------------------------------
lcd_cmd
        movwf portd
        bcf portb,rs
        bcf portb,rw
        bsf portb,en
        call delay
        bcf portb,en
        retlw 00h
;------------------------------------------------------------------
lcd_data
        movwf portd
        bsf portb,rs
        bcf portb,rw
        bsf portb,en
        call delay
        bcf portb,en
        retlw 00h
;------------------------------------------------------------------
lcd_init
        movlw 38h
        call lcd_cmd
        call delay
        movlw 0eh
        call lcd_cmd
        call delay
        movlw 01h
        call lcd_cmd
        call delay
        movlw 06h
        call lcd_cmd
        call delay
        movlw 80h
        call lcd_cmd
        call delay
        call delay
         retlw 00h
;-------------------------------------------------------------------
delay
        movlw 02h
        movwf count
here2   movlw 0ffh
        movwf count1
here    decfsz count1,1
        goto here
        decfsz count,1
        goto here2
        retlw 00h
;-----------------------------------------------------------------


initialise


		bcf status,RP1
		bsf status,RP0
        clrf portb
		clrf portd
		movlw b'00000111'
		movwf adcon1
        movlw b'11111111'
        movwf   portc               ; Set PORTC to all inputs
        clrf    sspstat             ; Disable SMBus inputs
        bsf     sspstat,SMP         ; Disable slew rate control
        movlw   09h                ; Load 0x18 into WREG
        movwf   sspadd              ; Setup 100 kHz I2C clock
        clrf    sspcon2
		bcf     status,RP0
        movlw   b'00101000'
        movwf   sspcon              ; Enable SSP, select I2C Master mode
        bcf     pir1,SSPIF          ; Clear SSP interrupt flag
        bcf     pir2,BCLIF
		retlw 00
;--------------------------------------------------------------
genstart
   
    bcf     STATUS,RP1
    bcf     STATUS,RP0          ; Select Bank 00
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,SEN         ; Generate Start condition
    bcf     STATUS,RP0          ; Select Bank 00
    start_wait
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    start_wait          ; If not, keep checking
    retlw   0
genstop
    bcf     STATUS,RP1
    bcf     STATUS,RP0          ; Select Bank 00
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,PEN         ; Generate Stop condition
    bcf     STATUS,RP0          ; Select Bank 00
stop_wait
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    stop_wait          ; If not, keep checking
    retlw   00
genrepstart
    bcf     STATUS,RP1
    bcf     STATUS,RP0          ; Select Bank 00
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,RSEN        ; Generate Restart condition
    bcf     STATUS,RP0          ; Select Bank 00
    repstart_wait
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    repstart_wait       ; If not, keep checking

    retlw   0
;-------------------------------------------------------------
receive
    movlw   0c0h
    call lcd_cmd
    bcf     STATUS,RP1
    bcf     STATUS,RP0          ; Select Bank 00
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,RCEN        ; Initiate reception of byte
    bcf     STATUS,RP0          ; Select Bank 00
rx_wait
    
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    rx_wait             ; If not, keep checking
    movf    SSPBUF,w           ; Copy byte to WREG
   ; movwf   dat                 ; Copy WREG to datai
   ;movf    dat,w
    call lcd_data
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,ACKEN       ; Generate ACK/NO ACK bit
    bcf     STATUS,RP0          ; Select Bank 00
rx_wait2
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    rx_wait2            ; If not, keep checking

    retlw   0
;-------------------------------------------------------------
transmit
    bcf     STATUS,RP1
    bcf     STATUS,RP0          ; Select Bank 00
    bcf     PIR1,SSPIF          ; Clear SSP interrupt flag
    movf    dat,w               ; Copy dat to WREG
    movwf   SSPBUF              ; Write byte out to device
tx_wait
    btfss   PIR1,SSPIF          ; Check if operation completed
    goto    tx_wait             ; If not, keep checking
    bcf     pir1,SSPIF
    bsf     STATUS,RP0          ; Select Bank 01
    btfsc   SSPCON2,ACKSTAT     ; Check if ACK bit was received
    call    ackfailed           ; This executes if no ACK received

    retlw   0
;-------------------------------------------------------------- 
;-----------------------------------------------------------
    byteread
    call    genstart              ; Generate Start condition

                                       ; Send control byte
    bcf     STATUS,RP0          ; Select Bank 00
    movlw   WRITE_ADDR          ; Load control byte for write
    movwf   dat                    ; Copy to datao for output
    call    transmit                 ; Send control byte to device

               ; Send word address high byte
    bcf     STATUS,RP0          ; Select Bank 00
    movlw   12h               ; Load 0x5A for word address
    movwf   dat               ; Copy to datao for output
    call    transmit                 ; Send high byte to device

                                ; Send word address low byte
    call    genrepstart            ; Generate Restart condition

                                ; Send control byte
    bcf     STATUS,RP0          ; Select Bank 00
    movlw   READ_ADDR           ; Load control byte for read
    movwf   dat                 ; Copy to datao for output
    call    transmit                 ; Send control byte to device
                               ; Read data byte
    bsf     STATUS,RP0          ; Select Bank 01
    bsf     SSPCON2,ACKDT       ; Select to send NO ACK bit
    bcf     status,RP0
    call    receive              ; Read data byte from device
    call    genstop               ; Generate Stop condition
    
    retlw   0

bytewrite

    call    genstart            ; Generate Start condition
                             ; Send control byte
    bcf     STATUS,RP0          ; Select Bank 00
    movlw   WRITE_ADDR          ; Load control byte for write
    movwf   dat                 ; Copy to dat for output
    call    transmit            ; Send control byte to device
  
    movlw   12h
    movwf   dat
    call    transmit
   
    movlw   'a'
    movwf   dat
    movwf   disp
    call    transmit
    call    genstop  
  
    movf    disp,w
    call    lcd_data   
    retlw   00
 ackfailed
    bcf status,RP0
    movlw 'E'
    call lcd_data
    retlw 00
;-------------------------------------------
; Main program starts
;-------------------------------------------
start		call initialise
            call lcd_init
            
            call bytewrite
            call byteread
           
 x           goto x
          end
the problem is tat ack is not being received at all in the part of code given below
Code:
    btfsc   SSPCON2,ACKSTAT     ; Check if ACK bit was received
    call    ackfailed
 
Last edited:

thnk u for trying to help me but i'm nt finding it useful
 

my code is like this only,sumhw my pic is nt receiving acnowledge signal from eeprom

- - - Updated - - -

my code is like this only,sumhw my pic is nt receiving acnowledge signal from eeprom
 

Hi,

I have only used SPI EEProm so do not know all the I2C routine.

You only show that little tx snippet, nothing about what chip your are using, in case your banking is wrong, or as to how your whole I2C routine is set up.

Perhaps if you post your complete source code, with the .hex and .dsn file someone can better help you find the error.

That WinpicProg tutorial is a good proven one if you want to follow it from the beginning, perhaps prove your design with that code which might give you knowledge to see where your own code has gone wrong.
 

i hav loaded the full code now as per your suggestion
 

Hi,

Have looked at your code and found some basic errors, so until you correct those its not worth checking any further.

I'm using Mplab v8.80 and it would not build the code , so not sure how you could run it ?

Have ammended your code so it builds but it may not be correct until you check all of the code for the errors.

Its 2 things, first the SFR, Special Function Registers are all defined in the 877a.INC file, located in MPASM directory.
These system registers locations can not and must not be changed.

As you can see from the error report it seems you have changed them, assume its all your own coding ??
Also you have listed many other SFR in the code, simply not needed, the second line of code includes them for you #include pic16f877a.inc

Second you have got your bank select bits mixed up, as shown use the banksel directive, much easier and clearer.
Like RP0/1 you only need use it when changing Banks

Have used a row of **** to highlight the changes I have made, but you need to go though all the code checking correct banks are being used.
 

Attachments

  • eeprom.rar
    75 KB · Views: 72
  • Like
Reactions: pratzz

    pratzz

    Points: 2
    Helpful Answer Positive Rating
actually i'm using mplab x and i'm frced to write these equ defn even after including file 16f877a ,i hav done glce interfacing 3 days ago like this only and tested it on hardware.
my build is coming out to be succesful and changes are being reflected on proteus,however if i dnt define those equ defn here then my compiler shws error

- - - Updated - - -

actually i'm using mplab x and i'm frced to write these equ defn even after including file 16f877a ,i hav done glce interfacing 3 days ago like this only and tested it on hardware.
my build is coming out to be succesful and changes are being reflected on proteus,however if i dnt define those equ defn here then my compiler shws error
 

I want share one thing here.....I2C bus require a pull up resistors so please check that there are pull up avalible on the SDA and SCL lines of PIC15F877a ....sencond point is if they are not there connect 4.7kohm pull-up there .....

Good Luck
 

i kknow that,thx by the way.
 

there may be one more thing that you need do in the config file is keep brown out detection off and oscillator frequecy one need to be very clear about that....Look on the simulation software like proteus will not show this kind of error or problem.... well I am not the assembly programming person....just trying to share some my experiences...

Good Luck
 

ya suffred frm tat prob while i was doing glcd interfacing but right nw sumthng else is wrng

- - - Updated - - -

ya suffred frm tat prob while i was doing glcd interfacing but right nw sumthng else is wrng
 

Hi,

It does not matter if you are using MPlab8, X, Y or Z, to compile, you cannot change SFR addresses and must get your Banking correct for the SFR and User Registers.

I assume you have loaded and are using all the Default settings of Mplab X.

In X, with default settings, you have two more problems you need to address.

The first 4 lines, the LIST, INCLUDE and CONFIG statements - change them to those shown in the pic below.

Second, all your 'LABELS' the register names like STATUS , PORTB are by default only recognised by the complier if the are in Capitals.
Thats why it appeared to you that the Include statement was not working - it will when you get your code right.

You have two options, change all your register Labels to Capitals now or change the Case Sensistivity parameter shown in the pic.
Personally perfer to have then in caps, but your choice.

Once that is done then the project will build without errors , but be careful you do not miss any Warnings that may have scrolled above the viewing area.
 

Attachments

  • ScreenShot002.jpg
    ScreenShot002.jpg
    164.2 KB · Views: 101
  • Like
Reactions: pratzz

    pratzz

    Points: 2
    Helpful Answer Positive Rating
Are you having problems with the actual device or simulating it in Proteus? I2C on PIC processors in Proteus is not fully implemented until version 7.10 SP1 (the latest version), if you are using a older version of Proteus it will not work.
 
  • Like
Reactions: pratzz

    pratzz

    Points: 2
    Helpful Answer Positive Rating
Are you having problems with the actual device or simulating it in Proteus? I2C on PIC processors in Proteus is not fully implemented until version 7.10 SP1 (the latest version), if you are using a older version of Proteus it will not work.
my version is 7.6. i hav not implemented it in original device yet

- - - Updated - - -

Hi,

It does not matter if you are using MPlab8, X, Y or Z, to compile, you cannot change SFR addresses and must get your Banking correct for the SFR and User Registers.

I assume you have loaded and are using all the Default settings of Mplab X.

In X, with default settings, you have two more problems you need to address.

The first 4 lines, the LIST, INCLUDE and CONFIG statements - change them to those shown in the pic below.

Second, all your 'LABELS' the register names like STATUS , PORTB are by default only recognised by the complier if the are in Capitals.
Thats why it appeared to you that the Include statement was not working - it will when you get your code right.

You have two options, change all your register Labels to Capitals now or change the Case Sensistivity parameter shown in the pic.
Personally perfer to have then in caps, but your choice.

Once that is done then the project will build without errors , but be careful you do not miss any Warnings that may have scrolled above the viewing area.

YA itz nw wrking the compile part ,dont knw about my code.
thank u for this useful information
 

Are you having problems with the actual device or simulating it in Proteus? I2C on PIC processors in Proteus is not fully implemented until version 7.10 SP1 (the latest version), if you are using a older version of Proteus it will not work.

thanks a ton,wen i tested it on hardware it wrked ,proteus cost me a day though :(
 

As you have discovered I"C is not implemented on Proteus 7.6, time for you to upgrade to 7.10 sp1 I think where I2C on the PIC processor has finally been implemented.
 

yes ,i will .u dnt knw my state of mind i hav rechecked my code atleast 15 times sincee yesterday bt couldnt find nething wrong.thank u once again
 

yes ,i will .u dnt knw my state of mind i hav rechecked my code atleast 15 times sincee yesterday bt couldnt find nething wrong.thank u once again


Hi,

Did you look at the code I sent; did you check all your banking; did you turn off the case sensistivity or change your labels to Caps and apply those extra 4 lines I mentioned.

I did that and it compiles properly without all those extra EQUs.

However nothing displays on the lcd does it ? - also you see nothing on the pics ports other than grey boxes - correct ?

I do not know which eeprom you are using, or what crystal frequency, but I have guessed at 4 meg.

However that does not work, looking at your code in more details shows you have not set up the i/o Ports correctly.

The PORT is used to read or write Data, but before you can do that properly you must set the Direction of the Port, Input or Outputs.
This is done with the TRIS instruction, it defaults at power on to all INPUTS so you have to set PORTB,C,D to OUTPUTS.


I have added these TRISC instructions and as you can see it does seem to work in part, it clearly sends and receives your 'a' .
I have not looked at your I2C routine in detail.

The attatched code was compiled in X

Would suggest you read and follow that WinPicprog I2c routine in detail.
 

Attachments

  • eeprom.rar
    1.8 KB · Views: 74
  • ScreenShot001.jpg
    ScreenShot001.jpg
    48.1 KB · Views: 97

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top