![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
microkid
Joined: 17 May 2007 Posts: 2
|
Two USARTS |
Posted: Thu May 17, 2007 2:25 am |
|
|
Hi...
I am working on a project that requires two USARTS, using a PIC18F4520 running at 16MHz.
The baud rate on both USARTS has to be 9600.
The hardware USART is used to create an RS232 interface with a host control PC, whilst the second USART is software based using the standard built in ccs functions... setup like this:
#use rs232(stream=serial1,baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_C7,bits=7)
#use rs232(stream=serial2,baud=9600,parity=N,xmit=PIN_C1,rcv=PIN_C0,bits=8)
The software USART services a peripheral device that must be polled every 200mS to ensure all events are captured.
This information is available to the control PC when it requests it, at which point the PIC will return the necessary information.
In general this all works well. However if the PC makes a requests for information whilst the software USART is polling the peripheral device things start to go wrong with its timing.
Does anyone have any suggestions on the best way to handle this scenario?
Does anyone have any more infor on the CCS software usarts? Do they use timers or loops for their timing control? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Thu May 17, 2007 2:50 am |
|
|
They use loops.
Because of this, if an interrupt occurs during a character transmission or reception, this character will almost certainly be significantly damaged. :-(
This can be dealt with for _transmission_, by sending the characters 'one at a time', and disabling the interrupts on a 'per character' basis. On the older compilers, this can be done by using a 'wrapper' function, and I have posted this in the past. On the newer compilers, this can be done automatically, by adding the keyword 'disable_ints' to the definition of the software UART.
The same trick can be used to some extent, for reception. However here the constaints become tighter (it is vital that the receive routine is called no latter than 0.5 bit time after the start of a character). Hence keeping the interrupt handler short, for the hardware UART, becomes even more vital.
You should be able to do what you want, with the following approach:
1) Add disable_ints to the setup for the software UART. If your compiler predates this ability, then come back here, and search for the routine I published. If you can't find it, I'll post an equivalent again.
2) Use interrupt driven transmission and reception on the hardware UART. Look at ex_sisr, and ex_stisr. However modify these slightly. Use a 'binary' buffer size (8, 16, 32, 64 characters), and instead of using the modulus function (%), use the binary '&' function, with the buffer size-1. This can make a _huge_ difference to the code time (the compiler will on latter versions, automtically do this if the buffer is a binary size). However with (for instance), a '50' character buffer, versus a '64' character one, the maths time for this, changes between about 30uSec, and about 0.5uSec!...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
microkid
Joined: 17 May 2007 Posts: 2
|
|
Posted: Thu May 17, 2007 4:57 am |
|
|
Thank you for the reply...
Adding DISABLE_INTS to the SW UART has made a big differnce, and at this point I have as yet been unable to create an error.
Where can i find ex_sisr and ex_stisr? I can find no refernce to them in my manual, or the program file.
I am using a Interrupt routine that checks for (RCIF == True && RCIE == True) if this occurs it checks for over run or framing error and if neither occur it put the RCREG contents into a 64 Character array the location of which is stored as an 8 bit int. This location gets incremented dafter each character is received. If is also tested to see if it is 64 if this occurs it resets to zero. The interrupt routine is then exited.
The main program then reads these characters out of the buffer, comparing its own read location with the location set when characters arrive to determines if there is new data.
In reality there is probably never more than 16 characters in the buffer.
I am also running a further test in the interrupt routine which check the character received to see if it matches one of the three message identifier characters if one is received a message counter is incremented. However this also means a further instruction is required to ensure bit 8 of rcreg which is parity (7 bit protocol) is ignored when looking for these characters. These lines maybe unnecessary and add unnecessary length.. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Thu May 17, 2007 5:24 am |
|
|
They are in the examples directory wth the compiler.
You don't ned to check the flags. If the interrupt routine is called, the interrupt was enabled, and the interrupt event has occured. If you add the keyword 'errors' to the hardware RS232 setup line, the compiler will automatically check for error conditions when getc is called, and clear these for you.
OK. The standard way of doing what you are doing in the interrupt routine, would be:
Code: |
#define RCSIZE (64);
rc_input=0, rc_output=0;
int8 rc_buff[RCSIZE];
#define rx_kbhit() !(rc_input==rc_output)
#INT_RDA
void receive_interrupt(void) {
rc_buff[rc_input]=getc();
rc_input=(rc_input+1)&(RCSIZE-1);
if (rc_input==rc_output) {
//here you have a potential overrun - handle as you like -
//normally increment the 'output' address to throw away the
//oldest character
}
}
|
This approaches being as efficient as possible in the handler (the compiler evaluatest RCSIZE-1, at compile time, so the operation becomes a simple bitwise '&', which is a single machine instruction).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Thu May 17, 2007 7:06 am |
|
|
Have you looked at using a PIC with 2 hardware UARTs?
The 18F65J10 has two hardware UARTs and is cheaper than the 18F4520. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|