|
|
View previous topic :: View next topic |
Author |
Message |
KennyK Guest
|
16F877A write/read eeprom issues |
Posted: Thu Aug 11, 2005 1:26 pm |
|
|
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
|
|
Posted: Thu Aug 11, 2005 3:06 pm |
|
|
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
|
|
Posted: Mon Aug 15, 2005 10:41 am |
|
|
Thanks for your help. I was able to get the code working from your tips.
Thanks again. |
|
|
|
|
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
|