;This is the code for programming the QROP Meter by Jason Hsu, AG4DG/AA0II. ;It is based on the Bert Kelley (AA4FB) design published in the December 1999 issue of QST magazine. ;Like Bert Kelley, I use a Microchip PICSTART PLUS programmer. ;My version has the following differences from Bert Kelley's version: ;1.A wattmeter as well as an SWR meter. ;2.A 16F72 PIC microcontroller instead of the PIC16C71. ;3.Displays consist of discrete LEDs instead of a digital numeric display. ;4.Because the 16F72 cannot be configured to keep pins RA0 and RA1 as analog AND RA2, RA3, RA4, and ; RA5 as digital SIMULTANEOUSLY, it is necessary to change the configuration to allow RA0 and RA1 ; to be analog when the forward and reflected voltage samples are needed and to allow all of the ; other port A pins to be outputs when the SWR LED display is needed. ;5.Because pin RA4 of the 16F72 has an open drain output with high impedance (unlike the low output ; impedances of all other I/O pins), it has to be configured differently. The 330 ohm resistor and ; LED in series with this pin connect to the 5V supply. The output is kept low at all times. ; The corresponding bit in TRISA is used to control the output voltage. Setting this port as ; an output port gives it low impedance, which means 0V output. Setting this port as an input ; port gives it high impedance, which means 5V output. ;Be sure that your MPLAB project includes this file (swrwatt.asm) under source files ;and P16f72.inc under header files. ;Keep the directory path name for the project short, ;because the compiler has difficulty with long names. ;Under the Debugger->Select Tool menu, I use MPLAB SIM. ;Under the Programmer->Select Programmer menu, I use PICSTART Plus. ;Subtraction is performed with 2's complement. x-y=x+NOT(y)+1. ;Please note that when you perform a subtraction option, a result >=0 sets the carry flag to '1' ;while a result <0 sets the carry flag to '0'. Performing the 2's complement subtraction manually ;will illustrate why this is so. list p=pic16f72 include "p16f72.inc" __config b'11111110111001' ;These are the same settings as those used by Bert Kelley. ;Code protection off, power-up timer disabled, watchdog timer disabled, XT oscillator ;Bits 13-7: unimplemented, read as '1' ;Bit 6: BOREN, brown-out reset enable bit (0=disabled) ;Bit 5: unimplemented, read as '1' ;Bit 4: CP, FLASH program memory code protection bit (1=off) ;Bit 3: PWRTEN, power-up timer enable bit (1=disabled) ;Bit 2: WDTEN, watchdog timer enable bit (0=disabled) ;Bits 1-0: FOSC1/FOSC0 oscillator selection bits (01=crystal XT oscillator) radix hex errorlevel -302 ;The variables used here that are predefined in p16f72.inc are: ;W=0, F=1, TMR0=1, STATUS=3, PORTA=5, PORTB=6, PORTC=7,ADRES=1e, ;ADCON0=1f, ADCON1=009f, TRISA=0085, TRISB=0086, TRISC=0087, ;RP1=6, RP0=5, Z=2, C=1 ;RESERVE GENERAL PURPOSE REGISTERS (addresses 20 to 7h in bank 0) ;NOTE: The "0x" denotes hex numbers. Binary numbers are denoted by ''. count equ 0x20;Utility counter ncount equ 0x21;Delay counter temp equ 0x22;Temporary register fwd equ 0x23;Forward voltage units from A/D refl equ 0x24;Reflected voltage units from A/D swrnumlo equ 0x25;Forward+reflected voltage units swrnumhi equ 0x26;Carry component of swrnumlo (if forward+reflected>255) swrden equ 0x27;Forward-reflected voltage units swrint equ 0x28;SWR with remainder truncated prodlo equ 0x29;Product of multiplication prodhi equ 0x2a;Carry component of prod1o dendlo equ 0x2b;Dividend in division algorithm dendhi equ 0x2c;Carry component of dividend in division algorithm dvsrlo equ 0x2d;Divisor in division algorithm ;quotient/dividend/divisor tenths equ 0x2e;Tenths component of SWR invnumlo equ 0x2f;Part of fwd/refl calculation invnumhi equ 0x30;Part of fwd/refl calculation tenths_inv equ 0x31;Tenths component of fwd/refl org 0x000; Program stored at location 000 start ;Set the microcontroller configurations ;Set the RP bit settings to select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Set the tris bits to determine which I/O pins are inputs and which are outputs. ;0=outputs, 1=inputs movlw b'000011';W register=b'000011' movwf TRISA;TRISA=b'000011' ;Now RA5, RA4, RA3, and RA2 are outputs while AN1 and AN0 are inputs. movlw b'00000000';W register=b'00000000' movwf TRISB;TRISB=b'00000000' ;Now RB7-RB0 pins are all outputs. movlw b'00000000';W register=b'00000000' movwf TRISC;TRISC=b'00000000' ;Now RC7-RC0 pins are all outputs. ;Finished setting the tris bits. movlw b'00000100' movwf ADCON1;ADCON1=b'00000100' ;Bits 7-3 are unimplemented. Bits 2-0 determine the configuration. ;Now RA0, RA1, and RA3 are analog while RA2 and RA4 are digital. ;VREF=VDD. bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register bank 0 is now selected. bcf INTCON,GIE;Set GIE (Global Interrupt Enable) bit of INTCON (Interrupt Control) register to 0. ;Global interrupt is now disabled. ;FORWARD POWER ACQUISITION getfwd ;Select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Configure A ports for analog/digital. movlw b'00000100' movwf ADCON1;ADCON1=b'00000100' ;Bits 7-3 are unimplemented. Bits 2-0 determine the configuration. ;Now RA0 and RA1 are analog. ;Completed configuration of A ports. ;Select Register Bank 0 bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register Bank 0 is now selected. ;Begin preparation for A/D conversion process movlw b'10000001'; movwf ADCON0;adcon0=b'10000001' ;Bits 7-6: A/D conversion clock select bits, 10=FOSC/32 ;Bits 5-3: Analog Channel Select Bits, 000=Channel 0=RA0 ;Bit 2: A/D conversion status bit, 0=A/D conversion not in progress ;Bit 1: unimplemented, read as '0' ;Bit 0: A/D On Bit, 1=A/D converter module is operating call del_20;Delay 20 microseconds bsf ADCON0,2;Set bit 2 of ADCON0 to '1'. This starts the A/D conversion process. test1 btfsc ADCON0,2;If bit 2 of ADCON0 is '0', skip the next instruction. ;Otherwise, proceed to the next instruction. ;Don't move on until the A/D conversion process is complete. goto test1 ;Completed A/D conversion process movf ADRES,W;Move data from ADRES (A/D conversion result) to W register. movwf fwd;fwd=adres=RA0 input=forward voltage sample ;Set the RP bit settings to select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Configure A ports for analog/digital. movlw b'00000111' movwf ADCON1;ADCON1=b'00000111' ;Bits 7-3 are unimplemented. Bits 2-0 determine the configuration. ;Now RA2, RA3, RA4, and RA5 are digital. ;Completed configuration of A ports. ;Set the RP bit settings to select Register Bank 0 bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register bank 0 is now selected. goto displaywatt ;fwd=forward voltage sample*10V/256 displaywatt ;WATTMETER DISPLAY call clear_wattmeter call clear_swrmeter ;led A/D range VF2 range Approx. Power Power Output Range ;all dark 0-7 0-.316V <.20W 0-.20W ;D11 8-10 .32-.45V .28W .20-.40W ;D12 11-15 .45-.63V .56W .40-.79W ;D13 16-22 .63-.89V 1.1W .79-1.6W ;D14 23-31 .89-1.3V 2.2W 1.6-3.2W ;D15 32-44 1.3-1.8V 4.5W 3.2-6.3W ;D16 45-63 1.8-2.5V 8.9W 6.3-13W ;D17 64-89 2.5-3.5V 18W 13-25W ;D18 90-127 3.5-5.0V 35W 25-50W ;D19 128-179 5.0-7.1V 71W 50-100W ;D20 180-255 7.1-10V >100W 100-200W movf fwd, W;W=fwd movwf temp;temp=fwd movlw .180;W='180' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'180'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display20 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .128;W='128' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'128'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display19 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .90;W='90' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'90'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display18 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .64;W='64' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'64'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display17 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .45;W='45' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'45'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display16 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .32;W='32' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'32'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display15 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .23;W='23' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'23'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display14 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .16;W='16' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'16'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display13 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .11;W='11' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'11'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display12 movf fwd, W;W=fwd movwf temp;temp=fwd movlw .8;W='8' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-'8'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This compares fwd to lower thresholds. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display11 goto getfwd;If the forward voltage is below all of the D11-D20 thresholds, both the wattmeter ;and SWRmeter displays will be dark, and we return to getfwd. ;REFLECTED POWER ACQUISITION getrefl ;Select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Configure A ports for analog/digital. movlw b'00000100' movwf ADCON1;ADCON1=b'00000100' ;Bits 7-3 are unimplemented. Bits 2-0 determine the configuration. ;Now RA0 and RA1 are analog. ;Completed configuration of A ports. ;Select Register Bank 0 bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register Bank 0 is now selected. ;Begin preparation for A/D conversion process movlw b'10001001'; movwf ADCON0;adcon0=b'10001001' ;Bits 7-6: A/D conversion clock select bits, 10=FOSC/32 ;Bits 5-3: Analog Channel Select Bits, 001=Channel 1=RA1 ;Bit 2: A/D conversion status bit, 0=A/D conversion not in progress ;Bit 1: unimplemented, read as '0' ;Bit 0: A/D On Bit, 1=A/D converter module is operating call del_20;Delay 20 microseconds bsf ADCON0,2;Set bit 2 of ADCON0 to '1'. This starts the A/D conversion process. test2 btfsc ADCON0,2;If bit 2 of ADCON0 is '0', skip the next instruction. ;Otherwise, proceed to the next instruction. ;Don't move on until the A/D conversion process is complete. goto test2 movf ADRES,W;Move data from ADRES (A/D conversion result) to W register. movwf refl;refl=adres=RA1 input=reflected voltage sample ;refl=reflected voltage sample*10V/256 ;Set the RP bit settings to select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Configure A ports for analog/digital. movlw b'00000110' movwf ADCON1;ADCON1=b'00000110' ;Bits 7-3 are unimplemented. Bits 2-0 determine the configuration. ;Now RA2, RA3, RA4, and RA5 are digital. ;Completed configuration of A ports. ;Set the RP bit settings to select Register Bank 0 bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register bank 0 is now selected. movf fwd,W ;W=fwd movwf temp;temp=fwd movf refl,W ;W=refl subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=fwd-refl. If fwd=refl, the carry bit equals '1'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. This lights the maximum SWR LED. ;If carry bit equals '1', execute the next instruction. This goes to SWR calculation. goto calculate_swr goto display10;fwd'11111111', then the carry bit (bit C of STATUS register) is 1. ;If the carry bit equals '0', then skip the next instruction. ;If the carry bit equals '1', then execute the next instruction. incf swrnumhi,F;Increment swrnumhi. ;Because F=1, put result back in register swrnumhi. swrnumhi='00000001'. ;At this point, if fwd+rev>'11111111', then swrnumhi=1. Otherwise, swrnumhi=0. movf refl,W;Because W='0', W=refl subwf fwd,W;Use 2's complement to subtract the contents of the W register from register fwd. ;Store the result in the W register. Thus, W=fwd-refl. movwf swrden;Move data from W register to swrden register. swrden=fwd-refl ;Setup for division to follow. movwf dvsrlo;Move data from W register to dvsrlo register. dvsrlo=fwd-refl movf swrnumhi,W;Because W='0', W=swrnumhi movwf dendhi;dendhi=W, dendhi=swrnumhi movf swrnumlo,W;Because W='0', W=swrnumlo movwf dendlo;dendlo=W, dendlo=swrnumlo ;At this point, dvsrlo=fwd-refl, 2^8*dendhi+dendlo=refl+fwd. ;If refl+fwd>'11111111', then dendhi='00000001'. Otherwise, dendhi='00000000'. ;SWR numerator=2^8*dendhi+dendlo ;SWR denominator=dvsrlo call divide movf dendlo,W ;Quotient in dendlo, rem. in dendhi movwf swrnumhi ;swrnumhi=dendlo=SWR with fractional component truncated movf dendhi,W ;W=dendhi=remainder from SWR division algorithm, swrhi in bcd if < 10 decimal movwf swrnumlo ;swrnumlo=remainder from SWR division algorithm goto calculate_swr_tenths ;CALCULATE TENTHS DIGIT OF SWR ;2^8*prodhi+prodlo=10*swrnumlo calculate_swr_tenths movlw 0x0a;W='0a' movwf count;count='0a', multiply swrnumlo by 0ah=multiply swrnumlo by 10 clrf prodhi;prodhi='00000000' clrf prodlo;prodlo='00000000' movf swrnumlo,W;W=swrnumlo, remainder is added 10 times multiply addwf prodlo,F;prodlo=prodlo+swrnumlo; increment prodlo by swrnumlo btfsc STATUS,C ;If carry bit of STATUS register is 1, execute the next instruction. ;If carry bit of STATUS register is 0, skip the next instruction. goto inc_hi; This subroutine increments prodhi. tally decfsz count,F;Decrement count. If the result is 0, skip the next instruction. ;Thus, we exit the multiply algorithm. ;If the result is 1, go to the next instruction. ;Thus, we continue to add swrnumlo to prodlo. goto multiply goto bcd; After multiplication is finished, convert binary to decimal. inc_hi incf prodhi,F;Increment prodhi goto tally ;As we enter bcd, 2^8*prodhi+prodlo=10*swrnumlo bcd movf prodhi,W;W=prodhi movwf dendhi;dendhi=prodhi movf prodlo,W;W=prodlo movwf dendlo;dendlo=prodlo movf swrden,W;W=swrden movwf dvsrlo;dvsrlo=swrden ;At this point, dendhi=prodhi, dendlo=prodlo, and dvsrlo=fwd-refl. ;We now divide 10*swrnumlo by dvsrlo to convert the remainder from the ;SWR calculation to tenths. call divide;(swrnumlo*10)/(fwd-refl)=tenths movf dendlo,W;W=dendlo movwf tenths;tenths=dendlo goto displayswr1 ;LED SWR Range 1/REFL Range ;D10 Infinity N/A ;D9 17.0 or higher N/A ;D8 8.0-16.9 N/A ;D7 5.0-7.9 N/A ;D6 3.5-4.9 N/A ;D5 2.6-3.4 N/A ;D4 2.0-2.5 N/A ;D3 N/A 3.0-4.4 ;D2 N/A 4.5-8.9 ;D1 N/A 9.0 or higher displayswr1 ;SWR METER DISPLAY (D7-D9) movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .17;W='17' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'17' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display9 movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .8;W='8' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'8' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display8 movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .5;W='5' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'5' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display7 goto displayswr2 displayswr2;SWR METER DISPLAY (D4-D6) movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .4;W='4' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'4' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display6 movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .3;W='3' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'3' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto displayswr2a movf swrnumhi, W;W=swrnumhi movwf temp;temp=swrnumhi movlw .2;W='2' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=swrnumhi-'2' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto displayswr2b goto calculate_inv displayswr2a ;SWR is 3.0-3.9 movf tenths, W;W=tenths movwf temp;temp=tenths movlw .5;W='5' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=tenths-'5' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display6 goto display5 displayswr2b ;SWR is 2.0 to 2.9 movf tenths, W;W=tenths movwf temp;temp=tenths movlw .6;W='6' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=tenths-'6' btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If carry bit equals '1', execute the next instruction. This lights the LED. goto display5 goto display4 calculate_inv ;fwd/refl clrf dendhi ;dendhi=0 initially because numerator is fwd and <=255 movf fwd,W ;Because W='0', W=fwd movwf dendlo ;dendlo=fwd movf refl,W ;Because W='0', W=refl movwf dvsrlo ;dvsrlo=refl call divide ;Quotient in dendlo, remainder in dendhi movf dendlo,W ; Because W='0, W=dendlo movwf invnumhi ;invnumhi=dendlo=fwd/refl with fractional component truncated movf dendhi,W ;W=dendhi=remainder from fwd/refl division algorithm, swrhi in bcd if < 10 decimal movwf invnumlo ;invnumlo=remainder from fwd/refl division algorithm goto inv_tenths ;CALCULATE TENTHS DIGIT OF fwd/refl ;2^8*prodhi+prodlo=10*invnumlo inv_tenths movlw 0x0a;W='0a' movwf count;count='0a', multiply swrnumlo by 0ah=multiply swrnumlo by 10 clrf prodhi;prodhi='00000000' clrf prodlo;prodlo='00000000' movf invnumlo,W;W=invnumlo, remainder is added 10 times multiply2 addwf prodlo,F;prodlo=prodlo+invnumlo; increment prodlo by invnumlo btfsc STATUS,C ;If carry bit of STATUS register is 1, execute the next instruction. ;If carry bit of STATUS register is 0, skip the next instruction. goto inc_hi_2; This subroutine increments prodhi. tally2 decfsz count,F;Decrement count. If the result is 0, skip the next instruction. ;Thus, we exit the multiply algorithm. ;If the result is 1, go to the next instruction. ;Thus, we continue to add invnumlo to prodlo. goto multiply2 goto bcd2; After multiplication is finished, convert binary to decimal. inc_hi_2 incf prodhi,F;Increment prodhi goto tally2 ;As we enter bcd, 2^8*prodhi+prodlo=10*invnumlo bcd2 movf prodhi,W;W=prodhi movwf dendhi;dendhi=prodhi movf prodlo,W;W=prodlo movwf dendlo;dendlo=prodlo movf refl,W;W=refl movwf dvsrlo;dvsrlo=refl ;At this point, dendhi=prodhi, dendlo=prodlo, and dvsrlo=refl. ;We now divide 10*invnumlo by dvsrlo to convert the remainder from the ;fwd/refl calculation to tenths. call divide;(invnumlo*10)/refl=tenths movf dendlo,W;W=dendlo movwf tenths_inv;tenths_inv=dendlo goto displayswr3 displayswr3;SWR METER DISPLAY (D1-D3) movf invnumhi, W ;W=invnumhi movwf temp ;temp=invnumhi movlw .9 ;W='9' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=invnumhi-'9'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If the carry bit equals '1', execute the next instruction. This lights the LED. goto display1 movf invnumhi, W ;W=invnumhi movwf temp ;temp=invnumhi movlw .5 ;W='5' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=invnumhi-'5'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If the carry bit equals '1', execute the next instruction. This lights the LED. goto display2 movf invnumhi, W ;W=invnumhi movwf temp ;temp=invnumhi movlw .4 ;W='4' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=invnumhi-'4'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If the carry bit equals '1', execute the next instruction. goto displayswr3a goto display3 displayswr3a movf tenths_inv, W ;W=invnumhi movwf temp ;temp=tenths_inv movlw .5 ;W='5' subwf temp,F ;Subtract (2's complement) W register from temp and store result in temp. ;temp=tenths_inv-'5'. btfsc STATUS,C ;If the carry bit equals '0', skip the next instruction. ;If the carry bit equals '1', execute the next instruction. goto display2 goto display3 del_20 ;DELAY 20 microseconds movlw 0x10; movwf count;count='0x10' again decfsz count,f;Decrement the count register and return the resulting value to count. ;If the result is 0, skip the next instruction. Otherwise, execute the next instruction. goto again return clear_wattmeter bcf PORTA,5;Set bit 5 of PORTA to 0. This turns off LED D11. bcf PORTC,0;Set bit 5 of PORTA to 0. This turns off LED D12. bcf PORTC,1;Set bit 5 of PORTA to 0. This turns off LED D13. bcf PORTC,2;Set bit 5 of PORTA to 0. This turns off LED D14. bcf PORTC,3;Set bit 5 of PORTA to 0. This turns off LED D15. bcf PORTB,0;Set bit 5 of PORTA to 0. This turns off LED D16. bcf PORTC,7;Set bit 5 of PORTA to 0. This turns off LED D17. bcf PORTC,6;Set bit 5 of PORTA to 0. This turns off LED D18. bcf PORTC,5;Set bit 5 of PORTA to 0. This turns off LED D19. bcf PORTC,4;Set bit 5 of PORTA to 0. This turns off LED D20. return clear_swrmeter bcf PORTB,7;Set bit 5 of PORTA to 0. This turns off LED D1. bcf PORTB,6;Set bit 5 of PORTA to 0. This turns off LED D2. bcf PORTA,2;Set bit 5 of PORTA to 0. This turns off LED D3. bcf PORTA,3;Set bit 5 of PORTA to 0. This turns off LED D4. bcf PORTA,4;Set bit 5 of PORTA to 0. ;Set the RP bit settings to select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Set the tris bits to determine which I/O pins are inputs and which are outputs. ;0=outputs, 1=inputs bsf TRISA,4 ;Port A pin 4 is now an input pin. This means high impedance, low current, ;and a dark LED D5. bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register bank 0 is now selected. ;Because register PORTA bit 4 is 0 and register TRISA bit 4 is 0, the RA4 output is 0V. bcf PORTB,5;Set bit 5 of PORTA to 0. This turns off LED D6. bcf PORTB,4;Set bit 5 of PORTA to 0. This turns off LED D7. bcf PORTB,3;Set bit 5 of PORTA to 0. This turns off LED D8. bcf PORTB,2;Set bit 5 of PORTA to 0. This turns off LED D9. bcf PORTB,1;Set bit 5 of PORTA to 0. This turns off LED D10. return ;-Divide program written by Bob Fehrenbach, from ;http://members.tripod.com/~mdileo/snippic.html ;This divide program performs long division in base 2. ;quotient=dividend/divisor ;At the start of the divide algorithm, dividend=2^8*dendhi+dendlo and divisor=dvsrlo. ;At the end of the divide algorithm, dendlo=quotient and dendhi=remainder. divide movlw 0x08 ;W='00001000' movwf count ;count='00001000' clrf temp ;temp holds borrow, temp=0 divloop rlf dendlo,f ;Rotate contents of register dendlo one bit to the left through the carry flag. rlf dendhi,f ;Rotate the contents of register dendhi one bit to the left through the carry flag. ; Any carry factor from "rlf dendlo,f" is rotated in to the least significant digit. rlf temp,f ;Rotate the contents of register temp one bit to the left. ;Any carry factor from "rlf dendhi,f" is rotated in to the least significant digit. ;These rlf commands double the value of 2^16*temp+2^8*dendhi+dendlo. movf dvsrlo,w ;W=dvsrlo subwf dendhi,w ;W=dendhi-dvsrlo btfss temp,0 ;If bit 0 of temp is '0', then execute the next instruction, ;If bit 0 of temp is '1', then skip the next instruction. skpnc ;Skip next instruction. movwf dendhi ;dendhi=W=dendhi-dvsrlo ;At this point, if bit 0 of temp is '0', dendhi is unchanged since the "rlf dendhi,f" command. ;At this point, if bit 0 of temp is '1', dendhi is decremented by dvsrlo by 2's complement. btfsc temp,0 ;If bit 0 in temp is '1', execute the next instruction. ;If bit 0 in temp is '0', skip the next instruction. rrf temp,f ;halve temp ;At this point, if bit 0 in temp is '0', temp is unchanged. ;At this point, if bit 0 in temp is '1', temp is halved (rotate bits to the right) ;and gets carry from dendhi-dvsrlo. decfsz count,f ;Decrement count by 1. ;If result is 0 (8 times through divloop), skip the next instruction. goto divloop ;quotient in dendlo rlf dendlo,f ;remainder in dendhi return display1 bsf PORTB,7 goto wait display2 bsf PORTB,6 goto wait display3 bsf PORTA,2 goto wait display4 bsf PORTA,3 goto wait display5 bcf PORTA,4;Set bit 5 of PORTA to 0. ;Set the RP bit settings to select Register Bank 1. bcf STATUS,RP1;Bit RP1 of STATUS register set to b'0'. bsf STATUS,RP0;Bit RP0 of STATUS register set to b'1'. ;Register Bank 1 selected. ;Set the tris bits to determine which I/O pins are inputs and which are outputs. ;0=outputs, 1=inputs bcf TRISA,4 ;Port A pin 4 is now an output pin. This means low impedance, high current,. ; and a lit LED D5. bcf STATUS,RP1;Set bit RP1 of STATUS register to b'0'. bcf STATUS,RP0;Set bit RP0 of STATUS register to b'0'. ;Register bank 0 is now selected. ;Because register PORTA bit 4 is 0 and register TRISA bit 4 is 0, the RA4 output is 0V. goto wait display6 bsf PORTB,5 goto wait display7 bsf PORTB,4 goto wait display8 bsf PORTB,3 goto wait display9 bsf PORTB,2 goto wait display10 bsf PORTB,1 goto wait display11 bsf PORTA,5 goto getrefl display12 bsf PORTC,0 goto getrefl display13 bsf PORTC,1 goto getrefl display14 bsf PORTC,2 goto getrefl display15 bsf PORTC,3 goto getrefl display16 bsf PORTB,0 goto getrefl display17 bsf PORTC,7 goto getrefl display18 bsf PORTC,6 goto getrefl display19 bsf PORTC,5 goto getrefl display20 bsf PORTC,4 goto getrefl ;WAIT 1ms after lighting SWR LED wait clrf ncount delay1 decf ncount,1 btfss STATUS,2 goto delay1 goto getfwd END