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

serial polling, software rs232 and timer0

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



Joined: 02 Jul 2005
Posts: 1

View user's profile Send private message

serial polling, software rs232 and timer0
PostPosted: Sat Jul 02, 2005 7:01 pm     Reply with quote

I am still learning, and having a conceptual problem with serial and timer0...

I have managed so far to control a stepper motor, and lcd, and serial tx/rx using a pic linked to a max3701 port expander. The pic16f630 in use didnt have a spi port, so I wrote my own routine, which seems to be working well. The rs232 uses a max232 chip for level shifting.
I would like to have the serial port read and buffered, its using the ccs software rs232 routines, as the pic does not have a built in uart

I could either re-wire the board to use port a and use the interupt on change to use that for the rs232 reading via interrupts, or I could
set up timer0 to interupt every x microseconds thereby polling the serial port on a regular basis. Polling seemed the easier option.... Plus I would learn about timers, so I decided to see what happens if I went that route for now.

If I was to poll the serial via timed interrupts would I be correct in thinking the following..

I need to poll at 10 times the bit rate, so for 9600 baud that would mean
interupting at
1 / (9600x10) = 1.0416666666666666666666666666667e-5
ie approx once every .0000104 seconds

and running with a 20Mhz crystal would give a clock speed of
1 / (20000000 / 4) = 0.0000004

0.0000104 seconds required interupt interval
0.0000004 seconds per timer clock
0.0000104 / 0.0000004 = 26 timer clocks

so no prescaler, and timer set to count to 26 would be correct?
Or have I got the calculation totally wrong somewhere?
Wish I had a scope, could measure the output to see if it is right....

I am trying with the following simple little test routine

Code:

#include <16f630.h>
#fuses HS,NOWDT,NOPROTECT,NOMCLR,BROWNOUT,PUT
// High speed osc, No WatchDog Timer, No Code protext, NoMclr, Brownout reset enabled, Power up timer enabled.
#use delay(clock=20000000)    // HS - High speed crystal osc 20hm, 30picofarad caps

int serin;

#USE  RS232(BAUD=9600 ,XMIT=PIN_C4, RCV=PIN_C5, bits=8, parity=n )
setup_counters(RTCC_INTERNAL, RTCC_DIV_1);
set_timer0(230);

#INT_TIMER0
void serial_timer()
{
   set_timer0(230);
  if(kbhit())
  {
     
      serin = getc();
  }
}

void main()
{
   delay_ms(500);
   puts ("STARTED OK.");
   set_timer0(0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   while (1==1)
   {

      if (serin != 0)
      {
         disable_interrupts(INT_RTCC);
         disable_interrupts(global);
         puts ("*********** FROM INTERUPT *********");
         putc(serin);
         serin = 0;
         enable_interrupts(global);
         enable_interrupts(INT_RTCC);
       }
   }
}



Serial on its own, without any interupts works fine, but the example above hardly ever picks up a character, so I figure I either have the setting of the timer way out, or Im doing something else silly..... Can someone point out where Im going wrong please?
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Jul 02, 2005 9:17 pm     Reply with quote

There is a mistake in your numbers.
Quote:
1 / (20000000 / 4) = 0.0000004


The result should be 1 / (20000000 / 4) = 0.0000002 This will give you a count of 52 timer ticks.

A problem with this type of solution if that you introduce errors as a result of interrupt handler overhead. The time it takes to interrupt the current task, right up to the point where you reset the timer in the interrupt handler. There are a couple of ways of dealing with this. You know that the error will be relatively constant (assuming you do not enable and disable interrrupts in the main line around large blocks of code. So you could subtract a correction factor form your number. (Use a count of 50 for example).

Another option is to choose a different tye of timer. I do not know the PIC you are using but some, such as the 18F PICs, have timer 2 which can be configured with a specific target point value. When the count hits this value it is automatically set to zero at the next timer interval. If I wanted a constant interrupt source at 52 timer ticks, I would set the PR register to 51. This provides me with an accurate time base.

Another method for PICs that do not have this type of timer if to do as you have done but use the PIC's timer to correct itself.

Crudely put Timerx = 230-Timerx
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sun Jul 03, 2005 7:55 am     Reply with quote

Quote:

I could either re-wire the board to use port a and use the interupt on change to use that for the rs232 reading via interrupts, or I could
set up timer0 to interupt every x microseconds thereby polling the serial port on a regular basis. Polling seemed the easier option.... Plus I would learn about timers, so I decided to see what happens if I went that route for now.


IMO, choosing that route all you get is to null other functionalities of a PIC and it's not
the best way to learn how timers works. Use #INT_EXT to ovoid Rx polling overhead
and then you can use some timers if you want to write your own getc() function.
Important key to know is that your code ignore the edge of the START bit and by
extension the BIT-samples would be done out of the right frame.
The code you posted can�t receive 2 consecutive characters. Am I wrong?.

Keep well,

Humberto
kensplace



Joined: 02 Jul 2005
Posts: 1

View user's profile Send private message

thanks
PostPosted: Sun Jul 03, 2005 7:58 pm     Reply with quote

Thanks, I will go down the route of getting the serial to interrupt, instead of using a timer. Just changed board so ra2 is the rx, and got a basic interupt working on it for a single char. Just need to write the buffer now, some nice examples on the forum I will look into.
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