Forums

RS485 and UART1

Started by varuzhandanielyan February 6, 2006
I use UART1 to connect to RS485.  For it
I need to enable RS485 transmitter before sending
and again desible it when sending is over.
Below is my code:
void Transmit1(int ch)
{
  U32 enabled_interrupts;
  // wait for transmission completed
  while (!(U1LSR & TEMT));

  enabled_interrupts = VICIntEnable;  //disable all interrupts
  VICIntEnClr        = enabled_interrupts;

  U1THR = ch;
//while (IO0PIN & Bit(15));
  T1EMR = Bit(2);		// ExtMatch2 = 1
  T1MR2 = T1TC + 10*60000000/115200;
  T1EMR |= Bit(8);      // ClearOnExtMatch2

  VICIntEnable = enabled_interrupts;
}

Problem:
the U1THR = ch; operator does not start sending
immediatelly.  There is a random delay in range
approximatelly from 0 to 1 bit duration.
I made different experiments to reset the baudrate
counter or other means but without result.  Only
way I found to solve the problem was an extra pin
(P0.15 in my case) usage to detect the real start
of trasmittion, this is done by commented while.
So one needs to use an extra pin and accept, that
interruptions could be desible by up to one bit
duration.
Maybe somebody knows how to force the UART1 start
to transmit the character immediatelly after writing
to U1THR register.

Thanks in advance,
Varuzhan
	

An Engineer's Guide to the LPC2100 Series

varuzhandanielyan wrote:

>I use UART1 to connect to RS485.  For it
>I need to enable RS485 transmitter before sending
>and again desible it when sending is over.
>Below is my code:
>void Transmit1(int ch)
>{
>  U32 enabled_interrupts;
>  // wait for transmission completed
>  while (!(U1LSR & TEMT));
>
>  enabled_interrupts = VICIntEnable;  //disable all interrupts
>  VICIntEnClr        = enabled_interrupts;
>
>  U1THR = ch;
>//while (IO0PIN & Bit(15));
>  T1EMR = Bit(2);		// ExtMatch2 = 1
>  T1MR2 = T1TC + 10*60000000/115200;
>  T1EMR |= Bit(8);      // ClearOnExtMatch2
>
>  VICIntEnable = enabled_interrupts;
>}
>
>Problem:
>the U1THR = ch; operator does not start sending
>immediatelly.  There is a random delay in range
>approximatelly from 0 to 1 bit duration.
>I made different experiments to reset the baudrate
>counter or other means but without result.  Only
>way I found to solve the problem was an extra pin
>(P0.15 in my case) usage to detect the real start
>of trasmittion, this is done by commented while.
>So one needs to use an extra pin and accept, that
>interruptions could be desible by up to one bit
>duration.
>Maybe somebody knows how to force the UART1 start
>to transmit the character immediatelly after writing
>to U1THR register.
>  
>
Ha!  Welcome to RS485.  It is a bit more complex than it looks.

I don't know why you believe that you needs such precise control over 
the relationship of TXD/RXD and the DIRection?  By it's very nature, 
RS485 communications over twisted pair require that the line be 
precharged before it can be used.

Think about it, the wire is floating electrically, any stray magnetic or 
electrical field can induce a blip into the "dead" wire.  By first 
turning the direction to Transmit, then hold that for a few TX char 
times, it allows the uart at the RX side to settle down.  The uart that 
the RX side may have heard a blip and is in the process of receiving a 
erroneous char.  Once you precharge the line, send your data, then HOLD 
the carrier (direction) until the last char has been sent and then flip 
the line back to RX mode.

Most of the systems I've seen / worked on have a "quiet" line floating

as the units are all listening for some other unit to speak.

TomW
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
> Ha!  Welcome to RS485.  It is a bit more complex than it looks.
>
> I don't know why you believe that you needs such precise control over
> the relationship of TXD/RXD and the DIRection?  By it's very nature,
> RS485 communications over twisted pair require that the line be
> precharged before it can be used.
>
> Think about it, the wire is floating electrically, any stray magnetic or
> electrical field can induce a blip into the "dead" wire.  By
first
> turning the direction to Transmit, then hold that for a few TX char
> times, it allows the uart at the RX side to settle down.  The uart that
> the RX side may have heard a blip and is in the process of receiving a
> erroneous char.  Once you precharge the line, send your data, then HOLD
> the carrier (direction) until the last char has been sent and then flip
> the line back to RX mode.
>
> Most of the systems I've seen / worked on have a "quiet" line
floating
> as the units are all listening for some other unit to speak.
>
> TomW

Hello Tom.
I am right now working with RS485. I had most of the problems (the last 3 
days) with a good way to make the computer transmit over RS485. I tried with 
RTS controling the DE pin, but it was a nightmare. I am drawing a board right 
now with a 555 that is trigged by RTS and every low level on the TX line to 
control the state of DE.

You talked about a precharge, do you know what are a safe time to precharge 
the line?

Xtian Xultz wrote:

>>Ha!  Welcome to RS485.  It is a bit more
complex than it looks.
>>
>>I don't know why you believe that you needs such precise control over
>>the relationship of TXD/RXD and the DIRection?  By it's very nature,
>>RS485 communications over twisted pair require that the line be
>>precharged before it can be used.
>>
>>Think about it, the wire is floating electrically, any stray magnetic or
>>electrical field can induce a blip into the "dead" wire.  By
first
>>turning the direction to Transmit, then hold that for a few TX char
>>times, it allows the uart at the RX side to settle down.  The uart that
>>the RX side may have heard a blip and is in the process of receiving a
>>erroneous char.  Once you precharge the line, send your data, then HOLD
>>the carrier (direction) until the last char has been sent and then flip
>>the line back to RX mode.
>>
>>Most of the systems I've seen / worked on have a "quiet" line
floating
>>as the units are all listening for some other unit to speak.
>>
>>TomW
>>    
>>
>
>Hello Tom.
>I am right now working with RS485. I had most of the problems (the last 3 
>days) with a good way to make the computer transmit over RS485. I tried with

>RTS controling the DE pin, but it was a nightmare. I am drawing a board
right 
>now with a 555 that is trigged by RTS and every low level on the TX line to 
>control the state of DE.
>
>  
>
No, no, don't even try that!  Go with the RTS Line, it is the most 
accepted practice.  Once you build your first driver code, you can move 
it to other uarts as most uarts have an RTS control line.  I agree, it 
is not simple to do RS485 with the line precharge requirement, but you 
should be able to come up with a fairly simple solution...

Like, have the software that puts the TX data into the data queue hold 
off on stuffing the first char into the uart TX buffer.  Have it set a 
count value to a preset value, then set the LINE to TX directions.  
Everytime a new char is put into the buffer, preset the counter.  No 
data is put into the TX uart register yet.

Have a timer try to decrement the counter, if the counter is non-zero, 
decrement it.  If the decrement goes to zero, take a SPECIAL(!) char / 
pair of them, and send stuff these into the TX uart data register to 
start the interrupt system into motion.

I said SPECIAL char(s) as I qualify the beginning of the transmission 
with a series of 0xfe chars.  The RX side looks for at least one 0xfe at 
the start of each data block.  The leading 0xfe's are peeled off and 
discarded.

Oh, BTW, you will need to checksum that data block somehow.  You need to 
verify that what you are recieving is not noise.  When you have a pair 
of wires running several miles / kilometers, you are going to start 
hearing Terrestial Noise.  Noise from magnetic field flux changes (e.g. 
"northern lights"), noise from lightning storms in the area, also from

distant storms.

A lightning stroke that is in the local area (within several miles) will 
induce from 3volts to 30volts per foot of wire.  THAT is a lot of 
energy!  You need a way to clamp this, don't bother with MOVs or PTCs, 
they are too slow and degrade with each use:  try the classic PI 
arrangement of Transil (sub-ns Zener), resistor, Transorb (gas tube).
	>You talked about a precharge, do you know what are a safe time to precharge

>the line?
>
>
>  
>
At least one and a half character time, compute your char time based on 
baudrate.  Typically, I will use 10ms precharge and 5ms trailing delays 
at 1200 baud.  BTW, 1200 baud may be slow, but it can go a really long 
distance over RS485, typically 5-7 miles (and longer with an end-user 
who cannot RTFM).
	TomW
	-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------
	
My question was about avoiding uncertainty
of interval betveen writing to U1THR and start
of the actual transmittion. Having sertain timing
on can foresee necessary delays, my code was only
an example.
Please, does anybody know an answer?

Varuzhan
	--- In lpc2000@lpc2..., Tom Walsh <tom@...> wrote:
>
> Xtian Xultz wrote:
> 
> >>Ha!  Welcome to RS485.  It is a bit more complex than it looks.
> >>
> >>I don't know why you believe that you needs such precise control
over
> >>the relationship of TXD/RXD and the DIRection?  By it's very
nature,
> >>RS485 communications over twisted pair require that the line be
> >>precharged before it can be used.
> >>
> >>Think about it, the wire is floating electrically, any stray
magnetic or
> >>electrical field can induce a blip into
the "dead" wire.  By first
> >>turning the direction to Transmit, then hold that for a few TX char
> >>times, it allows the uart at the RX side to settle down.  The uart
that
> >>the RX side may have heard a blip and is
in the process of receiving a
> >>erroneous char.  Once you precharge the line, send your data, then
HOLD
> >>the carrier (direction) until the last
char has been sent and then
flip
> >>the line back to RX mode.
> >>
> >>Most of the systems I've seen / worked on have a "quiet"
line floating
> >>as the units are all listening for some other unit to speak.
> >>
> >>TomW
> >>    
> >>
> >
> >Hello Tom.
> >I am right now working with RS485. I had most of the problems (the
last 3 
> >days) with a good way to make the computer
transmit over RS485. I
tried with 
> >RTS controling the DE pin, but it was a
nightmare. I am drawing a
board right 
> >now with a 555 that is trigged by RTS and
every low level on the TX
line to 
> >control the state of DE.
> >
> >  
> >
> No, no, don't even try that!  Go with the RTS Line, it is the most 
> accepted practice.  Once you build your first driver code, you can move 
> it to other uarts as most uarts have an RTS control line.  I agree, it 
> is not simple to do RS485 with the line precharge requirement, but you 
> should be able to come up with a fairly simple solution...
> 
> Like, have the software that puts the TX data into the data queue hold 
> off on stuffing the first char into the uart TX buffer.  Have it set a 
> count value to a preset value, then set the LINE to TX directions.  
> Everytime a new char is put into the buffer, preset the counter.  No 
> data is put into the TX uart register yet.
> 
> Have a timer try to decrement the counter, if the counter is non-zero, 
> decrement it.  If the decrement goes to zero, take a SPECIAL(!) char / 
> pair of them, and send stuff these into the TX uart data register to 
> start the interrupt system into motion.
> 
> I said SPECIAL char(s) as I qualify the beginning of the transmission 
> with a series of 0xfe chars.  The RX side looks for at least one
0xfe at 
> the start of each data block.  The leading 0xfe's
are peeled off and 
> discarded.
> 
> Oh, BTW, you will need to checksum that data block somehow.  You
need to 
> verify that what you are recieving is not noise. 
When you have a pair 
> of wires running several miles / kilometers, you are going to start 
> hearing Terrestial Noise.  Noise from magnetic field flux changes (e.g. 
> "northern lights"), noise from lightning storms in the area, also
from 
> distant storms.
> 
> A lightning stroke that is in the local area (within several miles)
will 
> induce from 3volts to 30volts per foot of wire. 
THAT is a lot of 
> energy!  You need a way to clamp this, don't bother with MOVs or PTCs, 
> they are too slow and degrade with each use:  try the classic PI 
> arrangement of Transil (sub-ns Zener), resistor, Transorb (gas tube).
> 
> 
> >You talked about a precharge, do you know what are a safe time to
precharge 
> >the line?
> >
> >
> >  
> >
> At least one and a half character time, compute your char time based on 
> baudrate.  Typically, I will use 10ms precharge and 5ms trailing delays 
> at 1200 baud.  BTW, 1200 baud may be slow, but it can go a really long 
> distance over RS485, typically 5-7 miles (and longer with an end-user 
> who cannot RTFM).
> 
> 
> TomW
> 
> 
> -- 
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------
>