Searching \ for '[PIC]:I need help trying to use PIC for a custom s' 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/devices.htm?key=pic
Search entire site for: 'I need help trying to use PIC for a custom s'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]:I need help trying to use PIC for a custom s'
2001\11\23@125436 by Louis Davis

flavicon
face
I need help with a PIC project that will convert standard RS232 serial data
from a PC to a custom serial protocol.
The custom serial protocol is: 1 start bit+ 16 data bits + 1 stop bit @
115200bps
The protocol is asynchronous and only requires half duplex.  Basically the
PC will send 16 bits of data then wait for a 16 bit response then send
another 16 bits and so on.  The side that transmits the custom protocol uses
1 line for transmit and receive and then 3 other lines for handshaking, so
that pin on the PIC would have to be set up for IN\OUT
I figure the only way this can be done is with bit-banging.  I have a 16F84
10mhz  and a 16F84 20mhz.  Does anyone think this can be done reliably with
the 10mhz? Can this be done with the 16F84 or do I need something bigger?

Thanks,
Louis

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@134447 by Bob Barr

flavicon
face
On Fri, 23 Nov 2001 11:38:53 -0600, you wrote:

>I need help with a PIC project that will convert standard RS232 serial data
>from a PC to a custom serial protocol.
>The custom serial protocol is: 1 start bit+ 16 data bits + 1 stop bit @
>115200bps

Your 115.2 Kbaud transfer rate requires 8.68 usec per bit time. How
tolerant is the other end of your custom link to baud rate error?

A 10 MHz PIC (400 nsec instruction time) will execute 21.7
instructions in 8.68 usec. If your bit-bang loop runs in 22
instruction cycles per bit, you'll have an error of about 1.4% slow.
A 20 MHz PIC (200 nsec instruction time) gives you 43.4 instruction
times per bit time. Running your loop at 43 cycles per bit will still
put you at about 1% fast. In this case, faster is a little better but
not by much. :=)

A 10 MHz PIC with a 9.216 MHz crystal (Mouser part #73-XT49U921-20)
yields an instruction time of 434.027 nsec. This gives you a loop of
19.998 instruction cycles per bit. A 20-cycle loop will have
negligible error (less than 0.1% theoretically). If you need an
accurate baud rate, this may be the way to go.

BTW, since your data will be read from (or placed into) two different
bytes, you'll want to be careful that the bit time doesn't shift when
you're switching from the first data byte to the second one.

Regards, Bob

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@135107 by Dave Mumert

flavicon
face
Hi Lois

If you use a 18.432MHz crystal you will get 40 instructions per bit.

If you don't need to monitor the incoming line while you transmit this
should be OK.

Dave

{Original Message removed}

2001\11\23@141248 by uter van ooijen & floortje hanneman

picon face
> Your 115.2 Kbaud transfer rate requires 8.68 usec per bit time. How
> tolerant is the other end of your custom link to baud rate error?
>
> A 10 MHz PIC (400 nsec instruction time) will execute 21.7
> instructions in 8.68 usec. If your bit-bang loop runs in 22
> instruction cycles per bit, you'll have an error of about 1.4% slow.

Note that there is no law that you must send the bits in a loop: with some
calculation (and enough code space) you can unroll the loop and be up to 1
instruction accurate.

Wouter

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@152404 by Bob Barr

flavicon
face
On Fri, 23 Nov 2001 15:40:10 +0100, you wrote:

>
>Note that there is no law that you must send the bits in a loop: with some
>calculation (and enough code space) you can unroll the loop and be up to 1
>instruction accurate.
>

True, but it doesn't make much difference whether you write your code
as a loop or unroll it. Either way, the baud rate cannot be made any
more accurate than the 1 instruction time granularity. Whether your 1
instruction accuracy is in a loop or in-line code, the instruction
time determines how close you can get to the desired baud rate.

Using a 10 MHz or 20 MHz crystal, by definition, introduces some
amount of baud rate error.
Using the 'oddball' 9.216 MHz crystal (or 18.432 MHz as someone else
suggested. How did I forget that one?) will allow you to minimize the
error.

Regards, Bob

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@154643 by Lawrence Glaister

flavicon
face
On Fri, 2001-11-23 at 12:15, Bob Barr wrote:
{Quote hidden}

By unrolling the loop, you can make the character timing accurate within
1 instruction cycle vs the bit times being accurate within one
instruction cycle ( at the expense of some non cummulative bit timing
jitter ). In this users case, with 1 start, 16 data bits and 1 stop bit,
the character timing can be made 18 times better by unrolling the loop.
This makes just about any crystal usable ( faster is better ).
cheers
--

=====================================================================
Lawrence Glaister VE7IT              spam_OUTve7itTakeThisOuTspamshaw.ca
1462 Madrona Drive                   http://jfm.bc.ca/
Nanoose Bay, B.C.                    http://members.home.com/cncstuff
Canada          V9P 9C9              http://gspy.sourceforge.net
=====================================================================

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@161514 by uter van ooijen & floortje hanneman

picon face
> >Note that there is no law that you must send the bits in a loop: with
some
> >calculation (and enough code space) you can unroll the loop and be up to
1
> >instruction accurate.
>
> True, but it doesn't make much difference whether you write your code
> as a loop or unroll it. Either way, the baud rate cannot be made any
> more accurate than the 1 instruction time granularity. Whether your 1
> instruction accuracy is in a loop or in-line code, the instruction
> time determines how close you can get to the desired baud rate.

I think it does. When you have a loop you can get the loop 'matching' the
baudrate up to (worst case) 0.5 instruction. So after 8 bits this inaccuracy
has accumulated and you can be 4 instructions off. With an unrolled loop you
can compensate for this, so each bit edge is at most 0.5 instruction off.

Wouter

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@173944 by Scott Dattalo

face
flavicon
face
On Fri, 23 Nov 2001, wouter van ooijen & floortje hanneman wrote:

> > >Note that there is no law that you must send the bits in a loop: with
> some
> > >calculation (and enough code space) you can unroll the loop and be up to
> 1
> > >instruction accurate.
> >
> > True, but it doesn't make much difference whether you write your code
> > as a loop or unroll it. Either way, the baud rate cannot be made any
> > more accurate than the 1 instruction time granularity. Whether your 1
> > instruction accuracy is in a loop or in-line code, the instruction
> > time determines how close you can get to the desired baud rate.
>
> I think it does. When you have a loop you can get the loop 'matching' the
> baudrate up to (worst case) 0.5 instruction. So after 8 bits this inaccuracy
> has accumulated and you can be 4 instructions off. With an unrolled loop you
> can compensate for this, so each bit edge is at most 0.5 instruction off.

Or if you want, use s phase accumulator in a loop. The average error would
be zero. If designed properly, the maximum error would be 1 instruction.
Of course, the same thing can be achieved by unrolling the loop and
putting a variable delay between each bit.

Tricks like:

  btfsc  flag,0
   goto  $+1

  do_something

  btfss  flag,1
   goto  $+1

Can be used to create isochronous code with variable phase shifts

Check out

http://www.dattalo.com/technical/software/pic/pwm256.txt

This a software PWM routine with single instruction cycle resolution.
There's a routine in there that takes this phase delay isochronous routine
concept to the extreme. It's guranteed to hurt your brain :).

;-----------------------------------------------------------
;end_pulse
;  The purpose of this isochronous routine is to turn off the
;PWM output. Only the lower 5 bits of 'pw' are used.
;
;Input: pw
;Output
;Execution: 52 cycles
;

end_pulse

       BTFSC   pw,4            ;01;01;
        CALL   delay17         ;02;02
ep1     BTFSC   pw,3            ;03;19
        CALL   delay9          ;04;20
       BTFSC   pw,2            ;05;29
        CALL   delay5          ;06;30
ep2     BTFSS   pw,1            ;07;35
        goto   $+3             ;08;36
       NOP                     ;  ;37
       GOTO    $+1             ;  ;38
ep3     BTFSS   pw,0            ;10;40
        BCF    PWM             ;11;sk
       BCF     PWM             ;12;42
       BTFSC   pw,1            ;13;43
        goto   $+3             ;14;44
       NOP                     ;15;
       GOTO    $+1             ;16;
       BTFSS   pw,2            ;18;46
        CALL   delay5          ;19;47
       BTFSS   pw,3            ;24;48
        CALL   delay9          ;25;49
       BTFSS   pw,4            ;34;50
        CALL   delay17         ;35;51

       return                  ;52;52

-----

Now the way to do the phase accumulator thing would be to design a loop
with the closest number cycles to the desired timing, but still less than
the desired timing. Each time through the loop, add a number to an
accumulator that represents the amount of error in the loop timing. When
this accumulator rolls over, then delay the loop one cycle. For example,


almost_exact_loop

     do_stuff

     movlw     LOOP_ERROR
     addwf     phase_accumulator,f   ; add in error for this iteration

     skpnc                           ;If the accumulator rolled over
      goto     $+1                   ;then add an extra cycle

     decfsz    loop_counter,f
      goto     almost_exact_loop

The way to figure out the amount LOOP_ERROR should be is determined by
examining the difference between the undelayed execution and the desired
execution. Suppose the desired loop execution is td and the undelayed
execution is N. td is a floating point number greater than N (as
stipulated above). So the error is:

E = td - N

E is a floating point number less than 1. It can be expressed as a
fraction by:

  E =  En/256
  En = E * 256

En is the number used for LOOP_ERROR.

Here's an example. Suppose we desire a loop that takes 20.2 cycles. We
design one that takes 20 cycles, so the error is 0.2. Multiplied by 256
this gives 51.2 or just 51 when rounded.

Now notices what happens when 51 is added to the phase accumulator

 iteration  phase accum
--------------------------
    0           0
    1           51
    2           102
    3           153
    4           204
    5           255
    6           50    ; rolls over causes an extra cycle of delay
    7           101
    8           152
...

After 5 iterations through the loop, an extra cycle gets inserted.

This concept can be extended for 16-bit phase accumulators. There the
fraction is 2^16 or 65536. In this example, Ed would be 13107 or 0x3333.
Adding a literal to a 16 bit variable is easy:

   movlw  LOW(LOOP_ERROR)
   addwf  phase_accumulator_lo,f
   movlw  HIGH(LOOP_ERROR)
   skpnc
   addlw  1
   addwf  phase_accumulator_hi,f

Of course, the second movlw is unnecessary in this example.

Scott

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@174651 by Josh Koffman

flavicon
face
This doesn't directly apply, but I have had the f84 bit banging 250Kbps
at 4MHz. I didn't have to worry about recieve though.

Josh
--
A common mistake that people make when trying to design something
completely foolproof is to underestimate the ingenuity of complete
fools.
       -Douglas Adams

Louis Davis wrote:
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\23@194501 by Tom Messenger

flavicon
face
GREAT tutorial, Scott. You put it down simply enough even fools like myself
could understand it. Thanks for taking the time to make it clear for the
rest of us.

Tom M.

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\11\24@050251 by Peter L. Peres

picon face
A 3.57MHz crystal gives <0.4% error at 115.2K transmit only. But he also
needs to receive so this does not help. 18.432 is probably the only
choice.

Could the external protocol not be coaxed into being more similar with
SPI, and use that peripheral for it ? Maybe a little hardware to fake the
clock ...

Peter

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\11\24@115417 by Louis Davis

flavicon
face
I have not control over the external device.  I just know the protocol that
it expects to see.
The external device supports a master\slave configuration. In my
implementation the PC will be the master and the external device will be the
slave.  There are only two lines that really come into play, a data line and
a handshake line.  When the master wants to transmit it puts logic 0 on the
handshake line and then transmits the 16 bit word then places logic 1 on the
handshake line. Then waits for a response from the slave.  I don't know if
this could be converted to an SPI type interface.

{Original Message removed}

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