|
|
View previous topic :: View next topic |
Author |
Message |
rrrr Guest
|
Found same string repeating |
Posted: Mon Dec 28, 2009 6:42 am |
|
|
I am sending and writing different strings to I[] and P[], but when I am reading found same string from both. What's going wrong? Please help me in resolving the problems.
Code: |
void write_string_ext_eeprom(long int add,char* data)
{
long int loc=0;
for (loc = 0; loc <= strlen(data); loc++)
{
if ( loc < strlen(data))
write_ext_eeprom((loc+add), data[loc]);
else write_ext_eeprom((loc+add), '\0');
}
}
char read_string_ext_eeprom(long int add)
{
long int loc=0;
char* data;
for (loc = 0; loc < 30; loc++)
{
if(read_ext_eeprom(loc+add)=='\0')
{
data[loc]=read_ext_eeprom(loc+add);
break;
}
else
{
data[loc]=read_ext_eeprom(loc+add);
}
}
return *data
}
Char I[],P[];
void read()
{
P=read_string_ext_eeprom(70);
N=read_string_ext_eeprom(120);
}
void writegpnvm()
{
write_string_ext_eeprom(70,P);
write_string_ext_eeprom(120,N);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 28, 2009 1:26 pm |
|
|
Quote: | char read_string_ext_eeprom(long int add)
{
long int loc=0;
char* data;
for (loc = 0; loc < 30; loc++)
{
if(read_ext_eeprom(loc+add)=='\0')
{
data[loc]=read_ext_eeprom(loc+add);
break;
}
else
{
data[loc]=read_ext_eeprom(loc+add);
}
}
return *data
}
|
You are writing to memory with an initialized pointer.
The pointer does not point to any memory array. Therefore,
you are overwriting random memory blocks in the PIC's ram space.
This may cause the program to crash or behave erratically.
Also, I think that you believe are returning a pointer, but you are not.
You're returning a char that 'data' is pointing to.
See this tutorial on common mistakes in C. This section is about
uninitialized pointers:
http://www.drpaulcarter.com/cs/common-c-errors.php#2.8
Also, read item #3 in the section on "Don't return a pointer to a local variable" in a function:
http://www.openismus.com/documents/cplusplus/cpointers.shtml
Here you have two arrays, but there is no RAM allocated to them.
You can't just start writing to an uninitialized pointer. You will
overwrite other RAM locations, which may be assigned to your
other variables. |
|
|
rrrr Guest
|
still not solved. |
Posted: Mon Dec 28, 2009 10:46 pm |
|
|
tried this way also still am getting same problem...
Code: | char read_string_ext_eeprom(long int add)
{
long int loc=0;
char data[30];
for (loc = 0; loc < 30; loc++)
{
if(read_ext_eeprom(loc+add)=='\0')
{
data[loc]=read_ext_eeprom(loc+add);
break;
}
else
{
data[loc]=read_ext_eeprom(loc+add);
}
}
return data;
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 28, 2009 11:40 pm |
|
|
Post your current, compilable test program. It should have the #include
for the PIC, #fuses, etc., and the routines, and a main() which calls the
routines and displays the result with printf statements.
Post what you see displayed on the terminal window, and also post what
you want it to display, if it was working.
Are you testing this in hardware or in a simulator ?
Also post your compiler version. |
|
|
rrrr Guest
|
its working in test code but.... |
Posted: Tue Dec 29, 2009 2:53 am |
|
|
hi PCM
Its working with test code on hardware but when i integrate into actual Project the problem persist.the actual code has same pic and fuses with many buffers,2 serial interfaces,RTC,LCD,ADC,GPS and many more tasks...
at present i just want to know whether the writing and reading string functions are correct or not so that i can find the bug in actual project code.
Test Code:- Code: |
#include <18f4620.h>
#device adc=10
#fuses HS,WDT,NOPROTECT,BROWNOUT
#use delay(clock=20000000,RESTART_WDT)
#use i2c(MASTER,SDA=PIN_D2,SCL=PIN_D3,RESTART_WDT)
#USE RS232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,stop=1,parity=n,STREAM=SM,timeout=1000,restart_wdt)
#include<float.h>
#include<math.h>
#include<stddef.h>
#include<string.h>
#include<stdlib.h>
#byte PORTA = 0xF80
#byte PORTB = 0xF81
#byte PORTC = 0xF82
#byte PORTD = 0xF83
#byte PORTE = 0xF84
#define EEPROM_SDA PIN_D2
#define EEPROM_SCL PIN_D3
#define sda EEPROM_SDA
#define scl EEPROM_SCL
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 65535
#define CR 0x0D
char buf[240];
CHAR C=34;
char I[],P[];
byte flag=0;
int1 RC_timeout=false;
int8 waitfor;
#define second (77)
#int_timer0
void timer0isr()
{
if (waitfor) --waitfor;
else RC_timeout=true;
}
void ftget_string(char *s, int max, int ticks){
int len,cps=0;
char c;
waitfor=ticks;
RC_timeout=false;
set_timer0(0);
clear_interrupt(int_timer0);
enable_interrupts(INT_TIMER0);
--max;
len=0;
do{
while(!kbhit(SM)){
if(RC_timeout){
c=10;
break;
}
}
if (kbhit(SM))
c=fgetc(SM);
if ((c>=' ')&&(c<='~'))
if(len<=max){
s[len++]=c;
//putc(c);
}
}while(c!=10);
s[len]=0;
disable_interrupts(INT_TIMER0);
}
#INT_RDA
void serial_isr()
{
ftget_string(buf, 200, second);
flag=1;
}
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
i2c_stop();
}
BYTE read_ext_eeprom(long int address) {
BYTE data;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}
void write_string_ext_eeprom(long int add,char* data)
{
long int loc=0;
for (loc = 0; loc <= strlen(data); loc++)
{
if ( loc < strlen(data))
write_ext_eeprom((loc+add), data[loc]);
else write_ext_eeprom((loc+add), '\0');
}
}
char read_string_ext_eeprom(long int add)
{
long int loc=0;
char data[30];
for (loc = 0; loc < 30; loc++)
{
if(read_ext_eeprom(loc+add)=='\0')
{
data[loc]=read_ext_eeprom(loc+add);
break;
}
else
{
data[loc]=read_ext_eeprom(loc+add);
}
}
return data;
}
void intialize()
{
set_tris_a(0X03);
set_tris_b(0x00);
set_tris_d(0x07);
set_tris_e(0x00);
set_Tris_C(0b10101101);
set_rtcc(0);
delay_ms(200);
init_ext_eeprom();
delay_ms(20);
}
void parsing()
{
char term[3],st[240],*ptr;
int rs=0;
strcpy(st,buf);
strcpy(term,",");
ptr = strtok(st, term);
while(ptr!=0){
++rs;
if(rs==2)
{
strcpy(I,ptr);
write_string_ext_eeprom(70,I);
}
if(rs==3)
{
strcpy(P,ptr);
write_string_ext_eeprom(120,P);
}
ptr = strtok(0, term);
}
}
void main()
{
setup_adc( ADC_CLOCK_INTERNAL );
setup_adc_ports(AN0);
set_adc_channel(0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_8);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
intialize();
SETUP_WDT(WDT_ON);
while(true)
{
if(flag==1)
{
parsing();
flag=0;
}
if(flag==0)
{
read_string_ext_eeprom(70);
read_string_ext_eeprom(120);
fprintf(SM,"\r\nRead From EEPROM IS:%s\r\n%s\r\n",I,P);
flag=2;
}
}
} |
PC to PIC:-
start,testprogram,success,notsuccessed\r\n
PIC to PC:-
Read From EEPROM IS:testprogram
success |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 29, 2009 10:14 am |
|
|
Just some remarks, not a complete list:
- Type variable names consistently. The CCS compiler is not case sensitive so your code compiles, but this is not according to the C-standard and makes reading more difficult. Add '#case' to the start of your program.
- Use indentation to make your program easier to read.
- Add the 'ERRORS' keyword to your #rs232 line to avoid the UART from blocking at receiver overflow.
Code: | setup_spi(SPI_SS_DISABLED); | This is an error in the CCS setup Wizard and creates an invalid hardware setup. Change to
- You enable INT_RTCC at program start. This starts your time-out timer and is not as intended.
- By default the CCS compiler handles the TRIS registers. Your setting of the TRIS registers will be overruled unless you add the '#use fast_io' or '#use fixed_io' directives.
- Pointers I and P are not initialised, i.e. they are pointing to a random memory location. So in the strcpy calls you are copying data to unknown destinations and overwriting existing data.
- NEVER do a get_string call from within INT_RDA! Just yesterday Ttelmah explained again why not to do this. Read his answer here |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 29, 2009 12:11 pm |
|
|
Quote: | char read_string_ext_eeprom(long int add)
{
long int loc=0;
char data[30];
for (loc = 0; loc < 30; loc++)
{
if(read_ext_eeprom(loc+add)=='\0')
{
data[loc]=read_ext_eeprom(loc+add);
break;
}
else
{
data[loc]=read_ext_eeprom(loc+add);
}
}
return data;
}
|
In addition to all that, this routine has two bugs.
1. You're returning a pointer to a local array. I gave you a link which
explains why this is a "no no".
2. Then, you're returning a pointer, but you've declared the function
as returning a 'char'. That's not correct. |
|
|
rrrr Guest
|
Thnaks a lot... |
Posted: Wed Dec 30, 2009 3:27 am |
|
|
hi pcm programmer
Thanks a lot. I changed the code according to the concepts/links you provided. Now its working good. |
|
|
|
|
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
|