Searching \ for 'programming challenge : 9600 baud transmit' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devprogs.htm?key=programming
Search entire site for: 'programming challenge : 9600 baud transmit'.

Truncated match.
PICList Thread
'programming challenge : 9600 baud transmit'
1997\11\26@161138 by wwl

picon face
While programming challenges seem to be popular, with some very clever
lateral-thinking going on, I thought I'd dig out my favorite chunk of
optimised code - I wrote it quite a while ago, but even with much more
PIC experience, I still can't think of any more optimisations, other
than maybe omitting the first skpnc, but this would cause (admittedly
short) output glitches.

.......................................................................

Extremely compact routine for sending asynchronous serial data at 9600
baud (with 4mhz osc). Uses only 16 instructions and 2 registers. Its
compactness makes it useful for temporarily adding to programs for
sending debug data etc. Number of stop bits can be increased up to 6
if the receiver needs gaps between bytes.

The speed isn't exactly 9600, but is only 0.16% fast. Output
polarity is inverted, for direct feeding into a PC RS232 port.
For use with an inverting RS232 driver, swap the bsf and bcf
>instructions.


txbyte        ; send byte in W at 9600 baud (4MHz osc), 8N1
 movwf temp
 movlw 0a    ; 8 data + 1 start + 1 stop (increase for more stop
             ; bits)
 movwf cnt   ; cnt is used as bit counter *and* a delay loop counter!
 clc         ; initial '1' for start bit
txloop
 skpnc             ;              _____
 bcf serport,dout  ; output bit = carry
 skpc              
 bsf serport,dout
 movlw 010  ; delay loop increment - bits 4..7 only
dloop        ; bit time delay
 goto $+1   ; 2-cycle NOP
 addwf cnt  ; increment upper 4 bits only
 skpc
 goto dloop ; loop sixteen times
 rrf temp   ; Shift next bit out, carry set & shifted in as
            ; stop bit(s)
 decfsz cnt
 goto txloop

 retlw 0

.........................................................................

    ____                                                           ____
  _/ L_/  Mike Harrison / White Wing Logic / spam_OUTwwlTakeThisOuTspamnetcomuk.co.uk  _/ L_/
_/ W_/  Hardware & Software design / PCB Design / Consultancy  _/ W_/
/_W_/  Industrial / Computer Peripherals / Hazardous Area      /_W_/

1997\11\27@145112 by Dwayne Reid

flavicon
face
Hiya Mike,

I did optimise your code a couple of years ago and posted it on the PICLIST
back then.  I also did 19200 and 38400 versions and posted those (but with
errors that Andy Warren spotted <very red face>).  I credited both you and
Andy for the original idea and the discussion that led to my optimisation.

I found that I got errors on the receive side with some comm programs.  It
appears that they don't like that the stop bit tends to be a little bit long
between individual characters (caused by the amount of time it takes to get
the next character to be transmitted.  Increasing to 2 or more stop bits
eliminated the error in every instance that it was encountered.

This was a VERY good idea that you came up with, Mike.  This and another
idea that you came up with about the same time (using the carry bit to
determine that a full 8 bits has been shifted into a register) have been
used in many projects over the past few years.

Here is the post that I sent to the Piclist back then...


The following is a series of tiny routines for sending asynchronous
serial data.  It is based upon ideas from both Mike Harrison and Andy
Warren and uses only 15 code spaces and 1 register.

The speed isn't exact, but is only 0.16% fast. The output polarity is
true and can directly feed a RS232 driver (MAX232).  For inverted data
(to directly feed an RS232 input), swap the bsf and bcf instructions.
There are 3 different versions for 9600, 19200, and 38,400 baud.  All
routines assume 4 MHz clock.

The following routines set the data format at 8N1.  Increase the .10
by up to .15 if you need more stop bits (this will affect the cycle
times mentioned).  Note that W is used as the delay counter.

;TXBYTE: send 1 byte @ 9600 baud: 1 RAM, 15 (16) ROM, 1043 cycles
;enters with data in w, exits with w trashed.
;Copyright (C) 1995 Dwayne Reid.  May be freely used so long as this
;copyright notice is retained.

txbyte                          ; send byte in W at 9600 baud (4MHz osc), 8N1
   movwf   temp
   movlw   .10        ; 8 data + 1 start + 1 stop (inc for more stop bits)
   clrc                        ; start bit
txloop                          ; bit time = 104.167 uSec
   skpnc
     bsf   serport,dout        ; output bit = carry
   skpc
     bcf   serport,dout
dloop                           ; 95 clk cycle delay
   goto    $+1                 ; 2-cycle NOP in 1 instruction!
   addlw   b'00010000'         ; increment upper nibble
   skpc                        ; delay = 6n -1 (1 less when falls thru)
     goto  dloop               ; loop sixteen times
   addlw   -1                  ; dec w, valid z, c=1 if w>=0 after decrement
   rrf     temp,F              ; carry will be set - shifted in as stop bit
   skpz
     goto  txloop              ; txloop is 104 clk cycles
   return

(other versions deleted for brevity - ask and yee shall receive).
Dwayne Reid   <.....dwaynerKILLspamspam@spam@planet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax

1997\11\27@160520 by wwl

picon face
On Thu, 27 Nov 1997 12:56:28 -0700, you wrote:

>Hiya Mike,
>
>I did optimise your code a couple of years ago and posted it on the PICLIST
>back then.
nice tweak - I didn't look at using addlw at the time as I wanted 5x
compatibility (may even have been written before the 16CXX parts!).

> I also did 19200 and 38400 versions and posted those (but with
>errors that Andy Warren spotted <very red face>).  I credited both you and
>Andy for the original idea and the discussion that led to my optimisation.
Only recently got on the net, so didn't see it!

>I found that I got errors on the receive side with some comm programs.  It
>appears that they don't like that the stop bit tends to be a little bit long
>between individual characters (caused by the amount of time it takes to get
>the next character to be transmitted.  Increasing to 2 or more stop bits
>eliminated the error in every instance that it was encountered.

... err a stop bit shouldn't be able to be too *long* - lengthening it
should just add idle time! Maybe if you send a lot of data
back-to-back, a sub-bitlength between characters may prevent the
receiver re-syncing properly? Obviously, the stopbit time can be too
short, especially with slow receivers!


    ____                                                           ____
  _/ L_/  Mike Harrison / White Wing Logic / wwlspamKILLspamnetcomuk.co.uk  _/ L_/
_/ W_/  Hardware & Software design / PCB Design / Consultancy  _/ W_/
/_W_/  Industrial / Computer Peripherals / Hazardous Area      /_W_/

1997\11\27@165131 by Andrew Warren

face
flavicon
face
Dwayne Reid <.....PICLISTKILLspamspam.....MITVMA.MIT.EDU> wrote:

> The following is a series of tiny routines for sending asynchronous
> serial data.  It is based upon ideas from both Mike Harrison and
> Andy Warren and uses only 15 code spaces and 1 register.

   Dwayne:

   I think I've mentioned this before... My only contribution to
   Mike's code was the "GOTO $+1" which replaced Mike's "MOVF PC,F"
   (a dangerous way to do a two-cycle NOP).

   Since my contribution was so exceedingly minor compared to the
   work that Mike put into the rest of the routine, I feel kinda
   silly being given any credit for the code... So please feel free
   to attribute it solely to Mike in the future.

   Thanks.

   -Andy

=== Andrew Warren - EraseMEfastfwdspam_OUTspamTakeThisOuTix.netcom.com
=== Fast Forward Engineering - Vista, California
=== http://www.geocities.com/SiliconValley/2499

1997\11\28@005355 by Eric Smith
flavicon
face
Mike Harrison <wwlspamspam_OUTNETCOMUK.CO.UK> wrote:
> ... err a stop bit shouldn't be able to be too *long* - lengthening it
> should just add idle time! Maybe if you send a lot of data
> back-to-back, a sub-bitlength between characters may prevent the
> receiver re-syncing properly? Obviously, the stopbit time can be too
> short, especially with slow receivers!

In fact, if you are designing an async receiver (hardware or software) that
might possibly be used with a modem, you should be aware that modern modems
may shave off a fraction of a stop bit in order to handle a speed mismatch if
the modem at the other end is running sligthly fast.  If I remember correctly,
this is part of the V.14 standard (along with an even more esoteric thing
called stop bit deletion), and the modem is allowed to shave the stop bit to
15/16 of the standard length.

As Mike points out, a device that is supposed to receive correctly with a
single stop bit should work with *any* stop bit length of at least one
bit-time.  It shouldn't matter if the transmitter uses 1.00 stop bits, or
1.02, or 1.15.  And good engineering practice suggests that it should be
willing to accept slightly less than 1.00 (even if you aren't trying to
support modems).

I think that the traditional stand-alone UART chips (AY-3-8500 et al.)
required the stop bit to be at least 9/16 of a bit time.

Cheers,
Eric

1997\11\28@133732 by Wim E. van Bemmel

picon face
Hello Eric,

We have Asynchronous communication. That means that both systems involved have
their own clock and thus bitrate. They synchronize at the leading edge of the
start bit. That is the only guaranteed 0-1 transition in the time-frame
sequence.
This transition may be from 'idle' to start bit or from stop bit to start bit.
Stop bits do nothing else than assuring the line is  'idle'  for a minimum time,
and therefore adding stop bits or stretching them should have no impact on the
receiver.
The RS232 and/or V24 standards specify the bitrate to be 9600 bps with a
tolerance
of - I recall from my memory - 2%. That implicates that after 10 bits (start, 8
data, stop) the 2 UARTs may differ 2+2 makes 4% of 10 bits, that is 0.4 bit.
(things are worse in RS485 where 9 databits are used in a frame, 8 data and an
address flag).
So you have to expect the leading edge of the start bit from just after the
middle
(to be more exact: about 10 microseconds) of the stop bit. You'd better not to
miss this leading edge, because all what follows next is referenced to this
edge....
Problem is of course, you have to detect the stop bit (in a simple system, no
DSP,
just sample at half bit time, to be able to generate a 'framing error', and FROM
within 10 us detect the leading EDGE of the following start bit.
There is more to say and perhaps still a lot to explain about this, let me know
if
so, but this is the heart of the matter.

O yes, one important thing.. Once you have your byte-by-byte communication
working, you'll find another challenge: you have still 2 systems with a
different
bit-rate, but at a higher level it may be a different byte-rate.. data may come
in
faster than you send it!
In a higher level protocol you have to deal with that too.
That is where buffers are invented for.

Good luck, I am interested in this!

Eric Smith wrote:

{Quote hidden}

--
Regards,

Wim
------------------------------------------------
 Wim van Bemmel, Singel 213 3311 KR Dordrecht
 Netherlands
 KILLspambemspanKILLspamspamxs4all.nl

 ... Life is about Interfacing .....
------------------------------------------------

1997\11\29@161101 by Dwayne Reid

flavicon
face
>Andy Warren <RemoveMEPICLISTTakeThisOuTspamMITVMA.MIT.EDU> wrote:
>
small snip
>    Dwayne:
>
>    I think I've mentioned this before... My only contribution to
>    Mike's code was the "GOTO $+1" which replaced Mike's "MOVF PC,F"
>    (a dangerous way to do a two-cycle NOP).

Not the only contribution, Andy.  I don't know if you would remember (this
all took place on the Mchip BBS several years ago) but you were helping
several people understand MPASM macros.  Up to that point, I did not realise
that MPASM could convert negative constants into the equivalent positive
constants and had never manipulated w that way.  The intense flash that
accompanied that revelation directly led to my using w as a down counter:
first with this comm program, then many, many times since then.  Pretty
obvious stuff now but very new and wonderful then.  My thanks again.

Dwayne Reid   <spamBeGonedwaynerspamBeGonespamplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, Alberta, CANADA
(403) 489-3199 voice     (403) 487-6397 fax

More... (looser matching)
- Last day of these posts
- In 1997 , 1998 only
- Today
- New search...