Exact match. Not showing close matches.
PICList
Thread
'[SX]: VP (Bit Bang) Serial ISR Calculator'
2000\10\11@162703
by
jamesnewton
|
For any Scenix users, or for PIC users who want to bit bang serial comms,
I've put up a new page at
http://www.sxlist.com/isrcalc.asp
that helps find what baud rates can be supported by a given clock rate, RTCC
pre-scale, RTCC Increment and ISR multiplex divider. It is an extension of
the one I converted from Andy Kunz's code at
www.piclist.com/../microchip/spbrgcalc.asp
This was necessary as there are a lot more variables involved in bit banged
serial.
The exhaustive search can be restricted to a list of one or more clock
speeds, prescales, Max RTCC Increment, Max UART ISR Subroutine Call Divide
Rate, Baud Rates, and allowable error percentage. For the PIC, set the
prescale to 1.
The ISR code supported by the routine would look something like:
;UNTESTED CODE
bank serial ;switch to serial register bank
:transmit
djnz tx_divide,:receive ;only do it every tx_divide ISRs
mov tx_divide,#RS232ISRDiv
test tx_count ;and not at all if we have no bits to send
jz :receive ; maybe we are recieving
clc ;shift in 0's for a stop bit at end of tx_count
rr tx_high ;
rr tx_low ;
movb RS232Tx, c ;copy the carry from the bottom of tx_low
;to the output pin
;
:receive
movb c,RS232Rx ;get current rx bit
test rx_count ;currently receiving byte?
jnz :rxbit ;if so, jump ahead
mov w,#9 ;in case start, ready 9 bits
sc ;skip ahead if not start bit
mov rx_count,w ;it is, so renew bit count
mov w, #RS232StartDelay
mov rx_divide,w ;ready 1.5 bit periods
:rxbit
djnz rx_divide,:Out ;middle of next bit?
mov w,#RS232ISRDiv
mov rx_divide,w ;yes, ready 1 bit period
dec rx_count ;last bit?
sz ;if not
rr rx_byte ; then save bit
jnz :Out ;if so
sc ; and if its a valid stop bit
setb RS232RxFrameErr ; set error flag
setb RS232Rx_flag ; then set flag
:Out
and is based on the following equates for the SXKey:
;EQUATES
*************************************************************************
OptRTCisW = %01111111 ;And with Opts to make register 1 show W
OptRTCEnable = %10111111 ;And with Opts to enable rtcc interrupt
OptRTCInternal = %11011111 ;And with Opts to make rtcc internal
OptRTCIntLead = %11101111 ;And with Opts to make rtcc inc on Leading edge
OptRTCPrescale = %11110111 ;And with Opts to enable rtcc prescaler
Opts = %11111000 ;base Options. Last 3 bits are the PreScale divider.
IF CpuMhz = 100
OptPreScale = 8
IntPeriod = 217 ;will be subtracted from 256 to inc RTCC
myOpts = Opts & OptRTCEnable & OptRTCInternal & OptRTCisW
ENDIF
IF CpuMhz = 75
OptPreScale = 8
IntPeriod = 244 ;will be subtracted from 256 to inc RTCC
myOpts = Opts & OptRTCEnable & OptRTCInternal & OptRTCisW
ENDIF
IF CpuMhz = 50
OptPreScale = 4
IntPeriod = 217 ;will be subtracted from 256 to inc RTCC
myOpts = Opts & OptRTCEnable & OptRTCInternal & OptRTCisW
ENDIF
;217 is a magic number that "just works" at 50 or 100Mhz for RS232
irrespective
;of the Pre Scale. Use 244 most often for 75MHz. See
;www.sxlist.com/techref/scenix/isrcalc.asp
;to calculate other options
;217*4=868 cycles per interrupt.
;57,604 Hz interrupt rate 0.000,017,36 seconds per interrupt
;PreScaleBits
;000=1:2, 001=1:4, 010=1:8, 011=1:16, 100=1:32,
; 101=1:64, 110=1:128, 111=1:256
OptPreScaleBits = ((OptPreScale>3)&1) + ((OptPreScale>7)&1)
OptPreScaleBits = OptPreScaleBits + ((OptPreScale>15)&1) +
((OptPreScale>31)&1)
OptPreScaleBits = OptPreScaleBits + ((OptPreScale>63)&1) +
((OptPreScale>127)&1)
OptPreScaleBits = OptPreScaleBits + ((OptPreScale>255)&1)
IF OptPreScale > 1
IF OptPreScale <> 2<<OptPreScaleBits
;Just incase an invalid PreScale was selected
ERROR 'invalid Prescale value'
ELSE
myOpts = myOpts & OptRTCPrescale | OptPreScaleBits
ENDIF
ELSE
myOpts = myOpts | (255^OptRTCPreScale)
ENDIF
ISRRate = 0
IF myOpts & OptRTCEnable AND myOpts & OptRTCInternal
MaxISRCycles = OptPreScale * IntPeriod
ISRRate = cpuMHz*1000000 / MaxISRCycles
ENDIF
; The following three values determine the UART baud rate.
; Baud rate = cpuMHz/(RS232ISRDiv * MaxISRCycles)
; = cpuMHz/(RS232ISRDiv * OptPreScale * IntPeriod)
;
RS232BaudRate = 9600
RS232ISRDiv = ISRRate / RS232BaudRate
IF RS232ISRDiv < 1 or RS232ISRDiv > 255
ERROR 'RS232BaudRate incompatible with cpuMhz and OptPreScale'
ENDIF
; The start delay value must be set equal to RS232ISRDiv * 1.5 + 1
RS232StartDelay = RS232ISRDiv + (RS232ISRDiv>>1) + 1
WKPND_B = $09
WKED_B = $0A
WKEN_B = $0B
TRIS = $1F
Let me know if you have any interest, comments or questions.
---
James Newton spam_OUTjamesnewtonTakeThisOuT
geocities.com 1-619-652-0593
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
More... (looser matching)
- Last day of these posts
- In 2000
, 2001 only
- Today
- New search...