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

problem reading-to/writing-from buffer

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



Joined: 21 Feb 2006
Posts: 2
Location: Buffalo NY

View user's profile Send private message

problem reading-to/writing-from buffer
PostPosted: Wed Feb 22, 2006 2:25 pm     Reply with quote

hello all,
i'm trying to figure out how to write a program that collects some data over rs232, writes it to a buffer, reads the buffer, performs an action based on that data over a period of time, and then reads the data that may have come into the buffer during the time the action was being performed [and then does the action... etc.].

my first attempt used getc() et al to get data from rs232, and this worked well as long as the execution loop (running a stepper motor in this case) finished before more data was sent. if the data was sent while the loop was running, the program would hang after the loop was completed.

i tried to fix this by emulating the example in CCS's ex_sisr.c file. i created a small buffer that could be filled (i hoped) while the output loop was running. allow me to bore you with my code:

Code:

#include <16f876a.h>

#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP,BROWNOUT
#use DELAY(CLOCK=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#use FAST_IO(B)

#include <stdlib.h>

// the following from ccs ex_sisr.c
#define BUFFER_SIZE 4
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#int_rda
void serial_isr() {
   int t;

   buffer[next_in]=getc();
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
     next_in=t;           // Buffer full !!
}

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;

   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

// my code
void main()
{
  char ip[BUFFER_SIZE];//string input buffer
  int32 bn = 0;//big number
  int p;//position number
  int16 time;//
  int j;//index used in buffer
  int1 flag = 0;

  enable_interrupts(global);
  enable_interrupts(int_rda);
 
  printf("Hello .. \r\n");//greeting
  while (1){
   
    if (flag == 1){
      bn=atol(ip);//make it a number
      p=bn/1000;//strip off the top digit
      time=bn-(p*1000);//get the bottom 3 digits
      printf("bn: %lu p: %u time: %lu\r\n", bn, p, time);
      flag = 0;//reset flag
    }
    // below is where output stuff would happen, just a simple
    //countdown in this case
    if (p != 0){
      while (p != 0){
   printf("countdown: %u\r\n", p);
   p = (p - 1);
   delay_ms(500);
      }
    }
   
    while(bkbhit){
      for(j=0;j<=(BUFFER_SIZE - 1);++j){
   ip[j] = bgetc();//get input string one char at a time
   printf("buf: %S %u\r\n", ip, j);// watch the buffer fill (or not)
   if(j==(BUFFER_SIZE - 1))
     flag = 1;//set flag
      }
    }

  }
}


in this case, the last index in the buffer is not filled (or read?) until the output loop ends. this is what the terminal shows - the buffer-filling stuff doesn't display until after the loop has finished whether the data came in during or after its run:
Code:

buf: 8        0
buf: 83      1
buf: 837    2
buf: 8372  3
bn: 8372 p: 8 time: 372
countdown: 8
countdown: 7
countdown: 6
countdown: 5
countdown: 4
countdown: 3
countdown: 2
countdown: 1
buf: 9372.  0
buf: 9972.  1
buf: 9992.  2
buf: 9991.  3
bn: 9991 p: 9 time: 991
countdown: 9
countdown: 8
countdown: 7
countdown: 6
countdown: 5
countdown: 4
countdown: 3
countdown: 2
countdown: 1


i seem to be misunderstanding something fairly basic here - is it clear what i want to do? it seems fairly universal, i just haven't been able to find any other examples out there.

many thanks,
bill
Ttelmah
Guest







PostPosted: Wed Feb 22, 2006 3:49 pm     Reply with quote

Start with your buffer being nowhere near large enough. You delay for 500mSec. In this time, if 9600bps communication runs flat out, you could receive 480 characters...
Don't count through the buffer 'size' in the output. Basically, if bkbhit is set, there are characters waiting. Remember characters can still be arriving while you are printing. Potentially your printout, could take about 15 character times, and another fifteen characters could have been received while you do this. This is why your code stays in the handler, since the output, is taking so long, that when it executes the first time, four characters have already been received, and the routine will loop four times, without a exiting.
Technically, your ip string, needs to be five characters long, with a null terminator in ip[4], otherwise garbage may get printed. That this hasn't happened so far, has been luck...

Best Wishes
bsack



Joined: 21 Feb 2006
Posts: 2
Location: Buffalo NY

View user's profile Send private message

PostPosted: Fri Feb 24, 2006 9:04 pm     Reply with quote

thank you for the clue. i added a null terminator and this made the code do pretty much what i wanted - though it's very ugly looking and i won't be sharing it anytime soon! - but if i continue to read postings here and read some more c texts i may get more of a handle on how to cope with these problems on my own.

thanks again,
bill
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