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

pic-to pic- communication

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







pic-to pic- communication
PostPosted: Wed Mar 31, 2004 7:52 pm     Reply with quote

Im am new pics and havent programed any myself, but I was wondering if there was a was to set up two UART's with only 1 PIC's, like the 452.
My project calls for setting up serial communication between 2 uC which the master would transmit data to the slave, and then the master would also send the information our to transmitter??

Thanks for any help.
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Wed Mar 31, 2004 8:18 pm     Reply with quote

You can use more than one #use rs232 statement to define several serial ports. If you map the send and receive pins on the hardware serial pins it will use the hardware UART, otherwise it will create a software serial port.
Jeprox
Guest







PostPosted: Wed Jun 23, 2004 9:40 pm     Reply with quote

I have 2 products with serial comms. I need to design an interface so these 2 can communicate. The design of mine will have some kind of translation inside so both will syncronize.

My question is, how do I use only 1 PIC to have two serial ports? Say, if I use a 16F877, what would the parameters be for the #use rs232()?

How do I resolve the conflict problem if both products try to send simultaneously?
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Wed Jun 23, 2004 10:45 pm     Reply with quote

Each #use rs232() will use different pins from the other ones. You can use the 'stream' identifier to distinguish between the serial ports.

Quote:

Syntax:
#use rs232 (options)



Elements:
Options are separated by commas and may be:

BAUD=x
Set baud rate to x

XMIT=pin
Set transmit pin

RCV=pin
Set receive pin

RESTART_WDT
Will cause GETC() to clear the WDT as it waits for a character.

INVERT
Invert the polarity of the serial pins (normally not needed when level converter, such as the MAX232). May not be used with the internal SCI.

PARITY=X
Where x is N, E, or O.

BITS =X
Where x is 5-9 (5-7 may not be used with the SCI).

FLOAT_HIGH
The line is not driven high. This is used for open collector outputs.

ERRORS
Used to cause the compiler to keep receive errors in the variable RS232_ERRORS and to reset errors when they occur.

BRGH1OK
Allow bad baud rates on chips that have baud rate problems.

ENABLE=pin
The specified pin will be high during transmit. This may be used to enable 485 transmit.

STREAM=streamed
Associates a stream identifier with this RS232 port. The identifier may then be used in functions like fputc.


Jeprox
Guest







PostPosted: Wed Jun 23, 2004 10:52 pm     Reply with quote

Assuming I have C0 and C1 for Tx and RX for the first serial, and D0 and
D1 for Tx and Rx for the second serial port, how do I send data to a particular port? If I use putc() how do I make sure it goes to C0 and not D0? Likewise, to receive data how do I determine it comes from C1 and not D1?

If I use int_rda will this be called if any of those 2 serial ports set up have data in? Or do I set up 2 int_rda. If so, how do you differentiate between the 2?
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Wed Jun 23, 2004 11:52 pm     Reply with quote

First, assign a different stream identifier to each #use RS232. Then use fputc instead of putc:

Quote:

Syntax:

value = fputc(cdata, stream)

Parameters:
cdata is a 8 bit character. Stream is a stream identifier (a constant byte)



Same thing goes for getc() and fgetc():

Quote:

Syntax:

value = fgetc(stream)

Parameters:
stream is a stream identifier (a constant byte)

Returns:
An 8 bit character



The int_rda interrupt only works with the hardware UART. Assuming you are using PIC16F877, the hardware UART is on the pins RC6 (TX) and RC7 (RX).
Jeprox
Guest







PostPosted: Wed Jun 23, 2004 11:59 pm     Reply with quote

I've got an update of the requirements.

Basically, I need 2 rs232, and 1 rs422.

But then again, assuming I put a stream parameter for each of these ports, how do I determine the data coming in if I don't use #int_rda? And how do I determine to which these data is and from which port?
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu Jun 24, 2004 12:49 am     Reply with quote

You'd have to poll the ports to see if any data is available. You can use the kbhit() function. Quoting from the manual:

Quote:

Syntax:
value = kbhit(stream)

Parameters:
Stream is a stream identifier (a constant byte)

Returns:
0 (or FALSE) if getc() will need to wait for a character to come in, 1 (or TRUE) if a character is ready for getc()

Function:
If the RS232 is under software control this function returns TRUE if the start bit of a character is being sent on the RS232 RCV pin. If the RS232 is hardware this function returns TRUE is a character has been received and is waiting in the hardware buffer for getc() to read. This function may be used to poll for data without stopping and waiting for the data to appear. Note that in the case of software RS232 this function should be called at least 10 times the bit rate to ensure incoming data is not lost.


The CCS manual also has a code sample demonstrating how to use this function.
Ttelmah
Guest







Re: pic-to pic- communication
PostPosted: Thu Jun 24, 2004 2:32 am     Reply with quote

newguy wrote:
Im am new pics and havent programed any myself, but I was wondering if there was a was to set up two UART's with only 1 PIC's, like the 452.
My project calls for setting up serial communication between 2 uC which the master would transmit data to the slave, and then the master would also send the information our to transmitter??

Thanks for any help.

There are more recent PICs, that have two hardware UARTs. These would represent the 'best' soution.
As others have said, you can use 'soft' UARTs, and the 'stream' ability to select the right port. However this carries large 'caveats'.
The first is that getting accurate timing using 'software serial', is dependant on the chip not doing much else at the time. The amount of mistiming that can be accepted, depends on the baud rate required. Hence if you have interrupts in use, to handle perhaps a 'timer' event, and hardware serial comms, you may well be able to send serial data using the 'software' serial port, at low baud rates, but have trouble at higher rates. If the data rates on both ports are comparable, you can 'bodge round' the transmission side of the problem, by writing a 'wrapper' transmit function, which disables the hardware interrupts on a 'per character' basis, while sending on the soft UART. I have posted such a wrapper in the past.
The second problem, is that the processor has to be 'watching' the port to receive incoming data. Unlike the hardware UART, where the hardware itself receives the characters, and user intervention is only needed when the data has arrived, on the 'soft' UART, the code has to sit monitoring the line as soon as the incoming character starts. You _can_ use one of the hardware interrupt lines, and call an interrupt handler as soon as the edge of the 'start' bit is seen, then use the software 'getc', inside the interrupt handler, but this does mean that other interrupts will not be responded to, till the character is complete. Also, because of the relatively long latency time when entering interrupts, this only works when the processor is being clocked fairly fast, compared to the baud rate involved.
So the soft UART _may_ be able to be used, but it will involve some careful thoughts about the timings involved...
The third alternative is to use an external UART. I have used the MAX3110 for exactly this type of application. This chip has some significant problems with errors in the data sheet (the manufacturers 'example' code, actually will not work, if data is only being transmitted at the time, rather than being both transmitted and received...). I have example drivers that do now work with this chip, and given that the package also includes the RS232 transceivers, it could be worth considering.

Best Wishes
Jeprox
Guest







PostPosted: Thu Jun 24, 2004 4:31 am     Reply with quote

In my application 'timing' is of utmost importance. The rs422 will be used to interface a GPS. So, my application expects a lot of data (streams of it), not just a single byte.

Other rs232 are for other peripherals with streams of data (lots of it) to be processed and sent to other peripherals.

Ttelmah, please explain more when you say: "will not work, if data is only being transmitted at the time, rather than being both transmitted and received". For my application will only receive data from the GPS receiver. For the other serial ports communication is two-way.

Also, one other thing is that I need is to accurately read analog inputs (18 to be exact!). These inputs are required to synchronise data received by the GPS from its own antennae.

The problem is that the analogue measurements I need to read are rated about 100V. I need this read by the PIC. What I need is some kind of an accurate translation of this level to the maximum input a PIC input can handle. If the Vcc is +5.00V, then this 100V must represent +5.00V, referenced to ground. Note that each 1V of the 100V scale must be accurately represented in the +5.00 scale. I'm not too convinced with using just resistors. Any thoughts? Perhaps, a direction to a schematic.
Ttelmah
Guest







PostPosted: Thu Jun 24, 2004 5:16 am     Reply with quote

Jeprox wrote:
In my application 'timing' is of utmost importance. The rs422 will be used to interface a GPS. So, my application expects a lot of data (streams of it), not just a single byte.

Other rs232 are for other peripherals with streams of data (lots of it) to be processed and sent to other peripherals.

Ttelmah, please explain more when you say: "will not work, if data is only being transmitted at the time, rather than being both transmitted and received". For my application will only receive data from the GPS receiver. For the other serial ports communication is two-way.

Also, one other thing is that I need is to accurately read analog inputs (18 to be exact!). These inputs are required to synchronise data received by the GPS from its own antennae.

The problem is that the analogue measurements I need to read are rated about 100V. I need this read by the PIC. What I need is some kind of an accurate translation of this level to the maximum input a PIC input can handle. If the Vcc is +5.00V, then this 100V must represent +5.00V, referenced to ground. Note that each 1V of the 100V scale must be accurately represented in the +5.00 scale. I'm not too convinced with using just resistors. Any thoughts? Perhaps, a direction to a schematic.

You allmost certainly need a hardware solution.
On the soft UART, timing is done just using delay loops. So, when sending a character, the bit is cleared (for the start bit), then the processor sits in a delay loop, till the end of the bit time, and then sends the net bit of data. This is repeated for the entire byte. Now at 4800bps, each bit time is 208uSec. RS232, will generally accept 'mistimings' of up to perhaps 3 to 4%, but not much more (perhaps 80uSec in the entre byte, but only about 40uSec in a single bit). If you enter an interrupt during the bit time, to handle a timer event, or the receipt of another character on the hardware UART, this interrupt handler takes typically, some 60 to 70 instruction times, _plus_ the duration of the handler itself (the extra is the 'saving/restoring of registers, and working out what device has interrupted). If the 452, was running at 40MHz, this corresponds to perhaps 10-20uSec, while on a slower clock, it is proportionately more. At the fast clock rate, if a single interrupt happens in one transmission, this would probably be OK, but if a lot more happens, the odds are that the serial will fail.
On the 3110 (which is what my 'will not work' reference was to), the demo code supplied, sends data, and receives data using an interrupt from the chip. When they want to send data, they switch the chip to enable the transmit function, and store the character into a software output buffer. They then have a handler in the interrupt routine, which transfers the character to the chip. Unfortunately, the interrupt on the chip, only occurs when the chips internal buffer 'becomes' empty, it doesn't generate an interrupt when the buffer _is_ allready empty. Hence if you send data, it just gets put into the output buffer, and nothing happens. However as soon as a character is received, the interrupt handler is called, this sees that data is waiting, and starts sending it.
So the code won't work if data is not being received, when you try to send a message...
I 'bodge' round the problem at present. My code has a timer running at 100Hz as well, and if this is called a couple of times, while data is waiting in the output buffer, it checks the status of the chip, and if it is not busy, transfers the first character to start everything going.
For a 'receive only' application, the chip would work fine without this bodge.
NMEA data from the GPS, will come in bursts, with quite long pauses between, so you might be able to make software RS232 handle it by 'time interleaving' the tasks, synchronising to the incoming data.
Nothing wrong with precision resistors. This is how every DVM does it.
If the signal has an AC component, you want to ensure they are non-inductive types. Remember though that a reasonable current has to flow down the sense divider, if the AD's are to give reasonable accuracy.
What are you intending to use for the 5v reference?. Generally, the supply rail is _not_ a good reference (even if it comes from an accurate regulator), because of the processor noise, so in a '5v' system, it is more normal to use a slightly lower reference voltage, derived from an accurate reference generator.
Jeprox
Guest







PostPosted: Thu Jun 24, 2004 9:58 pm     Reply with quote

I could use a precise reference generator and not use Vcc as reference.
And what about having multiple PICs, each PIC with hardware UART handling only one (1) serial port. The PCB footprint is not really that critical, so long as it's still portable.

The baud rate is 9600.

The question is, how do I connect multiple PICs together, and share the same crystal?
A sample schematic would be great and perhaps a little explanation on the relevant pins.

And on the subject of the 100V analogue inputs I need to translate this _accurately_ so it can be interfaced to the analogue input of the PIC or through some A/D converter. I don't know how this could be done. The word is is : _accurately_.

Thanks.
Jeprox
Guest







PostPosted: Thu Jun 24, 2004 10:00 pm     Reply with quote

Additionally, if I use multiple PICs then perhaps I could use the 16F84 as this can handle up to 9600 baud rate. Again, I need to link this together.

Any thoughts?
Kieran



Joined: 28 Nov 2003
Posts: 39
Location: Essex UK

View user's profile Send private message

Extra hardware serial ports
PostPosted: Fri Jun 25, 2004 2:20 am     Reply with quote

I have used a MAX3100 UART which has an SPI interface, ideal for use with a PIC. It has a programmable IRQ output which can be used to signal incomming data. Lots of other useful features, see the Maxim/Dallas website.

Data sheet http://pdfserv.maxim-ic/en/ds/MAX3100.pdf
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

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

PostPosted: Fri Jun 25, 2004 7:50 am     Reply with quote

Jeprox wrote:
Additionally, if I use multiple PICs then perhaps I could use the 16F84 as this can handle up to 9600 baud rate. Again, I need to link this together.

Any thoughts?


Pick a more "modern" PIC than the F84 if you can. The F88 might make a better choice.

You could make an ad-hoc networks between the PICs by building your own SPI software routines.

The MAX3100 is a good choice for an external UART or you can go all-out and get a dual- or quad-uart chip from TI and talk to it with one of the larger I/O count PICs.

You also mention the need to monitor 16 analog inputs. I think you will need to look at using an external ADC, ADC + MUX or multiple ADCs. Depending on your sampling speed requirements, you can probably get away with an SPI or I2C interfaced ADC. Or you could add an analog MUX in front of the PIC's ADC pins. You could use 2 8:1 muxes and 2 PIC ADC inputs or 4 4:1 muxes and 4 PIC inputs, etc

It sounds like your project specs aren't nailed down yet so maybe you need to get them down on paper and follow that up with a paper design of the hardware & software. That tends to help...
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
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