View previous topic :: View next topic |
Author |
Message |
MotoDan
Joined: 30 Dec 2011 Posts: 55
|
RS232 Timeout interaction with Timer0 |
Posted: Wed Jul 17, 2013 12:30 pm |
|
|
Hello all,
I have a strange problem with my Timer0 ISR changing interrupt intervals and it appears to be related to the 'timeout' parameter of the #use rs232.
Timer0 is set to interrupt at 1ms which is does reliably - as long as there is serial data streaming into the board (no timeouts).
If I change the rs232 'timeout', I can see the change in the Timer0 interval.
I'm using a PIC16F1517 with PCM 4.132.
Any ideas? Compiler issue perhaps? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 17, 2013 12:56 pm |
|
|
Post a small, compilable test program that shows the problem.
The program should be ideally not more than 20 lines. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
Re: RS232 Timeout interaction with Timer0 |
Posted: Thu Jul 18, 2013 2:04 am |
|
|
Few PIC EUARTS have timeout in hardware, so if you specifiy a timeout in #use rs232 CCS C generally has to implement a software UART. Only a few recent PICs have hardware that has serial timeout capability.
I don't know exactly what's happenning, but you need to be aware that software UARTS behave differently to hardware. When you try to receive, the software UART has to sit and wait in code until a character comes in. Possibly other interrupts are disabled for some or even all of that waiting time, especially if timeouts are required as that timing needs to be reasonably accurate. Also serial ISRs are generally not called from software UARTS as interupts come from hardware.
We need to see your code - the simplest compilable code that shows the problem - to be able to make any more suggestions.
RF Developer |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jul 18, 2013 2:30 am |
|
|
No, it doesn't switch to using a software UART.
Doesn't have to.
All it does, is loops for a defined 'time', checking the RCIF bit. If at any point this goes 'true', it reads the character, and exits with this. If the time runs out, it exits returning zero, and setting the errors value to zero as well.
It doesn't affect the timer. I've used it fine. The only 'time' the timer behaviour would get affected, is if you have set the option 'disable_interrupts=TRUE'. Then it disables the interrupt as soon as it is called, and this remains disabled till it exits. You don't want this with the hardware UART anyway...
The timeout code is 'roughly' equivalent to:
Code: |
#define WAITFOR (100)
#define DISABLE_INTS (TRUE)
#byte GIE=getenv("BIT:GIE")
int8 timed_getc()
{
int16 countdown;
int1 intbit;
intbit=GIE; //check if interrupts are enabled
disable_interrupts(GLOBAL);
countdown=WAITFOR;
//Now loop for 'WAITFOR' msec, or till a character arrives
do
{
if (kbhit())
{
//Character has arrived
if (intbit)
enable_interrupts(GLOBAL); //re-enable interrupts if they were on
return getc(); //return the character
}
delay_ms(1);
} while(--countdown>0);
if (intbit)
enable_interrupts(GLOBAL);
//In the real routine, would also set RS232_ERRORS here to zero.
return 0;
}
|
I'd guess the poster has the disable_interrupts flag turned on.
Best Wishes |
|
|
|