;****************************************************************************** ;* * ;* PIC12C508 version of RC to RS232 (C) By K. Hewitt Nov 2001 * ;* Ver 2.2 Drives RS232 via resistor * ;* 1 transistor input stage * ;****************************************************************************** ; LIST P=16C54, F=INHX8M, R=HEX include "C:\mydata~1\PIC\PICREG.EQU" ;****************************************************************************** ;* Set up varibles and values * ;****************************************************************************** DX equ 0 ;Set bit for TX to bit 0 RX equ 3H ;Set bit 3 for PPM ip Width equ 0CH ;F12 to count pulse width XCount equ 0DH ;F13 to hold TX bit count XmtReg equ 0EH ;F14 to hold TX character Delayreg equ 0FH ;F15 to hold delay loop Chars equ 10H ;F16 Number of chars to send Txchar equ 11H ;F17 pointer to tx char Txcount equ 12H ;F18 Tx char loop counter ;****************************************************************************** ;* Start of program * ;****************************************************************************** ORG 0 ;set start of program to 000 hex movwf OSCCAL Begin clrf PORT_B movlw B'11111110' ;set bit 0 for output tris PORT_B ;*********************************************************** ;* Main program loop, it starts by waiting for RX line to * ;* go low then as soon RX goes Hi it calls the routine to * ;* measure the pulse width. On return from this routine if * ;* the pulse was the sync pulse then it starts to measure * ;* the width of the pulses when it finds the next sync it * ;* calls the routine to send the ASCII data * ;*********************************************************** Find_sync Hi btfss PORT_B,RX ;is RX line Hi goto Hi ;Yes Lo btfsc PORT_B,RX ;RX line is lo wait to go Hi goto Lo ;RX line lo call Measure ;Call routine to measure width tstf Width ;Find status of width bnz Hi ;Not zero so not sync try again goto Readings ;Zero so it is sync pulse goto Find_sync ;Go and find next sync pulse Readings movlw 02H ;Set chars to 2 (sync + buttons) movwf Chars ; movlw 17H ;Set start of TX buffer to F23 movwf FSR ; Hi_1 btfss PORT_B,RX ;is RX line Hi goto Hi_1 ;Yes Lo_1 btfsc PORT_B,RX ;RX line is lo wait to go Hi goto Lo_1 ;RX line lo call Measure ;Call routine to measure width tstf Width ;Find status of width bnz Pulse ;Not zero,so not sync read next pulse goto Send ;Zero so it is sync pulse Pulse incf Chars,1 ;Inc number of chars to send movf Width,0 ;Save width measurement movwf 0 ;to TX buffer position Txchar incf FSR,1 ;Inc TX buffer pointer goto Lo_1 ;Go wait for start of next pulse ;************************************************************ ;* This routine measures the width of positive going pulses * ;* and returns with a value >0 for pulses up to 2.55mS or a * ;* value of 0 if it is the sync pulse. * ;************************************************************ Measure clrf Width ;Clear F8 to zero Repeat nop ;Five NOP's to pad nop ;out routine to give nop ;a total loop time of nop ;10uS nop ; btfsc PORT_B,RX ;is RX lo goto Done ;Yes go to Done incfsz Width,1 ;Inc width count goto Repeat ;loop for another 10uS Done retlw 0 ;return from routine ;************************************************************ ;* This routine is called when the sync pulse is found and * ;* it sends a sync char (240 dec)+the number of chars in * ;* this TX packet(max 15 chars) then a char representing * ;* the status of the push buttons and then chars for how * ;* ever many pulse width measurements where taken. * ;************************************************************ Send movlw 15H ;Set pointer to F21 movwf Txchar ; movlw .240 ;Set 1st char of TX buffer to sync movwf 15H ;Store in F21 movf Chars,0 ;Set W to number of TX chars addwf 15H,1 ;Add W to 240 movlw 0 ;Read button status movwf 16H ;Saved in 2nd char of TX buffer movf Chars,0 ;Set W to Chars movwf Txcount ;Set tx loop to chars movf Txchar,0 ;set W to first tx char movwf FSR ;Set FSR to Txchar Loop2 movf 0,0 ;Get Next char movwf XmtReg ;Copy to XmtReg Xmtr movlw 8 movwf XCount ;8 data bits bsf PORT_B,DX ;Send start bit X_next call Delay94 ;Delay 94uS to make total 104uS rrf XmtReg ;Shift character right 1 bit btfsc STATUS,CARRY ;Test bit to be transmitted bcf PORT_B,DX ;Bit is a 1 btfss STATUS,CARRY bsf PORT_B,DX ;Bit is a 0 decfsz XCount ;If Count=0 then send a stop bit goto X_next ;Transmit next bit X_Stop call Delay101 ;101uS bcf PORT_B,DX ;Send stop bit call Delay102 ;102uS incf FSR,1 ;inc pointer to next char decfsz Txcount ;Dec loop counter goto Loop2 ;Send next Char X_Over goto Find_sync ;return back ;************************************************************* ;* This routine provides the different delays needed by the * ;* serial TX routine the delay is decided by the entery point* ;************************************************************* Delay102 nop ;Delay of 102uS to retlw Delay101 nop ;Delay of 101uS to retlw nop nop nop nop nop nop Delay94 movlw .22 ;Set delay loop value to 22 decimal movwf Delayreg ;22*(1+1+2)uS = 88uS Delay1 nop ;Total delay from Delay94 decfsz Delayreg,1 ;Decrement F18 by 1 goto Delay1 ;to retlw = 94uS nop nop retlw 0 End