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 http://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 ;http://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< 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 mailto:jamesnewton@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.