list C=120,E=0,F=INHX8M,N=126,T=OFF,P=16C73,R=HEX,X=ON,W=2 ;******************************************************************* ; WXPIC73.ASM ; ;******************************************************************* ; The signals from a directional antenna system (crossed loops and ;sense) are used to generate directional, signal characteristic, and ;timing information which is exported in RS232 serial format. ; ; Analog circuitry is controlled to provide an integration of the ;crossed loop signals followed by quadrature oscillation cycle which ;generates a time period proportional to direction-of-arrival of the ;signal (integrate and oscillation modes). ; ; Two peak amplitude detectors provide signals which are used to ;provide both the polarity and pulse width of the input signal. ; ; The various signals described above are manipulated to generate ;three serial data bytes. For positive syncronization of the serial ;data, the first byte has an high D7 bit while D7 of the following ;two bytes will always be low. The D6 bit of the first byte denotes ;signal polarity with the remaining bytes representing the pulse ;width timing (0-63). The second byte contains the direction-of-arrival ;data (0 to 119). The third byte provides the time-between-events ;data (0 to 127). ; ;****************************************************************** include "P16C73.INC" ;************* PROGRAM ADDRESS ************************************ RESET EQU 0 ; Program starting address ;************* DEFAULTS ******************************************* DEFTBE EQU D'20' ; TBE timing resolution t/51.2 us ~ 1 ms. DEFCAL EQU D'200' ; Direction calibration divisor DEFTHR EQU D'14' ; Threshold 7 mv/unit + 7 mv ~105 mv. ;************* I/O PORTS ****************************************** DIRA EQU B'100001' ; Port A D0,5 inputs D1-4 outputs DIRB EQU B'00000001' ; Port B D0 input D1-7 outputs DIRC EQU B'10111111' ; Port C inputs except TX RC6 ;************* I/O LABELS ***************************************** ; Oscillation timing -RC2/CCP1 ; Pulse detection -RC1/CCP2 PULPOL EQU 3 ; Pulse polarity (low = pos ) -RC3 NEGSEN EQU 4 ; Negative signal sense -RC4 POSSEN EQU 5 ; Positive signal sense -RC5 INT EQU 1 ; Integrate drive -RB1 OSC EQU 2 ; Oscillate drive -RB2 WDTLED EQU 3 ; Timeout LED -RB3 LEVEL0 EQU 4 ; Above threshold level -RB4 LEVEL1 EQU 5 ; > 1V signal -RB5 LEVEL2 EQU 6 ; > 2V signal -RB6 LEVEL3 EQU 7 ; > 4V signal--overload -RB7 ADC4 EQU 5 ; ADC channel 4 bit -RA5 PORTB0 EQU B'11111000' ; PortB reset-all LED's off ;************* CONFIGURATION ************************************** TM0WDT EQU B'10000000' ; No pullups, interrupts -Timer0 TM1CFG EQU B'00000001' ; Enabled -Timer1 TM2CFG EQU B'01111111' ; Pre/Post scaler = 16 /256 -Timer2 ADCHN0 EQU B'10000001' ; ADC osc/32 and enabled -Chan 0 OSCCAP EQU B'00000100' ; Capture 1--Oscillate falling edge PULCAP EQU B'00000100' ; Capture 2--Pulse falling edge BAUD EQU D'32' ; 9600 baud BRGH=0 -SPBRG ;************* REGISTER ASSIGNMENTS ***************************** CBLOCK 20 POLTIM ; Polarity-time data WIDTH ; Pulse width THRES ; Signal threshold level DEGS ; Direction 0-119 TBECAL ; Time-between-event factor TBE ; Time-between-event counter/data DIRCAL ; Direction calibration NUMmsb ; Direction numerator NUMlsb ; DEN ; Divide denominator REM ; Remainder TMP1 ; Scratch register TMP2 ; Scratch register COUNT ; Counter COMMAND ; Second character/command CHAR3 ; Third character ENDC ;************* PROGRAM ****************************************** ORG RESET GOTO START ;************* START ******************************************** ORG 8 START BTFSS STATUS,NOT_TO ; Don't set defaults if time-out GOTO START1 MOVLW DEFTBE ; Get default TBE factor MOVWF TBECAL ; Set period factor MOVLW DEFCAL ; Default direction calibration MOVWF DIRCAL ; Set direction calibration MOVLW DEFTHR ; Default threshold 100 mv. MOVWF THRES ; Set threshold level START1 MOVFW TBECAL ; Get TBE factor BSF STATUS,RP0 ; Goto page 1 MOVWF PR2 ; Set TBE period count MOVLW TM0WDT ; Timer0/WDT options MOVWF OPTION_REG MOVLW DIRA ; Tristate port bits MOVWF TRISA MOVLW DIRB MOVWF TRISB MOVLW DIRC MOVWF TRISC MOVLW BAUD MOVWF SPBRG ; Set baud rate BSF TXSTA,TXEN ; Enable serial xmit BCF STATUS,RP0 ; Return to page 0 MOVLW TM1CFG ; Enable Timer1 MOVWF T1CON MOVLW TM2CFG ; Timer2 configuration MOVWF T2CON MOVLW ADCHN0 ; ADC control--chan 0 MOVWF ADCON0 ; ADC on MOVLW OSCCAP ; Oscillate falling edge compare MOVWF CCP1CON ; Set Compare1 MOVLW PULCAP ; Pulse falling edge compare MOVWF CCP2CON ; Set compare2 MOVFW THRES ; Get threshold MOVWF PORTA ; and set level BSF RCSTA,SPEN ; Enable serial port BCF PORTB,WDTLED ; Timeout/FAULT LED on CLRWDT ; Clear watch dog timer ;************* NEW EVENT **************************************** OVERLD MOVLW 8 ; Set wait ~ 2 ms. GOTO EVENT1 EVENT MOVLW 1 ; Default conversion clear EVENT1 MOVWF TMP1 ; Set wait timer ~250 us. CLRF TMP2 CLRF TBE ; Clear time-between-events CLRF TMR2 BCF PIR1,TMR2IF ; Clear flag NULL BTFSS PIR1,TMR2IF ; Timer2 (TBE) overflow? GOTO NULL1 ; Continue null loop BCF PIR1,TMR2IF ; Clear flag BTFSS TBE,7 ; Check >127 INCF TBE,F ; If not, increment TBE NULL1 BTFSS PORTC,NEGSEN ; Check signal--low active BSF TMP2,7 ; Force minimum ~128 us. DECFSZ TMP2,F ; Inner loop ~250 us. GOTO NULL DECFSZ TMP1,F ; Skip and wait for signal GOTO NULL ; Continue until time-out MOVLW PORTB0 ; Reset port--all LED's off MOVWF PORTB BCF RCSTA,CREN ; Reset receive flag BSF RCSTA,CREN ; Enable receive ;************* SIGNAL WAIT LOOP ********************************** WAIT BCF PIR1,TMR1IF ; Clear timer overflow flag CLRF TMR1L ; Reset timer1 for next compare CLRF TMR1H WAIT0 BCF PIR2,CCP2IF ; Clear pulse width capture flag WAIT1 BTFSC PIR2,CCP2IF ; Pulse edge detected GOTO PULSE? BTFSC PIR1,RCIF ; Receive serial data? GOTO RECEIVE CLRWDT BTFSS PORTC,POSSEN ; Positive signal detected GOTO POSSKP ; Skip thru this positive cycle BTFSS PORTC,NEGSEN ; Negative signal detected GOTO INT0 ; Start integration BTFSS PIR1,TMR2IF ; Timer2 (TBE) overflow? GOTO WAIT1 ; Continue loop BCF PIR1,TMR2IF ; Clear flag BTFSS TBE,7 ; Check >127 INCF TBE,F ; If not, increment TBE GOTO WAIT1 ;************* INTEGRATE CYCLE ********************************** INT0 NOP NOP NOP NOP SKIP1 BTFSS PORTC,NEGSEN ; Skip first negative cycle GOTO SKIP1 POSSKP NOP NOP NOP NOP SKIP2 BTFSS PORTC,POSSEN ; Skip positive cycle GOTO SKIP2 BSF PORTB,INT ; Start integration INT1 BTFSS PORTC,NEGSEN ; Loop during signal integration GOTO INT1 ;************* OSCILLATE CYCLE ********************************** OSC0 BSF PORTB,OSC ; Start oscillation cycle CLRF TMR1L ; Clear Timer1 CLRF TMR1H MOVLW D'50' ; Set minimal oscillation cycle MOVWF TMP1 ; ~ 50 x 0.6 us OSC1 DECFSZ TMP1,F GOTO OSC1 BCF PIR1,CCP1IF ; Clear capture flag OSC2 BTFSC TMR1H,3 ; > 2048 counts GOTO EVENT ; If so, cancel event BTFSS PIR1,CCP1IF ; Loop till timer capture GOTO OSC2 BCF PORTB,INT ; Stop oscillation MOVFW CCPR1L ; Transfer oscillate time to MOVWF NUMlsb ; divide numerator MOVFW CCPR1H MOVWF NUMmsb ; 300 us max = 1500 counts BSF ADCON0,GO ; Start ADC ADC1 BTFSC ADCON0,GO ; Wait for conversion GOTO ADC1 ; 0 signal amplitude = 255 ; Max signal amplitude = 0 BCF PORTB,OSC ; Clamp converter MOVLW D'3' ; Minimum signal ~60 mv. ADDWF ADRES,W ; Compare SKPNC ; No carry if signal greater GOTO EVENT ; Cancel if < 60 mv. BCF PORTB,LEVEL0 ; Minimum signal LED on` MOVLW D'50' ; Level 1 ADDWF ADRES,W ; Compare SKPC BCF PORTB,LEVEL1 ; > "50" ~ 1V MOVLW D'100' ; Level 2 ADDWF ADRES,W SKPC BCF PORTB,LEVEL2 ; > "100" ~ 2V MOVLW D'245' ; Level 3 ADDWF ADRES,W SKPNC ; > "245" ~ 4.8V GOTO DIR ; Not overload signal BCF PORTB,LEVEL3 GOTO OVERLD ; Cancel this event ;************* DIRECTION CALCULATION **************************** DIR CLRC ; Clear carry (4 high msb = 0) RLF NUMlsb,F ; Shift left x2 RLF NUMmsb,F CLRC RLF NUMlsb,F ; Shift left x2 RLF NUMmsb,F CLRC RLF NUMlsb,F ; Shift left x2 RLF NUMmsb,F CLRC RLF NUMlsb,F ; Shift left x2 RLF NUMmsb,F ; Numerator x 16 (max 24000) MOVFW DIRCAL ; Get calibration factor MOVWF DEN ; Move to denominator CALL DIV ; Call division MOVFW NUMlsb ; Get division result MOVWF DEGS ; Save direction MOVLW D'120' ; Maximum 120 (360 degs) SUBWF DEGS,W ; Check/correct for overscale (>120) SKPNC ; Skip if negative--data in range MOVWF DEGS ; overwrite with the subtraction ;************* SEND SERIAL DATA ********************************** BSF STATUS,RP0 ; Set page 1 SND1 BTFSS TXSTA,TRMT ; Wait till buffer empty GOTO SND1 BCF STATUS,RP0 ; Return to page 0 MOVFW POLTIM ; Get polarity-time MOVWF TXREG ; Sent character BSF STATUS,RP0 ; Set page 1 SND2 BTFSS TXSTA,TRMT ; Wait till buffer empty GOTO SND2 BCF STATUS,RP0 ; Return to page 0 MOVFW DEGS ; Send direction byte MOVWF TXREG ; Sent character BSF STATUS,RP0 ; Set page 1 SND3 BTFSS TXSTA,TRMT ; Wait till buffer empty GOTO SND3 BCF STATUS,RP0 ; Return to page MOVFW TBE ; Get Time-Between-Events MOVWF TXREG ; Sent character GOTO EVENT ; Continue ;************* SERIAL RECEIVE *********************************** RECEIVE MOVFW RCREG ; Get 1st character and drop CLRWDT REC1 BTFSS PIR1,RCIF ; Wait for 2nd character GOTO REC1 MOVFW RCREG ; Second (first useable) byte MOVWF COMMAND ; Save as command byte CLRWDT REC2 BTFSS PIR1,RCIF ; Wait for 3rd character GOTO REC2 MOVFW RCREG ; Get character MOVWF CHAR3 ; and save CLRWDT MOVFW COMMAND ; Get command character ANDLW H'0F' ; Strip commands bits ADDWF PCL,F ; Add to program counter GOTO ECHO ; @ P GOTO ECHO ; A Q GOTO RDTHR ; B R Read signal threshold GOTO SETTHR ; C S Set signal threshold GOTO SETTBE ; D T Set TBE factor GOTO RDTBE ; E U Read TBE factor GOTO ECHO ; F V GOTO ECHO ; G W GOTO ECHO ; H X GOTO RDION ; I Y Read sense/ion current GOTO RDCAL ; J Z Read calibration factor GOTO SETFAC ; K [ Set calibration factor GOTO ECHO ; L \ GOTO ECHO ; M ] GOTO ECHO ; N ^ GOTO ECHO ; O _ SETTHR MOVFW CHAR3 ; Get third character sent MOVWF PORTA ; Set threshold MOVWF THRES ; Update threshold GOTO SNDCHR ; Echo character SETFAC MOVFW CHAR3 ; Get third character sent MOVWF DIRCAL ; Set calibration factor GOTO SNDCHR ; Echo character SETTBE MOVFW CHAR3 ; Get third character sent MOVWF TBECAL ; Update TBE factor BSF STATUS,RP0 ; Goto page 1 MOVWF PR2 ; Set TBE factor GOTO SND4 ; Echo character RDTHR MOVFW THRES ; Get threshold GOTO SNDCHR ; Send data character RDCAL MOVFW DIRCAL ; Get direction calibration GOTO SNDCHR ; Send data character RDTBE BSF STATUS,RP0 ; Goto page 1 MOVFW PR2 ; Get TBE factor GOTO SND4 ; Send data character RDION BSF ADCON0,ADC4 ; Set ADC to channel 4 MOVLW 15 ; 10+ us. delay MOVWF TMP1 RDION0 DECFSZ TMP1,1 ; Delay loop 3/4 us. GOTO RDION0 BSF ADCON0,GO ; Start ADC RDION1 BTFSC ADCON0,GO ; Wait for conversion GOTO RDION1 MOVFW ADRES ; Get ADC data BCF ADCON0,ADC4 ; Return ADC to channel 0 GOTO SNDCHR ; Send data character ECHO MOVFW COMMAND ; Get "O" character SNDCHR CLRWDT BSF STATUS,RP0 ; Set page 1 SND4 BTFSS TXSTA,TRMT ; Wait till buffer empty GOTO SND4 BCF STATUS,RP0 ; Return to page 0 MOVWF TXREG ; Sent character GOTO EVENT ;************* PULSE WIDTH ************************************** ORG H'100' PULSE? BTFSC PIR1,TMR1IF ; Check timer overflow GOTO PLSONE MOVFW CCPR2H ; Get compare MSB ANDLW B'11111100' ; Greater 204 us. SKPNZ GOTO PLSTWO ; Second pulse PLSONE MOVLW B'11000000' ; Negative pulse data BTFSC PORTC,PULPOL ; Low if negative MOVLW B'10000000' ; Positive pulse data MOVWF POLTIM ; Sync and polarity bits GOTO WAIT ; Wait for next pulse PLSTWO MOVFW POLTIM ; First pulse polarity bit BTFSC PORTC,PULPOL ; If this positive, invert XORLW B'01000000' ; Neg-pos 1>0 Neg-neg 1>1 ; Pos-neg 0>0 Pos-pos 0>1 ANDLW B'01111111' ; Strip polarity-time bits SKPZ ; Low if different & time not set GOTO WAIT0 ; Wait for another pulse MOVFW CCPR2H ; Get compare MSB ANDLW B'11111110' ; Width overscale > 102 us. SKPZ ; Overscale width if not zero GOTO OVERSCL RRF CCPR2H,F ; Shift timer bytes RRF CCPR2L,F ; three bits to the right CLRC ; Clear final bits 6-7 RRF CCPR2L,F CLRC ; Max width=102 us. RRF CCPR2L,W ; Put result in W IORWF POLTIM,F ; Add width bits to sync-polarity GOTO WAIT OVERSCL MOVLW B'00111111' ; Overscale data IORWF POLTIM,F GOTO WAIT ;************** DIVIDE ******************************************* ; Divide NUMmsb-NUMlsb by DEN result in NUMlsb-REM DIV MOVLW 8 MOVWF COUNT CLRC CLRF REM DIV1 RLF NUMmsb,W RLF REM,F MOVF DEN,W SUBWF REM,F SKPNC GOTO DIV2 ADDWF REM,F CLRC DIV2 RLF NUMmsb,F DECFSZ COUNT,F GOTO DIV1 CLRF TMP1 MOVLW 8 MOVWF COUNT DIV3 RLF NUMlsb,W RLF REM,F RLF TMP1,F MOVF DEN,W SUBWF REM,F CLRF TMP2 CLRW SKPC INCFSZ TMP2,W SUBWF TMP1,F SKPNC GOTO DIV4 MOVF DEN,W ADDWF REM,F CLRF TMP2 CLRW SKPNC INCFSZ TMP2,W ADDWF TMP1,F CLRC DIV4 RLF NUMlsb,F DECFSZ COUNT,F GOTO DIV3 RETURN END