;******************************************************************* ; Youngs_Controller.ASM ; ; Robert Hunt, April 2009. ;******************************************************************* ; ; Device : PIC16F690 ; ; Performance : ; Program Memory : 4k words ; Stack : 8 level ; SRAM data reg : 256 ; EEPROM data mem : 256 ; ADC channels : 12 ; EUSART : 1 ; SSP : 1 ; Timers : 3 ; ; Configuration Bits: ; Clock Mode : Internal 8MHz ; Watchdog Timer : Off ; Power Up Timer : Off ; Master Clear : Internal ; Brown Out Detect : On ; Code Protect : Off ; EE Read Protect : Off ; ;******************************************************************* ; Pins : Pin No Pin name I/O Operation ; 1 Vdd +5V ; 2 TICKI I Timer 1 CK IP from discriminator ; 3 /T1G I Timer 1 gate control input ; 4 RA3 I nMINDEX (Mask index detected) ; 5 RC5 O nMSTEP (Manual step button) ; 6 RC4 I nMFWD (Direction switch) ; 7 RC3 I nMTRK0 (Seek track 0 button) ; 8 RC6 O /CS on TLC2615 DAC for disc. ; 9 SDO O Serial data to TLC2615 DAC ; 10 TX O RS232 Tx to PC ; 11 SCK O Clock to TLC2615 DAC ; 12 RX I RS232 Rx from PC ; 13 SDI I Connected to SDO ; 14 RC2 I nTRK0 (Slit posn. 0 detected) ; 15 RC1 O nSTEP (Step acceptance slit) ; 16 RC0 O nFWD (Fwd/Rev for mask & slit) ; 17 RA2 O BLUEON (1 = Blue Laser on) ; 18 RA1 O REDON (1 = Red Laser on) ; 19 RA0 O nSSTEP (Step to next mask) ; 20 Vss 0V ;******************************************************************* ; Notes: ; The integral ADC is not used. ; An external TLC5615 10 bit serial DAC is used to control the ; discriminator level. ; ;******************************************************************* ; RS232 Commands: ; I Step acceptance slit forwards. ; i Step acceptance slit backwards. ; 0 Step acceptance slit to position 0. ; M Next mask. ; m Previous mask. ; R Red laser on. ; r Red laser off. ; B Blue laser on. ; b Blue laser off. ; D Increase discriminator level one step (6dB). ; d Decrease discriminator level one step (6dB). ;******************************************************************* ;Status word returned by PIC every gate period: ;*Expt1RBMADRRRCL ; Where: ;*Expt1 = Sync marker. ;R = Red laser. R = on. r = off. ;B = Blue laser. B = on. b = off. ;M = Mask selected. Binary 0 to 7. ;A = Acceptance slit position. Binary 0 to 79. ;D = Discriminator level. Binary. ;RRR = Photon count. 24 bit binary. ;C = Carriage return. ;L = Line feed. ;******************************************************************* #include __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF) ;Configuration Constants: ;----------------------- MaxTrack EQU .79 ;Highest track number that can be stepped to. MaxMask EQU .5 ;Highest mask number that can be stepped to. ;Note square wave masks 6 & 7 inhibited as results are poor. MaxDisc EQU .54 ;Highest alowable discriminator level in dB. ;SRAM Register Assignments: cblock 0x20 SaveW ;Storage of W register during interrupt. SaveStatus ;Storage of Status register during interrupt. Debounce ;Counter for ignoring the step button. GenLoop ;General purpose loop counter. Track ;Position of the PMT admittance slit. Delay1 ;Counter for 1ms delay routine. Delay2 ;Counter for 1s delay routine. RxChar ;Temporary register for EUSART received character. CountOf ;Count Timer 1 overflows to expand by 256x. CountEx ;Storage for Timer 1 (Extension) overflows. CountHi ;Storage for Timer 1 high byte. CountLo ;Storage for Timer 1 low byte. RedLaser ;'R' = on, 'r' = off. For status word. BlueLaser ;'B' = on, 'b' = off. For status word. Mask ;Mask selected (0 to 7 binary). Disc ;Discriminator level in dB (binary). DiscH ;Discriminator DAC high byte. DiscL ;Discriminator DAC low byte. endc org 0000h goto Start ;******************************************************************* ;Interrupt Service Routine org 0004h movwf SaveW ;Store W so it can be restored. movf STATUS,W ;\ Store Status register so it movwf SaveStatus ;/ can be restored. btfss INTCON,0 ;Check if it is int on change. goto EndGateInt bcf INTCON,0 ;Clear interrupt flag (RABIF). btfss PORTA,4 ;Check timer gate is closed. goto EndGateInt bcf T1CON,0 ;Disable Timer 1. movf CountOf,W ;\ movwf CountEx ;| movf TMR1H,W ;| movwf CountHi ;| Get the Timer 1 result. movf TMR1L,W ;| movwf CountLo ;/ clrf TMR1H ;\ Reset Timer 1. clrf TMR1L ;/ bsf T1CON,0 ;Enable Timer 1. clrf CountOf ;Reset overflow counter. call SendStatus ;Send the status to RS232 EndGateInt: btfss PIR1,0 ;Check if it is int on T1 overflow. goto EndOflwInt bcf PIR1,0 ;Clear interrupt flag (TMR1IF). incf CountOf,F ;Increment overflow counter. EndOflwInt: movf SaveStatus,W ;\ Restore Status register. movwf STATUS ;/ movf SaveW,W ;Restore W register. retfie ;Return from interrupt. ;******************************************************************* ;Main Program ; Start: call InitOsc ;Configure master oscillator call InitIO ;Configure and initialise IO pins call InitReg ;Initialise variables call Delay1s ;Allow supplies to stabilise. call InitSSP ;Initialise the SSP for the DAC call InitUART ;Initialise the EUSART call InitTimer1 ;Inialise Timer 1 as the counter. MainLoop: incf Debounce,F ;\ If the debounce counter is decfsz Debounce,F ;| not zero, decrement it. decf Debounce,F ;/ btfsc PORTC,5 ;Test manual step button goto No_Step incf Debounce,F ;\ decfsz Debounce,F ;| Check if a debounce period goto No_Step ;/ is in effect. call Man_Step No_Step: btfsc PORTC,3 ;Test seek track 0 button goto No_Trk0 incf Debounce,F ;\ decfsz Debounce,F ;| Check if a debounce period goto No_Trk0 ;/ is in effect. call Seek_Trk0 ;Move admittance slit to track 0 No_Trk0: call Delay1ms call Delay1ms call Delay1ms call Delay1ms btfss PIR1,5 ;Check if EUSART has received goto MainLoop ;Start again call SerCom ;Serial byte received so process it goto MainLoop ;Start again ;******************************************************************* ;Master Oscillator Configuration Routine ; InitOsc: bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ bsf OSCCON,4 ;Internal oscillator 8MHz bsf OSCCON,0 ;System clock internal bcf STATUS,RP0 ;Bank 0 return ;******************************************************************* ;IO Pin Initialisation Routine ; InitIO: bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ clrf PORTA ;Init PORTA clrf PORTC ;Init PORTC bsf STATUS,RP1 ;Bank 2 clrf ANSEL ;Digital I/O only clrf ANSELH ;Digital I/O only bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ movlw 038h ;\ Set RA2, RA1 & RA0 as O/P. movwf TRISA ;/ Set RA5, RA4 & RA3 as I/P. movlw 0B0h ;\TRISB<6> must be 0 for SCK master movwf TRISB ;/ movlw 03Ch ;\ Set RC7, RC6, RC1 & RC0 as O/P. movwf TRISC ;/ Set RC5, 4, 3 & 2 as I/P. bcf STATUS,RP0 ;Bank 0 bsf PORTC,6 ;Disable discriminator DAC bsf PORTA,0 ;Set nMINDEX high bsf PORTC,1 ;Set nSTEP high bcf PORTA,1 ;Turn red laser off bsf PORTA,2 ;Turn blue laser on return ;******************************************************************* ; Variable Initialisation Routine ; InitReg: clrf Delay1 ;Counter for 1ms delay routine. clrf Delay2 ;Counter for 1s delay routine. clrf Debounce ;Counter for ignoring the step button. clrf Track ;Slit stepper auto-steps to position 0. clrf CountOf ;Count Timer 1 overflows to expand by 256x. movlw 'r' movwf RedLaser ;'R' = on, 'r' = off. For status word. movlw 'B' movwf BlueLaser ;'B' = on, 'b' = off. For status word. clrf Mask ;Mask stepper auto-steps to position 0. clrf Disc ;Discriminator level in dB (binary). clrf DiscH ;Discriminator DAC high byte. movlw 07h ;\Discriminator DAC low byte. movwf DiscL ;/Note 2 LSBs of DAC are dummy. return ;******************************************************************* ; SSP Initialisation Routine ; ;TLC5615 Requirements: ;Data is rising edge clocked. ;SCK should idle low when /CS is high. InitSSP: bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ movlw 040h ;\ movwf SSPSTAT ;/ bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ movlw 022h ;\SPI master Fosc/64 movwf SSPCON ;/ return ;******************************************************************* ; EUSART Initialisation Routine ; InitUART: bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ movlw 0Ch ;\ movwf SPBRG ;| clrf SPBRGH ;| Set 9600 baud. bcf BAUDCTL,3 ;| bcf TXSTA,2 ;/ bcf TXSTA,4 ;Asynchronous mode. (SYNC=0) bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ bsf RCSTA,7 ;Enable serial port.(SPEN=1) bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ bsf TXSTA,5 ;Enable transmission. bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ bsf RCSTA,4 ;Enable reception. (CREN=1) return ;******************************************************************* ; Timer 1 Initialisation Routine ; InitTimer1: clrf TMR1H ;\ Reset Timer 1. clrf TMR1L ;/ movlw 47h ;\ External gate active low. movwf T1CON ;/ Ext clock. Timer on. bcf PIR1,0 ;Clear overflow interrupt flag (TMR1IF). bsf STATUS,RP0 ;Bank 1 bsf INTCON,7 ;Global interrupt enable (GIE). bsf INTCON,6 ;Enable peripheral interrupts (PEIE). bsf INTCON,3 ;Enable interrupt on change (RABIE). bsf IOCA,4 ;Enable interrupt on /T1G change. bsf PIE1,0 ;Enable Timer 1 overflow interrupts. bcf STATUS,RP0 ;Bank 0 movf PORTA,W ;Read Port A to prime IOC. return ;******************************************************************* ; 1s Delay Routine ; Delay1s: clrf Delay2 Loop1s: call Delay1ms call Delay1ms call Delay1ms call Delay1ms decfsz Delay2,F goto Loop1s return ;******************************************************************* ; 1ms Delay Routine ; Delay1ms: movlw .142 ;Delay ~1000uS movwf Delay1 decfsz Delay1,F ;This loop does 430 cycles goto $-1 decfsz Delay1,F ;This loop does 786 cycles goto $-1 return ;******************************************************************* ; Serial Character Received Routine ; SerCom: btfss RCSTA,1 ;\ Goto NoOverrun ;| Check for and handle bcf RCSTA,7 ;| receive overrun error. bsf RCSTA,7 ;| goto EndSerCom ;/ NoOverrun: btfss RCSTA,2 ;\ Goto FrameOK ;| Check for and handle bcf RCSTA,7 ;| receive framing error. bsf RCSTA,7 ;| goto EndSerCom ;/ FrameOK: movf RCREG,W ;\ Read and store received movwf RxChar ;/ character. sublw 'R' ;\ Check if received character btfsc STATUS,Z ;/ is the red laser on command. call RedOn ;Switch on red laser. movf RxChar,W ;Recover last character received. sublw 'r' ;\ Check if received character btfsc STATUS,Z ;/ is the red laser off command. call RedOff ;Switch off red laser. movf RxChar,W ;Recover last character received. sublw 'B' ;\ Check if received character btfsc STATUS,Z ;/ is the blue laser on command. call BlueOn ;Switch on blue laser. movf RxChar,W ;Recover last character received. sublw 'b' ;\ Check if received character btfsc STATUS,Z ;/ is the blue laser off command. call BlueOff ;Switch off blue laser. movf RxChar,W ;Recover last character received. sublw 'M' ;\ Check if received character btfsc STATUS,Z ;/ is the next mask command. call NextMask ;Step to next mask. movf RxChar,W ;Recover last character received. sublw 'm' ;\ Check if received character btfsc STATUS,Z ;/ is the previous mask command. call PrevMask ;Step to previous mask. movf RxChar,W ;Recover last character received. sublw 'I' ;\ Check if received character btfsc STATUS,Z ;/ is the step forward command. call StepFwd ;Step acceptance slit forward. movf RxChar,W ;Recover last character received. sublw 'i' ;\ Check if received character btfsc STATUS,Z ;/ is the step backwards command. call StepRev ;Step acceptance slit backwards. movf RxChar,W ;Recover last character received. sublw '0' ;\ Check if received character btfsc STATUS,Z ;/ is the seek position 0 command. call Seek_Trk0 ;Move acceptance slit to position 0. movf RxChar,W ;Recover last character received. sublw 'D' ;\ Check if received character btfsc STATUS,Z ;/ is the increase disc. level cmd. call IncDisc ;Increase discriminator 1 step. movf RxChar,W ;Recover last character received. sublw 'd' ;\ Check if received character btfsc STATUS,Z ;/ is the decrease disc. level cmd. call DecDisc ;Decrease discriminator 1 step. movf RxChar,W ;Recover last character received. EndSerCom: return ;******************************************************************* ; Send the Status Word to the EUSART ; SendStatus: movlw .42 ;\ Send '*' EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX1 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX1 ;/ bcf STATUS,RP0 ;Bank 0 movlw 'E' ;\ Send 'E' to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX2 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX2 ;/ bcf STATUS,RP0 ;Bank 0 movlw 'x' ;\ Send 'x' to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX3 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX3 ;/ bcf STATUS,RP0 ;Bank 0 movlw 'p' ;\ Send 'p' to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX4 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX4 ;/ bcf STATUS,RP0 ;Bank 0 movlw 't' ;\ Send 't' to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX5 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX5 ;/ bcf STATUS,RP0 ;Bank 0 movlw '1' ;\ Send '1' to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX6 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX6 ;/ bcf STATUS,RP0 ;Bank 0 movf RedLaser,W ;\ Send red laser status to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX7 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX7 ;/ bcf STATUS,RP0 ;Bank 0 movf BlueLaser,W ;\ Send blue laser status to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX8 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX8 ;/ bcf STATUS,RP0 ;Bank 0 movf Mask,W ;\ Send mask selected byte to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX9 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX9 ;/ bcf STATUS,RP0 ;Bank 0 movf Track,W ;\ Send acceptance slit position to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX10 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX10 ;/ bcf STATUS,RP0 ;Bank 0 movf Disc,W ;\ Send discriminator level byte to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX11 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX11 ;/ bcf STATUS,RP0 ;Bank 0 movf CountEx,W ;\ Send rate byte 2 to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX12 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX12 ;/ bcf STATUS,RP0 ;Bank 0 movf CountHi,W ;\ Send rate byte 1 to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX13 btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX13 ;/ bcf STATUS,RP0 ;Bank 0 movf CountLo,W ;\ Send rate byte 0 to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX14: btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX14 ;/ bcf STATUS,RP0 ;Bank 0 movlw .14 ;\Send CR to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX15: btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX15 ;/ bcf STATUS,RP0 ;Bank 0 movlw .10 ;\Send LF to EUSART. movwf TXREG ;/ bsf STATUS,RP0 ;Bank 1 LoopTX16: btfss TXSTA,1 ;\ Wait until Tx complete. goto LoopTX16 ;/ bcf STATUS,RP0 ;Bank 0 return ;******************************************************************* ; ; Switch On Red Laser Routine RedOn: bsf PORTA,1 ;Turn red laser on movlw 'R' ;\ Update status movwf RedLaser ;/ 'R' = on, 'r' = off. return ;******************************************************************* ; ; Switch Off Red Laser Routine RedOff: bcf PORTA,1 ;Turn red laser off movlw 'r' ;\ Update status movwf RedLaser ;/ 'R' = on, 'r' = off. return ;******************************************************************* ; ; Switch On Blue Laser Routine BlueOn: bsf PORTA,2 ;Turn blue laser on movlw 'B' ;\ Update status movwf BlueLaser ;/ 'B' = on, 'b' = off. return ;******************************************************************* ; ; Switch Off Blue Laser Routine BlueOff: bcf PORTA,2 ;Turn blue laser off movlw 'b' ;\ Update status movwf BlueLaser ;/ 'B' = on, 'b' = off. return ;******************************************************************* ; ; Step to Next Mask Routine (with limiting) NextMask: movlw MaxMask ;\ Forward, so test if at MaxMask subwf Mask,W ;| C=0 if MaxMask>Mask btfsc STATUS,C ;/ goto No_Step5 bcf PORTC,0 ;Low is forward incf Mask,F ;Update mask counter movlw .11 ;Step 11 times (1 step is 0.2646mm) movwf GenLoop call Delay1ms ;Delay for drection line to settle Next1: bcf PORTA,0 ;\ Pulse mask step line low bsf PORTA,0 ;/ call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms decfsz GenLoop,F goto Next1 No_Step5: return ;******************************************************************* ; ; Step to Previous Mask Routine (with limiting) PrevMask: btfsc PORTA,3 ;Reverse, so test if at positon 0 goto StepMask clrf Mask ;\ Is at position 0 (index mask) goto No_Step6 ;/ StepMask: bsf PORTC,0 ;High is reverse decf Mask,F ;Update mask counter movlw .11 ;Step 11 times (1 step is 0.2646mm) movwf GenLoop call Delay1ms ;Delay for drection line to settle Next2: bcf PORTA,0 ;\ Pulse mask step line low bsf PORTA,0 ;/ call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms btfss PORTA,3 ;Test if at positon 0 due to fault. goto No_Step6 ;If at 0 avoid forcing mechanism. decfsz GenLoop,F goto Next2 No_Step6: return ;******************************************************************* ; ; Forward Step Acceptance Slit Routine (with limiting) StepFwd: movlw MaxTrack ;\ Forward, so test if at MaxTrack subwf Track,W ;| C=0 if MaxTrack>Track btfsc STATUS,C ;/ goto No_Step3 bcf PORTC,0 ;Low is forward incf Track,F ;Update track counter call Delay1ms ;Delay for drection line to settle bcf PORTC,1 ;\ Pulse slit step line low bsf PORTC,1 ;/ No_Step3: return ;******************************************************************* ; ; Reverse Step Acceptance Slit Routine (with limiting) StepRev: btfsc PORTC,2 ;Reverse, so test if at positon 0 goto StepSlit clrf Track ;\ Is at position 0 (index mask) goto No_Step4 ;/ StepSlit bsf PORTC,0 ;High is reverse decf Track,F ;Update track counter call Delay1ms ;Delay for drection line to settle bcf PORTC,1 ;\ Pulse slit step line low bsf PORTC,1 ;/ No_Step4: return ;******************************************************************* ; ; Manual Acceptance Slit Step Routine (with limiting) Man_Step: btfsc PORTC,4 ;Test direction switch goto Reverse movlw MaxTrack ;\ Forward, so test if at MaxTrack subwf Track,W ;| C=0 if MaxTrack>Track btfsc STATUS,C ;/ goto No_Step2 goto Step1 Reverse: movf Track,F ;\ Reverse, so test if at btfsc STATUS,Z ;/ position 0 goto No_Step2 Step1: bcf PORTC,0 ;\ Test direction switch, incf Track,F ;| & copy to the direction btfss PORTC,4 ;| control line (low is forward) goto Step2 ;| bsf PORTC,0 ;| Update track counter decf Track,F ;| decf Track,F ;/ call Delay1ms ;Delay for drection line to settle Step2: bcf PORTC,1 ;\ Pulse slit step line low bsf PORTC,1 ;/ No_Step2: clrf Debounce ;\ Ignore buttons for a decf Debounce,F ;/ while. return ;******************************************************************* ; ; Acceptance Slit Position 0 Seek Routine Seek_Trk0: btfss PORTC,2 ;\ Check if already at track 0 return ;/ bsf PORTC,0 ;Reverse step direction call Delay1ms ;Delay for drection line to settle Next_Step: bcf PORTC,1 ;\ Pulse slit step line low bsf PORTC,1 ;/ call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms call Delay1ms btfsc PORTC,2 ;\ Keep stepping until nTRK0 goto Next_Step ;/ goes low. clrf Debounce ;\ Ignore buttons for a decf Debounce,F ;/ while. clrf Track ;Reset track counter return ;******************************************************************* ; ; Increase Discriminator Level 1 Step Routine ; ;One step is x2 (6dB) achieved by shifting. IncDisc: movlw MaxDisc ;\ Forward, so test if at maximum subwf Disc,W ;| C=0 if MaxDisc>Disc btfsc STATUS,C ;/ goto NoIncDisc ;At maximum bsf STATUS,C ;\ rlf DiscL,F ;|Multiply DAC value by 2 (approx.) rlf DiscH,F ;/ movlw .6 ;\Add 6 to Disc addwf Disc,F ;/ bcf PORTC,6 ;Enable discriminator DAC movf DiscH,W ;\Send high byte to DAC movwf SSPBUF ;/ bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ Wait1: btfss SSPSTAT,BF ;Has data been rxd (tx complete) goto Wait1 ;Not yet movf SSPBUF,W ;Have to read rxd data to clear BF bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ movf DiscL,W ;\Send low byte to DAC movwf SSPBUF ;/ bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ Wait2: btfss SSPSTAT,BF ;Has data been rxd (tx complete) goto Wait2 ;Not yet movf SSPBUF,W ;Have to read rxd data to clear BF bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ bsf PORTC,6 ;Disable discriminator DAC NoIncDisc: return ;******************************************************************* ; ; Decrease Discriminator Level 1 Step Routine ; ;One step is /2 (-6dB) achieved by shifting. DecDisc: movf Disc,F ;\Test if at minimum btfsc STATUS,Z ;/Disc = 0dB at minimum goto NoDecDisc ;At minimum bcf STATUS,C ;\ rrf DiscH,F ;|Divide DAC value by 2 (approx.) rrf DiscL,F ;/ movlw .6 ;\Subtract 6 from Disc subwf Disc,F ;/ bcf PORTC,6 ;Enable discriminator DAC movf DiscH,W ;\Send high byte to DAC movwf SSPBUF ;/ bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ Wait3: btfss SSPSTAT,BF ;Has data been rxd (tx complete) goto Wait3 ;Not yet movf SSPBUF,W ;Have to read rxd data to clear BF bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ movf DiscL,W ;\Send low byte to DAC movwf SSPBUF ;/ bsf STATUS,RP0 ;\Bank 1 bcf STATUS,RP1 ;/ Wait4: btfss SSPSTAT,BF ;Has data been rxd (tx complete) goto Wait4 ;Not yet movf SSPBUF,W ;Have to read rxd data to clear BF bcf STATUS,RP0 ;\Bank 0 bcf STATUS,RP1 ;/ bsf PORTC,6 ;Disable discriminator DAC NoDecDisc: return ;******************************************************************* end