CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problems with writing to 16F877 internal EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Benoit St-Jean
Guest







Problems with writing to 16F877 internal EEPROM
PostPosted: Sun Nov 24, 2002 9:37 pm     Reply with quote

Has anybody ever encountered a problem with writing to the internal EEPROM on a PIC16F877?

I'm using an old version of the PCM compiler (2.660).

There is definitely a problem with the write_eeprom() function. I print a message to an LCD screen just before I call write_eeprom(value). After this command, I write another message to indicate the write was successful. But it doesn't print the second message, my PIC device simply resets.

Anyone has an explanation for this?

Thanks,

Benoit
___________________________
This message was ported from CCS's old forum
Original Post ID: 9355
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Mon Nov 25, 2002 12:55 pm     Reply with quote

:=Has anybody ever encountered a problem with writing to the internal EEPROM on a PIC16F877?
:=
:=I'm using an old version of the PCM compiler (2.660).
:=
:=There is definitely a problem with the write_eeprom() function. I print a message to an LCD screen just before I call write_eeprom(value). After this command, I write another message to indicate the write was successful. But it doesn't print the second message, my PIC device simply resets.
:=
-------------------------------------------------
Can you post a very small program that demonstrates
the problem ? (Be sure to show all the pre-processor
statements and compiler directives).
___________________________
This message was ported from CCS's old forum
Original Post ID: 9406
Benoit St-Jean
Guest







Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Mon Nov 25, 2002 5:36 pm     Reply with quote

:=:=Has anybody ever encountered a problem with writing to the internal EEPROM on a PIC16F877?
:=:=
:=:=I'm using an old version of the PCM compiler (2.660).
:=:=
:=:=There is definitely a problem with the write_eeprom() function. I print a message to an LCD screen just before I call write_eeprom(value). After this command, I write another message to indicate the write was successful. But it doesn't print the second message, my PIC device simply resets.
:=:=
:=-------------------------------------------------
:=Can you post a very small program that demonstrates
:=the problem ? (Be sure to show all the pre-processor
:=statements and compiler directives).

Yeah, I thought of doing this. What I did notice afterwards is that the function write_eeprom() either resets or simply 'hangs' the PIC device when the function is called from within the RB_CHANGE interrupt routine. I found a way around it for now, but I am very interested in finding why this happens because the current way I'm doing it is a "workaround" for now and I cannot use the RB_CHANGE interrupts anymore. The ultimate goal here is to be able to use the RB_CHANGE interrupts and be able to call write_eeprom() in that interrupt routine. I did try to enable the INT_EEPROM interrupt routine, but it does not change anything.

I do call write_eeprom() in the main() program without a problem... it's just when it's called in the RB_CHANGE interrupt isr that it either hangs or resets.

I'll see what I can come-up with.

Thanks.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9418
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Mon Nov 25, 2002 6:02 pm     Reply with quote

:=Yeah, I thought of doing this. What I did notice afterwards is that the function write_eeprom() either resets or simply 'hangs' the PIC device when the function is called from within the RB_CHANGE interrupt routine.
--------------------------------------------------------
Now that you gave a little bit more information, I can tell
you why it's not working.

I compiled the code with PCM vs. 2.660 and 3.110 and looked
at the .LST files. The difference between the two versions
is in how they handle Global interrupts. In 2.660, they
turn off the GIE bit, and when the EEPROM code is done, they
turn it back on again. In 3.110, they first save the state
of the GIE bit, then turn it off. When the EEPROM code is
finished, they restore the GIE bit to its initial state.
So if it was off, they keep it off.

So that's what's causing a problem for you. The GIE bit is
being re-enabled inside your isr. Then you probably get
another interrupt, and CCS can't handle nested interrupts.
CCS can only save the state of the machine once.

I suppose, to fix this, you could write your own routine to
write to EEPROM, and incorporate the changes that I've given
above. You could also remove the call to the write_eeprom
function from the isr, and put it in main(). Just set a flag
in the isr, and poll it in main(). If it's set, then clear
it and do the write to eeprom.

If you want me to post the assembly code from PCM vs. 3.110,
let me know.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9420
Benoit St-Jean
Guest







Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Mon Nov 25, 2002 11:11 pm     Reply with quote

:=:=Yeah, I thought of doing this. What I did notice afterwards is that the function write_eeprom() either resets or simply 'hangs' the PIC device when the function is called from within the RB_CHANGE interrupt routine.
:=--------------------------------------------------------
:=Now that you gave a little bit more information, I can tell
:=you why it's not working.
:=
:=I compiled the code with PCM vs. 2.660 and 3.110 and looked
:=at the .LST files. The difference between the two versions
:=is in how they handle Global interrupts. In 2.660, they
:=turn off the GIE bit, and when the EEPROM code is done, they
:=turn it back on again. In 3.110, they first save the state
:=of the GIE bit, then turn it off. When the EEPROM code is
:=finished, they restore the GIE bit to its initial state.
:=So if it was off, they keep it off.
:=
:=So that's what's causing a problem for you. The GIE bit is
:=being re-enabled inside your isr. Then you probably get
:=another interrupt, and CCS can't handle nested interrupts.
:=CCS can only save the state of the machine once.
:=
:=I suppose, to fix this, you could write your own routine to
:=write to EEPROM, and incorporate the changes that I've given
:=above. You could also remove the call to the write_eeprom
:=function from the isr, and put it in main(). Just set a flag
:=in the isr, and poll it in main(). If it's set, then clear
:=it and do the write to eeprom.
:=
:=If you want me to post the assembly code from PCM vs. 3.110,
:=let me know.

Wow, thanks! That's great! Sure, if you can post the code, it would be very appreciated. I was going to do it myself, but if you have it handy, it will be that much less code to write. I haven't written any PIC apps using the microchip assembly before, so your code would help. I know I would be able, but if you can avoid me all that trouble, I'd be very happy. I sort of found some workaround for it for now, but I'm still not satisfied 100\%. If I stress the circuit, I sometimes seem to be missing one of the values in the EEPROM. This is what I'm currently trying to figure out. I can't have any failures in reading the EEPROM.

And you know what? Your explanation makes a lot of sense now that you've been able to see what is causing this issue because I've tried to write in the EEPROM in another isr (EXT_INT this time instead of RB_CHANGE) and it has the exact same effect - the PIC resets itself....

So the GIE bit is the 'GLOBAL' interrupt. Let's say I can't disable the GIE because I have other interrupts required to occur (RTCC), is there another workaround? Because right now, I disable at the begining of an isr the interrupt for which the interrupt occured:

#int_rtcc rtcc_isr()
{
disable_interrupts( RTCC_ZERO );
[...] my code [...]
enable_interrupts( RTCC_ZERO );
}

I do this type of scenario for each interrupt. I cannot disable the GLOBAL interrupt though... or should I?

The reason is because I'm using 4 bits to display on three 7 segment displays a 3 digit number (through a 74LS47), but I switch from one display to another after 3 RTCC interrupts. This is done so fast that the displays don't flicker and it works well and I see one 3 digit number, not alternating digits. But if I have any type of delay, the displays will flicker, which I have to avoid. So disabling and re-enabling the global interrupt could matter in this situation because the time it takes to execute the code between the "disable" and "enable" could make the display flicker. I'll give it a try anyhow. It's working great so far except for this odd situation where the EEPROM is not read under heavy power supply stress.

Thanks a lot for all your help. This is very appreciated.

Benoit
___________________________
This message was ported from CCS's old forum
Original Post ID: 9424
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Tue Nov 26, 2002 1:23 am     Reply with quote

:=
:=Wow, thanks! That's great! Sure, if you can post the code, it would be very appreciated. I was going to do it myself, but if you have it handy, it will be that much less code to write. I haven't written any PIC apps using the microchip assembly before, so your code would help.
------------

I think you misunderstood me Smile I wasn't going to write
the program for you in C. I'm just going to post the assembly
language listing for write_eeprom(), which was compiled with
PCM vs. 3.110. I'm going to let you compare it to the
listing generated by vs. 2.660, and then translate it to C.
Smile Smile :)

I've commented the code below, to show how it saves the
state of the GIE bit (on or off), and restores it when
the eeprom code is finished. Your version of the compiler
does not do that. Look at your listing file and compare it
to this one.

<PRE>
.................... main ()
.................... {
0004: CLRF FSR
0005: MOVLW 1F
0006: ANDWF STATUS,F
0007: MOVLW 07
0008: BSF STATUS.5
0009: MOVWF ADCON1
000A: BCF STATUS.5
....................
.................... write_eeprom(0, 0x55);
000B: BSF STATUS.6
000C: CLRF EEADR
000D: CLRF EEADRH
000E: MOVLW 55
000F: MOVWF EEDATA
0010: BSF STATUS.5
0011: BCF EECON1.7
0012: BSF EECON1.2
0013: BCF STATUS.5
0014: BCF STATUS.6
0015: MOVF INTCON,W // Save INTCON in a temp register
0016: MOVWF @77
0017: BCF INTCON.7 // Clear the GIE bit
0018: BSF STATUS.5
0019: BSF STATUS.6
001A: MOVLW 55
001B: MOVWF EECON2
001C: MOVLW AA
001D: MOVWF EECON2
001E: BSF EECON1.1
001F: BCF STATUS.5
0020: BCF STATUS.6
0021: BSF STATUS.5
0022: BSF STATUS.6
0023: BTFSS EECON1.1
0024: GOTO 028
0025: BCF STATUS.5
0026: BCF STATUS.6
0027: GOTO 021
0028: BCF EECON1.2
0029: MOVF @77,W // Get INTCON in the W register
002A: BCF STATUS.5
002B: BCF STATUS.6
002C: IORWF INTCON,F // Restore the state of the GIE bit
....................
.................... while(1);
002D: GOTO 02D
.................... }
....................

</PRE>

:=So the GIE bit is the 'GLOBAL' interrupt. Let's say I can't disable the GIE because I have other interrupts required to occur (RTCC), is there another workaround? Because right now, I disable at the begining of an isr the interrupt for which the interrupt occured:
:=
:=#int_rtcc rtcc_isr()
:={
:= disable_interrupts( RTCC_ZERO );
:=[...] my code [...]
:= enable_interrupts( RTCC_ZERO );
:=}

When the PIC responds to an interrupt, it disables the GIE bit
(global interrupts). It enables GIE again when it executes
a RETFIE instruction at the end of the isr function.
CCS doesn't allow nested interrupts. You can't re-enable
interrupts within an isr. At least not with standard CCS code.

So I don't see the reason for disabling RTCC_ZERO interrupts
in the routine above. You aren't going to get an interrupt
in that routine anyway, because GIE is disabled. The only
reason you're seeing an interrupt currently, is because you're
calling write_eeprom() from within that routine.
And, your version of the compiler has a bug, in which the
write_eeprom() function enables the GIE bit when it's done.
It should not do so. That's what is causing your PIC to reset.

___________________________
This message was ported from CCS's old forum
Original Post ID: 9431
R.J.Hamlett
Guest







Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Tue Nov 26, 2002 3:20 am     Reply with quote

:=:=:=Has anybody ever encountered a problem with writing to the internal EEPROM on a PIC16F877?
:=:=:=
:=:=:=I'm using an old version of the PCM compiler (2.660).
:=:=:=
:=:=:=There is definitely a problem with the write_eeprom() function. I print a message to an LCD screen just before I call write_eeprom(value). After this command, I write another message to indicate the write was successful. But it doesn't print the second message, my PIC device simply resets.
:=:=:=
:=:=-------------------------------------------------
:=:=Can you post a very small program that demonstrates
:=:=the problem ? (Be sure to show all the pre-processor
:=:=statements and compiler directives).
:=
:=Yeah, I thought of doing this. What I did notice afterwards is that the function write_eeprom() either resets or simply 'hangs' the PIC device when the function is called from within the RB_CHANGE interrupt routine. I found a way around it for now, but I am very interested in finding why this happens because the current way I'm doing it is a "workaround" for now and I cannot use the RB_CHANGE interrupts anymore. The ultimate goal here is to be able to use the RB_CHANGE interrupts and be able to call write_eeprom() in that interrupt routine. I did try to enable the INT_EEPROM interrupt routine, but it does not change anything.
:=
:=I do call write_eeprom() in the main() program without a problem... it's just when it's called in the RB_CHANGE interrupt isr that it either hangs or resets.
:=
:=I'll see what I can come-up with.
:=
:=Thanks.
First thing to note here. If you have calls to the EEPROM write function in main, and then add calls to this function in the interrupt handler, interrupts will be disabled in the main calls. This has to happen, to prevent the possibility of one write interrupting the other. Generally it is a 'rule of thumb', to keep interrupt handlers as short as possible in time, otherwise you are asking for problems with missed interrupts.
Hence in your situation, you should probably generate a new 'check_eeprom_update' function, which checks a flag to see if an eeprom update is required. You should call this regularly from your main code. Then if you wish to update the eeprom in the main code, you set the flag, and it will be updated the next time this function is called. Similarly in the interrupt code, if an event occurs that requires a write to the eeprom, you can just set the flag here.

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 9434
Benoit St-Jean
Guest







Re: Problems with writing to 16F877 internal EEPROM
PostPosted: Tue Nov 26, 2002 7:30 pm     Reply with quote

:=:=
:=:=Wow, thanks! That's great! Sure, if you can post the code, it would be very appreciated. I was going to do it myself, but if you have it handy, it will be that much less code to write. I haven't written any PIC apps using the microchip assembly before, so your code would help.
:=------------
:=
:=I think you misunderstood me <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0"> I wasn't going to write
:=the program for you in C. I'm just going to post the assembly
:=language listing for write_eeprom(), which was compiled with
:=PCM vs. 3.110. I'm going to let you compare it to the
:=listing generated by vs. 2.660, and then translate it to C.
:=<img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0"> <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0"> <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0">
:=
:=I've commented the code below, to show how it saves the
:=state of the GIE bit (on or off), and restores it when
:=the eeprom code is finished. Your version of the compiler
:=does not do that. Look at your listing file and compare it
:=to this one.
:=
:=<PRE>
:=.................... main ()
:=.................... {
:=0004: CLRF FSR
:=0005: MOVLW 1F
:=0006: ANDWF STATUS,F
:=0007: MOVLW 07
:=0008: BSF STATUS.5
:=0009: MOVWF ADCON1
:=000A: BCF STATUS.5
:=....................
:=.................... write_eeprom(0, 0x55);
:=000B: BSF STATUS.6
:=000C: CLRF EEADR
:=000D: CLRF EEADRH
:=000E: MOVLW 55
:=000F: MOVWF EEDATA
:=0010: BSF STATUS.5
:=0011: BCF EECON1.7
:=0012: BSF EECON1.2
:=0013: BCF STATUS.5
:=0014: BCF STATUS.6
:=0015: MOVF INTCON,W // Save INTCON in a temp register
:=0016: MOVWF @77
:=0017: BCF INTCON.7 // Clear the GIE bit
:=0018: BSF STATUS.5
:=0019: BSF STATUS.6
:=001A: MOVLW 55
:=001B: MOVWF EECON2
:=001C: MOVLW AA
:=001D: MOVWF EECON2
:=001E: BSF EECON1.1
:=001F: BCF STATUS.5
:=0020: BCF STATUS.6
:=0021: BSF STATUS.5
:=0022: BSF STATUS.6
:=0023: BTFSS EECON1.1
:=0024: GOTO 028
:=0025: BCF STATUS.5
:=0026: BCF STATUS.6
:=0027: GOTO 021
:=0028: BCF EECON1.2
:=0029: MOVF @77,W // Get INTCON in the W register
:=002A: BCF STATUS.5
:=002B: BCF STATUS.6
:=002C: IORWF INTCON,F // Restore the state of the GIE bit
:=....................
:=.................... while(1);
:=002D: GOTO 02D
:=.................... }
:=....................
:=
:=</PRE>
:=
:=:=So the GIE bit is the 'GLOBAL' interrupt. Let's say I can't disable the GIE because I have other interrupts required to occur (RTCC), is there another workaround? Because right now, I disable at the begining of an isr the interrupt for which the interrupt occured:
:=:=
:=:=#int_rtcc rtcc_isr()
:=:={
:=:= disable_interrupts( RTCC_ZERO );
:=:=[...] my code [...]
:=:= enable_interrupts( RTCC_ZERO );
:=:=}
:=
:=When the PIC responds to an interrupt, it disables the GIE bit
:=(global interrupts). It enables GIE again when it executes
:=a RETFIE instruction at the end of the isr function.
:=CCS doesn't allow nested interrupts. You can't re-enable
:=interrupts within an isr. At least not with standard CCS code.
:=
:=So I don't see the reason for disabling RTCC_ZERO interrupts
:=in the routine above. You aren't going to get an interrupt
:=in that routine anyway, because GIE is disabled. The only
:=reason you're seeing an interrupt currently, is because you're
:=calling write_eeprom() from within that routine.
:=And, your version of the compiler has a bug, in which the
:=write_eeprom() function enables the GIE bit when it's done.
:=It should not do so. That's what is causing your PIC to reset.
:=

No, I understood you... you misunderstood me! Smile I didn't expect you to write the program. I know you were going to post the asm code for the isr. Maybe I was too 'interrupt happy' when I saw your message and I responded "over-joyly" (with too much joy! ah! ah!). Anyways, thanks for your help, I understand now.

I guess I'll have to buy the new release then.

Thanks again.

Benoit
___________________________
This message was ported from CCS's old forum
Original Post ID: 9478
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group