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

erratic behaviour of write_eeprom

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
quantum mechanic



Joined: 28 Jun 2006
Posts: 3

View user's profile Send private message

erratic behaviour of write_eeprom
PostPosted: Wed Jun 28, 2006 9:51 am     Reply with quote

Hi all, nice to finally be logged in...

I am trying to write some code where my PIC can be put into a setup mode at startup to set some values which are to be used in normal operation. The device is then reset or power cycled with the values carrying through to normal mode. Hence I am planning on storing these values in internal EEPROM.

I am finding that seemingly unrelated changes in other parts of my code affect whether the write_eeprom call actually works. So far, I have pinned the problem down to what you see in the code below. (The first part is the fairly standard routines I use to drive an LCD matrix display. I have included these for completeness.)

Code:

#include <16f870.h>
#fuses NOWDT,HS,NOPUT,NOPROTECT,NODEBUG,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#use delay(clock=20000000)
#use fast_io(C)
#use fast_io(B)

// HD77480 on Port B ------------------------
// N.B. R/W line of HD is wired to WRITE
struct s_lcd
{
   BOOLEAN en;
   BOOLEAN rs;
   int data : 4;
   int unused : 2;
} lcd;

#if defined(__PCH__)
   #byte lcd = 0xf81
#else
   #byte lcd = 6
#endif

void send_nibble(BYTE b)
{
   lcd.data = b;
     lcd.en = 1;   delay_us(20);
   lcd.en = 0;   delay_us(20);
}

void display_char(BYTE b)
{
   // Clear display
   lcd.rs = 0;
   delay_us(5);
   send_nibble(0x00);   send_nibble(0x01);
   delay_ms(2);

   // Write character to display
   lcd.rs = 1;
   delay_us(5);
   send_nibble(b >> 4);   send_nibble(b & 0x0f);         
}

void lcd_init(void)
{
   int8 count;
   lcd.rs = 0;
   delay_ms(1000);
   for(count = 0; count < 3; count++)
   {
       send_nibble(0x03);    // Set 8-bit op
       delay_ms(5);
   }
   send_nibble(0x02);                              // Set 4-bit op
   send_nibble(0x02);   send_nibble(0x08);               // 2 lines, 5x7
   send_nibble(0x00);   send_nibble(0x08);               // Display off
   send_nibble(0x00);   send_nibble(0x01);   delay_ms(2);   // Display clear
   send_nibble(0x00);   send_nibble(0x0c);               // Display on, cursor off
   send_nibble(0x00);   send_nibble(0x06);               // Entry mode set   
}

//-------------------------------------------

void main(void)
{
   int8 value;
   int8 count;
   
   //set_tris_c(0b00000000);   // Causes eeprom write to fail
   set_tris_c(0b11111111);   // Causes eeprom write to succeed
   set_tris_b(0x00);  // Does not affect eeprom
   lcd_init();
   
   write_eeprom(11, 'a');
   delay_ms(100);
   
   for(count = 0; count < 4; count++)
   {   
      value = read_eeprom(11);      
      display_char(value);
      value++;      
      write_eeprom(11, value);
      delay_ms(200);
   }
}


This code reads a value from eeprom, displays, increments, then writes back. When the code works I can see a...b...c...d on the display. Otherwise, I just get whatever value was held in the eeprom at startup.

I find that with TRISC set to 0xff, write operations are completely reliable, but for certain other values, e.g. 0x00, the thing just does not store the data.

Why should a call to set_tris_c affect the operation of write_eeprom?

Has anyone else had a similar experience?

I got this far:
* I am using EEPROM addresses that I know are fresh and have not been fatigued by too many write operations. (Address 11 was picked for this reason and is arbitrary)
* The code simulates perfectly in MPLAB even when it fails on chip.
* This set_tris_c business is the one thing I have found which definitely affects writes, but not necessarily the only change I could have made in my full code to have this effect. (The code I present here is purely to demonstrate the problem)

System:
XP Pro 32, PIC16F870, CCS-C PCB/M/H v3.245, MPLAB v7.10, PICSTART Plus
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 28, 2006 10:47 am     Reply with quote

Quote:
I find that with TRISC set to 0xff, write operations are completely
reliable, but for certain other values, e.g. 0x00, the thing just does not
store the data.

What external components or chips are connected to Port C ?
Describe them in detail, giving component values.
quantum mechanic



Joined: 28 Jun 2006
Posts: 3

View user's profile Send private message

PostPosted: Thu Jun 29, 2006 9:04 am     Reply with quote

Dead simple components...

The way I want Port C set up is:

e.g. set_tris_c(0b00110000);

the 2 inputs are connected through push-to-make switches to ground, pulled to Vcc when open with 1k resistors (i.e. an active-low configuration)

the outputs drive LEDs to ground through 360R resistors

I could change these pin assignments - it's mainly a case of what was easiest on stripboard

Port B drives a HD44780 display module through 6 lines (see code), the other 2 lines (RB6,7) are used for ICSP

All other ports open circuit, apart from RA0 which connects to the sweeper of a 5k pot between Vcc and 0V (I will eventually use a/d on AN0)

Vcc is 5V.

Hope this helps
quantum mechanic



Joined: 28 Jun 2006
Posts: 3

View user's profile Send private message

PostPosted: Thu Jun 29, 2006 9:05 am     Reply with quote

... oh and I don't touch the buttons during execution of this code, so consider them high inputs
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 29, 2006 1:33 pm     Reply with quote

There are two ways you can trouble-shoot this.

Hardware approach:
Disconnect external circuits from Port C, one pin at a time.
Keep testing the program until you find out which pin (or pins) is
causing the problem. Or, try it a different way. First remove
all LED circuits. See if it now works. If not, remove the switch
circuits, including the resistors, and test it. Etc.

Software approach:
Set the bit mask for set_tris_c() to 0xFE (1111 1110) and see if
you get the problem. If not, change it to 0xFD (1111 1101) and
try again, etc. Or, do it by groups of circuits. Set both LED pins
to be inputs.


Also, your test program as posted, will fall off the end of main() and
the PIC will execute a sleep instruction (put there by the compiler).
You should prevent this by putting a while(1); statement right before
the closing brace of main().
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