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

Using timed_getc with several software USARTs

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



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

Using timed_getc with several software USARTs
PostPosted: Thu Sep 01, 2005 7:08 am     Reply with quote

Hi,

Compiler: PCM 3.1619

My project consists of a PIC 16F877 which is the master PIC and three slaves ( one is a 16F877, the others are 16F628). I am using software USARTs to communicate with these PICs.

To receive data I am using the timed_getc() given in CCS help. Based on this I have written the following code for three software USARTs

Code:


//The USART configuration is as follows. and is declared in the start of the code

#use rs232(baud=300,xmit=pin_c6, rcv=pin_c7,parity=n,stream=PC,errors)
#use rs232(baud=300,xmit=pin_c5, rcv=pin_c2,parity=n,brgh1ok,stream=LASER,INVERT)
#use rs232(baud=9600,xmit=pin_d0, rcv=pin_d4,parity=n,brgh1ok,stream=RHSROTATION,errors)
#use rs232(baud=9600,xmit=pin_d5, rcv=pin_d6,parity=n,brgh1ok,stream=LHSROTATION,errors)


char timed_getc(char cSelDevice)
 {

     long timeout;
   
     timeout_error=FALSE;
     timeout=0;


      switch(cSelDevice)
      {

         case 'R':         //Right Sensor

                     while(!kbhit(RHSROTATION)&&(++timeout<50000))   // 1/2 second
                        delay_us(10);
                  
                     if(kbhit(RHSROTATION))
                          return(fgetc(RHSROTATION));
                     else
                     {
                          timeout_error=TRUE;
                          return(0);
                     }
   
                  break;


         case 'L':         //Left Sensor

                   
                     while(!kbhit(LHSROTATION)&&(++timeout<50000))   // 1/2 second
                        delay_us(10);
                  
                     if(kbhit(LHSROTATION))
                          return(fgetc(LHSROTATION));
                     else
                     {
                          timeout_error=TRUE;
                          return(0);
                     }
                  
   
                  break;


         case 'B':         //Laser Controller

                  
                     while(!kbhit(LASER)&&(++timeout<50000))   // 1/2 second
                        delay_us(10);
                  
                     if(kbhit(LASER))
                          return(fgetc(LASER));
                     else
                     {
                          timeout_error=TRUE;
                          return(0);
                     }
                                    

                  break;

      }



}




Is the above code OK ,if any modifications are required kindly post them...

thanks
arunb
Ttelmah
Guest







PostPosted: Thu Sep 01, 2005 8:48 am     Reply with quote

Within it's limitiations, it'll pretty nearly work as expected. The timeout will be somewhat more than 0.5 seconds in each loop, because the extra test in the loop will take time. It depends on your clock frequency, but at 4MHz for example, the timout will probably be nearly 1 second, rather than 0.5 seconds.
The main limitation, is that data _will_ be lost, unless you are sitting waiting in this loop for each device when it sends. Note also that the 'errors' directive, basically does nothing on the software UARTs. There are some wasted areas of code (for instance, there is no point in using the 'else' statement after each kbhit test, since you have already left the routine with 'return', in the case that data has been fetched. The optimiser may almost remove the extra code this generates, but it might save a byte or two to do this yourself.

Best Wishes
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE;
PostPosted: Fri Sep 02, 2005 2:08 am     Reply with quote

hi,

The trouble with the above piece of code is that I tend to get invalid characters, so I modified the use rs232 command by adding a force_sw and sample_early commands.

This improved matters and I received data correctly, but I noticed that data came out quite slowly.

My question is ..

a. Is the KBHIT function being used correctly, KBHIT(Stream)... ??
b. Do I have to put the #Use RS 232 diretive before each case statement in the timed_getc() function ??

Note: Crystal is 4 Mhz

Thanks
arnb
Ttelmah
Guest







PostPosted: Fri Sep 02, 2005 5:24 am     Reply with quote

If you are getting corrupted chaacters, and 'sample early' helps, then the characters have almost certainly started _before_ you call the routine.
Force_sw has no effect on pins that don't have hardware UART's.
It will be slow. At 300bps, a character will take approximately 33000 instruction times to arrive.
Yes, kbhit(stream) is correct (provided your compiler is reasonably recent), and the stream ability removes the need for seperate USE_RS232 statements inside the code.

Best Wishes
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE;
PostPosted: Sat Sep 03, 2005 1:33 am     Reply with quote

Hi,

Thank you for the help.

I noticed that force_sw delayed the transmission (even at 9600 bauds), also sometimes commands where entirely ignored.

The slave PICs send an acknowledge character immediately after receiving a command from the master, there could be a slight delay in the reciving part and the processing, say a few instructions.

Please note the slave PICs use INT_RDA to receive commands.


Do you think a slight delay of a few milliseconds just after receiving should improve matters ??

thanks
arunb
Eugeneo



Joined: 30 Aug 2005
Posts: 155
Location: Calgary, AB

View user's profile Send private message

PostPosted: Mon Sep 05, 2005 1:49 am     Reply with quote

I don't know if this is really necessary but at those baud rates and that processor, you may should be able to go to 20 mhz, use 2 of your timers and with the INT_CCP for input 1, IN_EXT for input 2. Use hardware usart for input 3. And bit bang input 1&2. This way you won't miss any data.
Ttelmah
Guest







PostPosted: Mon Sep 05, 2005 4:48 am     Reply with quote

I'd try with something like this:
Code:

//The USART configuration is as follows. and is declared in the start of the code

#use rs232(baud=300,xmit=pin_c6, rcv=pin_c7,parity=n,stream=PC,errors)
#use rs232(baud=300,xmit=pin_c5, rcv=pin_c2,parity=n,stream=LASER,INVERT)
#use rs232(baud=9600,xmit=pin_d0, rcv=pin_d4,parity=n,stream=RHSROTATION)
#use rs232(baud=9600,xmit=pin_d5, rcv=pin_d6,parity=n,stream=LHSROTATION)
//brg10Kh only applies when you are using a baud rate generator.
//Similarly 'errors' only applies with a hardware UART.


char timed_getc(char cSelDevice)
 {

     long timeout;
   
     timeout_error=FALSE;
     timeout=0;


      switch(cSelDevice)
      {

         case 'R':         //Right Sensor

                     while(input(PIN_D4)&&(++timeout<50000))   // 1/2 second
                        delay_us(2);
                   
                     if(input(PIN_D4)) {
                          timeout_error=TRUE;
                          return(0);
                     }
                     else
                          return(fgetc(RHSROTATION));
   
                  break;


         case 'L':         //Left Sensor

                   
                     while(input(PIN_D6)&&(++timeout<50000))   // 1/2 second
                        delay_us(2);
                   
                     if(input(PIN_D6)) {
                          timeout_error=TRUE;
                          return(0);
                     }
                     else
                          return(fgetc(LHSROTATION));
               
                  break;


         case 'B':         //Laser Controller

                   
                     while(!input(PIN_C2)&&(++timeout<50000))   // 1/2 second
                        delay_us(2);
                   
                     if(input(PIN_C2))
                          return(fgetc(LASER));
                     else
                     {
                          timeout_error=TRUE;
                          return(0);
                     }
                  break;
      }
}

This uses direct input, rather than 'kbhit' to check for the line changing. Though the compiler ought to optimise this fairly well, it'd be interesting to see if this improves things. Also the delay count is reduced to allow for the time taken in the test. My 'guess' would be that the test for the 'edge', would take about two to four instructions, while the increment, and test, could easily take another six or more instructions. With the delay in the loop, and the jump time itself, this means that the loop, is probably taking something more in terms of 20 to 30uSec. As such, on the existing code, if the edge goes 'active', immediately after the last test, it'll not actually start reading the character, for perhaps 40 to 50uSec (once round the loop, jump to exit, test again, then start the actual sample), which may be why 'sample early' is helping. Reducing the delay, should improve this.

Best Wishes
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Mon Sep 05, 2005 8:44 am     Reply with quote

Hi,

I solved the problem, here is what I did..

I retained the original code, as posted, but I delayed the transmission in the slave PICs by 100 micro seconds. This solved the problem, firstly there was no delay in receiving
the characters, and also I received no un wanted characters..


Thanks a lot for the help and suggestions...

arunb
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