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 support@ccsinfo.com

16F877A write/read eeprom issues

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







16F877A write/read eeprom issues
PostPosted: Thu Aug 11, 2005 1:26 pm     Reply with quote

Hello all,

The problem that I am having is that I am trying to write/read values into the eeprom. I am able to read the eeprom, ask for an address to change and then ask for a value to put into the eeprom(in hex) (implemented in case ('C')). But what i really want to do is to read a value from the adc and store it into the eeprom (case('T')). With the program i have below, when i try to read_adc() and then anter it into the eeprom, I only get 00 in the eeprom( I intially though that it may have been that I was reading an analog value off RA1, and then sending a digital signal off RA0, so I commented out the digitasl portion and I got the same result). I am reading a voltage off the adc that is fairly small (.2-2 V), but if I read the manual correctly, I should be able to measure this just fine. I have checked my supply voltage (since I am referencing it) and it is a very steady supply (4.99xV +/-.003). I have also used some capacitors as bandpass filters to get rid of some noise that I was initially getting.

I have tried going through the forums as much as possible and I have been trying to implement sending a 16 bit in 2 parts (since the eeprom is only 8 bits in the 16f877A) as well, but I seem to have not been successful.

Also, I was curious if the complier version (3.148) that I had was correctly setting up the adc (although I beleive it is since I was able to get readings off it (in case('C')) and I converted it by dividing by 1024 and then multiplying by 5 and it was the correct answer), but I saw some posts that seemed to say that this version was too old.....???? However, in case('C') when I try to convert the int16 photo to float photo2, it does not display correctly, I only get .000. I have checked the RA1 pin on the PIC and it is getting a nice clean voltage.

#include "C:\light dimmer\tester.h"
#include <input.c>
#include <math.h>

EXT_isr() {

}

// The following initializes the first 4 locations of the data EERPOM
// using the #ROM directive
#IF defined (__PCM__)
#rom 0x21={1,2,3,4}
#elif defined(__PCH__)
#rom int 0xf00000={1,2,3,4}
#endif

int16 photo;//value off adc
float photo2;//converted value


void main() {

byte answer,i,j,address;
int16 value;


setup_adc_ports(RA0_RA1_RA3_ANALOG);
setup_adc( ADC_CLOCK_DIV_8 );
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(FALSE);
setup_vref(FALSE);
enable_interrupts(INT_EXT);
enable_interrupts(global);

delay_ms(10);
printf("\f"); //clears screen
delay_ms(10);
printf("Make a selection:\n\r");//sets up menu
delay_ms(10);
printf("\n\r");
delay_ms(10);
printf("*****\n\r");
delay_ms(10);
printf("T=Calibration\n\r");
delay_ms(10);
printf("C = Flash LED\n\r");
delay_ms(10);
printf("D = Test\n\r");
delay_ms(10);
printf("E = End\n\r");
delay_ms(2000);

do {
answer = getc();
}
while(answer!='T' && answer!='C' && answer!='D' && answer!='E');

switch (answer)
{
case ('T'):
{
set_adc_channel(1);//channel RA1 for cal photo cell
delay_us(60);
do {
printf("\r\n\nEEPROM:\r\n"); // Display contents of the first 64
for(i=0; i<=3; ++i) { // bytes of the data EEPROM in hex
for(j=0; j<=15; ++j) {
printf( "%2x ", read_eeprom( i*16+j ) );
}
printf("\n\r");
}
printf("\r\nLocation to change: ");
address = gethex();
value = read_adc();
delay_us(100);
printf("\r\nNew value: %3Ld", value);//print voltage value

write_eeprom( address, *(&value +1 ));

// printf("\r\n\nEEPROM:\r\n"); // Display contents of the first 64
//for(i=0; i<=3; ++i) { // bytes of the data EEPROM in hex
// for(j=0; j<=15; ++j) {
// printf( "%2x ", read_eeprom( i*16+j ) );
// }
// printf("\n\r");
//}
//delay_ms(2000);

printf("\r\n*****\n\r");
delay_ms(10);
printf("Calibration\n\r");
delay_ms(5);
printf("complete\n\r");
delay_ms(1000);
answer='A';//restart main
break;
} while (true);

break;

}
case ('C'):
{
set_adc_channel(1);//channel RA1 for cal photo cell
delay_us(60);
photo = read_adc();
delay_us(500);
printf("Bytes = %lu\n\r", photo);
delay_ms(1000);
photo2 = (photo/1024)*5;//conversion
printf("Voltage = %1.3f\n\r", photo2);
delay_ms(1000);

output_high(PIN_A0);//flash LED
delay_ms(100);
output_low(PIN_A0);
delay_ms(100);
output_high(PIN_A0);
delay_ms(100);
output_low(PIN_A0);
delay_ms(100);
output_high(PIN_A0);
delay_ms(100);
output_low(PIN_A0);
delay_ms(100);

answer='A';//restart main

break;
}
case ('D'):
{
printf("Test");
delay_ms(1000);
answer='A';//restart main
break;
}
case ('E'):
{printf("thank you\n\r");
delay_ms(1000);
answer='A';//restart main
break;
}
default:
printf("wrong answer");
delay_ms(10);
printf("try again");
answer='A';//restart main
break;
}

reset_cpu();


}

header file

#include <16F877A.h>
#device adc=10
#use delay(clock=4000000)
#fuses HS,PUT,NOWDT,NOLVP,NOBROWNOUT
#use RS232(baud=2400,xmit=PIN_C6,rcv=PIN_C7)

I know that it is a lot and thanks for any help.
Ttelmah
Guest







PostPosted: Thu Aug 11, 2005 3:06 pm     Reply with quote

There are a series of comments, without looking too far.
The address to program the EEPROM in PCM, is 0x2100, not 0x21. 0x21, will be overwriting part of the code...
Put something (even if only a one byte operation), into the int_ext routine. On some compiler versions, a 'blank' routine gets optimised completely away. If this happens, the interrupt may never get cleared...
Most of the problems with 16 chips, had been fixed well before 3.148. It is the 18 chips that still have faults.
Why use two counters to access the eeprom?. One is smaller, and simpler coding...
There is no need to delay after reading the ADC.
Are you sure the 'address' value is being set right. Print this as well to check.
Your address arithmetic is wrong. If you increment a pointer to a 16bit number, it points to the _next_ 16bit number in memory (not the next byte). Do the output as:
write_eeprom(address, make8(value,0));
write_eeprom( address, make8(value,1));

To send the two bytes (LSB first).

To get to the second byte of a 16bit number, using pointer arithmetic, take the address, and cast it to be a pointer to an 8bit value, then increment this).

Best Wishes
KennyK
Guest







PostPosted: Mon Aug 15, 2005 10:41 am     Reply with quote

Thanks for your help. I was able to get the code working from your tips.

Thanks again.
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