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

strtok problem

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



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

strtok problem
PostPosted: Fri Mar 14, 2008 5:29 pm     Reply with quote

hi pro's
i do some test to get a sentence from rs232 and strtok it from spaces, as shown from TX code, i send two sentence but just one of them appear on RX
here is tx code:
Code:

#include <16f874.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

void main(){
while(1) {

         printf("HOW ARE YOU MY LORD\r\n") ;
         delay_ms(5000);
         printf("ONE TOW THREE FOUR FIVE\r\n") ;
         delay_ms(5000);
}
}//END MAIN



and RX code:
Code:

#include <16f877a.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20000000)
#include <string.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include "lcd_d.c"
char string[30], term[3], *ptr,s1[10],s2[10],s3[10],s4[10],s5[10],RX[50];
int f,i;
int1 flag=0;

#int_rda
void serial_isr()  {
RX[i++]=getch();
flag=1;
}

void main(){
   f=1;
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);

   LCD_Init ( );
   LCD_PutCmd ( CLEAR_DISP );
   strcpy(term," ");
   while(1){

   if(flag==1){
   ptr = strtok(RX, term);

   while(ptr!=0) {
   if(f==1)
   strcpy(s1,ptr);
   if(f==2)
   strcpy(s2,ptr);
   if(f==3)
   strcpy(s3,ptr);
   if(f==4)
   strcpy(s4,ptr);
   if(f==5)
   strcpy(s5,ptr);

   ptr = strtok(0, term);
   ++f;
   }
    puts(s1);
    delay_ms(100);
    puts(s2);
    delay_ms(100);
    puts(s3);
    delay_ms(100);
    puts(s4);
    delay_ms(100);
    puts(s5);
    delay_ms(100);

    LCD_SetPosition(0x81);
    printf(LCD_PutChar,s1);
    LCD_SetPosition(0x85);
    printf(LCD_PutChar,s2);
    LCD_SetPosition(0x8a);
    printf(LCD_PutChar,s3);
    LCD_SetPosition(0xc1);
    printf(LCD_PutChar,s4);
    LCD_SetPosition(0xc7);
    printf(LCD_PutChar,s5);
   
   delay_ms(1000);
    flag=0;
    f=1;
    strcpy(RX," ");
   }//end flag
}// end while
}// end main





its supposed to print
HOW
ARE
YOU
MY
LORD

and after 5 sec
ONE
TWO
THREE
FOUR
FIVE

but it print just first segment, and after 5 sec (next interrupt occurrence ) print the first segment again!!!code do this for many times then stop working.
i use Proteus 6 Professional simulation
please if you can help me

Reagrds
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Mar 14, 2008 7:59 pm     Reply with quote

Code:
#int_rda
void serial_isr()  {
RX[i++]=getch();
flag=1;
}


Two major problems:
1) You never reset i.
2) You set flag as soon as the first character is received. This makes no sense as your main loop is now going to process a string that's not completely received.

I'm surprised your program is even behaving a bit as expected, this must be so because you are running the same test again and again. RAM is not cleared in between the tests and still contains the data from the previous test which makes it behave good. You ever wondered why the program failed the first time?

A possible fix is to set the ready flag only after receiving the end-of-line character.
Code:
#int_rda
void serial_isr()
{
  char temp;

  temp = getch();
  if (flag == 0)        // Ignore all data when not ready to receive
  {
    RX[i++] = temp;
    if (temp == '\n')  // if end of line received
    {
      flag=1;         // then set ready flag
      RX[i]=0;        // Terminate string
    }
  }
}


...and change the end of your main to:
Code:
   delay_ms(1000);
    flag=0;
    f=1;
    i=0;                        // Added
    memset(RX, 0, sizeof(RX));  // this resets the whole array. Original code only cleared first two characters.
hadeelqasaimeh



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

PostPosted: Fri Mar 14, 2008 8:42 pm     Reply with quote

thank you ckielstra
unfortunately still there is some problem!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Mar 15, 2008 4:29 am     Reply with quote

My mind reading is not as good as it used to be. If you want us to help you, you will have to describe the problem.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sat Mar 15, 2008 8:50 am     Reply with quote

ckielstra is right it is not enough to say I have a problem will someone give me the solution. Transferring the information to another person to help with an issue often requires a logical approach. Often times it is the lack of a logical approach that requires the assistance of another in the first place. So there is a conflict. But try to develop the skill to transfer appropriate information. Posting the whole program obviously is a complete transfer but few will want to take the time to tease out errors in another persons often illogical code. PCM programmer's advice is to pare your code down to the bare minimum. Many times just doing this will let you solve your issue yourself. EX the missing initialization of the RX buffer position pointer variable i would have been caught by almost all coders had the code been pared down to just reading chars and viewing them in the buffer.
hadeelqasaimeh



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

PostPosted: Sat Mar 15, 2008 5:52 pm     Reply with quote

actually i face problem with English language sometimes, i will try to give you good explain soon, anyway i see pcm programmer answers in this post
http://www.ccsinfo.com/forum/viewtopic.php?t=22049&highlight=strtok
and i will try to rebuild code,thank you!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Mar 16, 2008 7:12 am     Reply with quote

Your English was no problem to me, only a bit short sometimes. When you say 'there is some problem' I can't help you because that's not enough information. Did the changes I proposed make it better or worse? What do you see happening? etc.

You noticed Douglas Kennedy found another bug in your program? At program start you forgot to initialize variable i.
Code:
void main(){
   f=1;
   i=0;   // add this line !!!
hadeelqasaimeh



Joined: 05 Jan 2006
Posts: 105

View user's profile Send private message

PostPosted: Sun Mar 16, 2008 6:32 pm     Reply with quote

ckielstra,thank you very much for follow up,
i go back from beginning, i think there were many error in last code, so as i said before i go back,and start with this code [PCM code] :

Code:

#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <string.h>

void main(){

      char *ptr;
      char string[20];
      char term[10];
         
      strcpy(string, "one two three");
      strcpy(term, " ");
   
      ptr = strtok(string, term);
     
      while(ptr!=0)
         {
          puts(ptr);
          ptr = strtok(0, term);
         }
     
      while(1);  // Prevent the PIC from going to sleep
      }

i simulate it, output was
one
two
three


cool, now if add more words to string as four five six.... and increas string buffer to 40 so i modify code to:

Code:


#include <16f877a.h>
#fuses xt,NOWDT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>


void main(){

      char *ptr;
      char string[40];
      char term[10];
         
      strcpy(string, "hello my lord one two three four");
      strcpy(term, " ");
   start:       
      ptr = strtok(string, term);
     
      while(ptr!=0)
         {
          puts(ptr);
          ptr = strtok(0, term);
         }

   delay_ms(1000);
     goto start;  // Prevent the PIC from going to sleep
      }



output is:
hello
my
lord
one
two
three
four
hello
hello
hello
hello
hello
.
.
.
i predict to get
hello
my
lord
one
two
three
four
and repeat again,right?!

note: overall code aims to read from rs232 and parse the string them\n put each one as single word,buffer in range of 70, and finally i do simulation with isis professional

i hope this post is clear now Embarassed
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Mar 16, 2008 8:07 pm     Reply with quote

From the CCS manual on strtok():
Quote:
If one is found, it is overwritten by '\0', which terminates current token.
Your problem is that strtok() modifies the input string, all spaces get replaced by a 0.
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