start: 'This program is fully protected by the provisions of the 'Commonwealth Copyright Act (Australia). Although any form 'of reproduction contravenes the Act, the author is not concerned 'about bona fide electronic hobbyists (and particularly radio 'amateurs) making single copies of it for their own personal 'use. However, commercial organisations should note that no 'significant part of this software can be offered for sale or 'sold, either on its own or as part of an assembly, unless a 'licence to do so has been obtained from myself-James Tregellas, '14 Sheringa Drive, Morphett Vale 5162 July 2004 'Subroutine to blank leading zeros on F, R and X displays inserted ' 11-Jan-2005. VK5OQ gosub init 'initialise lcd battery: readadc 3,b1 'readadc 3.External resistors are scaled to give a resulting 'count of around 120 for a 12volt battery-16K from +12volt to 'adc input 3 and 3K9 from adc input 3 to ground. let w0=b1*100 'adjust the adc count by multiplication and then division so that let w0=w0/100 'the display shows the correct voltage - change say division only w1=w0/100 'Derive individual digits for display w2=w0//100 w2=w2/10 w3=w0//10 w1=w1+48 'convert individual digits to ASCII w2=w2+48 w3=w3+48 let b1=1 gosub wrins 'ASCII characters are formatted,punctuated,and labelled, let b10="B" 'and fed to 16 character X 2 line alphanumeric display- gosub wrchr 'display starts at position 1- Display uses industry let b10="A" 'standard Hitachi HD44780 chip. Display format can be gosub wrchr 'simply altered to accomodate 2X20,2X40,4X16 displays let b10="T" gosub wrchr let b10="T" gosub wrchr let b10="E" gosub wrchr let b10="R" gosub wrchr let b10="Y" gosub wrchr let b10="=" gosub wrchr let b10=b2 gosub wrchr let b10=b4 gosub wrchr let b10="." gosub wrchr let b10=b6 gosub wrchr let b10="V" gosub wrchr pause 6000 'display battery volts for 1.5 seconds main: if pin2=1 then quick 'Frequency counter routine. 5 digit resolution count 3,4093,w0 'Max input frequency is 50KHz on digital input 3 (IC pin14)- w1=w0/10000 'NOTE-careful measurement shows 100KHz published is WRONG. w2=w0//10000 w2=w2/1000 w3=w0//1000 'Routines with w1,w2,w3,w4,w6 recover individual digits from w3=w3/100 'count total w0. Clock rate used is 16MHz. Prescaler divider w4=w0//100 'ratio used to feed input 3 is 1024. w4=w4/10 w6=w0//10 let w1=w1+48 'Individual digits are converted to ASCII by adding 48 let w2=w2+48 let w3=w3+48 let w4=w4+48 let w6=w6+48 gosub leadzero 'suppress one leading zero if neccessary let b1=1 gosub wrins 'ASCII characters are formatted,punctuated,and labelled, let b10=b2 'and fed to 16 character X 2 line alphanumeric display- gosub wrchr 'display starts at position 1- Display uses industry let b10=b4 'standard Hitachi HD44780 chip. Display format can be gosub wrchr 'simply altered to accomodate 2X20,2X40,4X16 displays let b10="." gosub wrchr let b10=b6 gosub wrchr let b10=b8 gosub wrchr let b10=b12 gosub wrchr let b10="M" gosub wrchr let b10="H" gosub wrchr let b10="z" gosub wrchr goto imped quick: count 3,409,w0 'Frequency counter routine. 4 digit resolution w1=w0/1000 'Comments as for preceding routine w2=w0//1000 w2=w2/100 w3=w0//100 w3=w3/10 w4=w0//10 let w1=w1+48 let w2=w2+48 let w3=w3+48 let w4=w4+48 gosub leadzero 'suppress one leading zero if neccessary let b1=1 gosub wrins let b10=b2 gosub wrchr let b10=b4 gosub wrchr let b10="." gosub wrchr let b10=b6 gosub wrchr let b10=b8 gosub wrchr let b10="M" gosub wrchr let b10="H" gosub wrchr let b10="z" gosub wrchr imped: '3 voltages are read from test network via ADC 'inputs AN0(ICpin2),AN1(ICpin3)AN2(ICpin4) and 'used to calculate magnitudes of complex and 'real parts of antenna load attached readadc 0,b1 'b1=network input volts readadc 1,b2 'b2=voltage proportional to network current readadc 2,b3 'b3=network output voltage let b1=b1/2 'input voltages halved to prevent overflows let b2=b2/2 'during calculations following let b3=b3/2 if b1<5 then cactus 'no rf oscillator output to drive network '-display error message if b2<5 then open 'no network current.Display "open" after 'frequency then return to program start if b3<5 then short 'no network output volts-display "short"after 'frequency then return to program start let b0=b2+b3 if b1>b0 then rpure 'impossible output from network-b1>b2+b3 '-modify output b1 and treat as pure resistance goto square rpure: let b1=b2+b3 square: let w2=b1*b1 'calculate b1 squared let w3=b2*b2 'calculate b2 squared let w4=b3*b3 'calculate b3 squared let w5=w3+w4 if w2999 then r2large if w4>999 then x2large goto printr r2large: let b1=192 gosub wrins let b10="R" gosub wrchr let b10=">" gosub wrchr let b10="9" gosub wrchr let b10="9" gosub wrchr let b10="9" gosub wrchr let b10=$f4 gosub wrchr goto main x2large: let b1=192 gosub wrins let b10="X" gosub wrchr let b10=">" gosub wrchr let b10="9" gosub wrchr let b10="9" gosub wrchr let b10="9" gosub wrchr let b10=$f4 gosub wrchr goto main printr: let w0=w2 'recover individual digits from w2 (resistance) let w6=w0 w1=w0/100 w2=w0//100 w2=w2/10 w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 gosub leadzero 'suppress one or two leading zeros if neccessary let b10=" " 'Format and display resistance on line 1 gosub wrchr let b10="R" gosub wrchr let b10="=" gosub wrchr let b10=b2 gosub wrchr let b10=b4 gosub wrchr let b10=b6 gosub wrchr let b10=$f4 gosub wrchr printx: let w0=w4 'Recover individual digits from w4 (reactance) w1=w0/100 w2=w0//100 w2=w2/10 w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 gosub leadzero 'suppress one or two leading zeros if neccessary let b1=192 'Format and display reactance at start gosub wrins 'of line 2 (address $C0) let b10="X" gosub wrchr let b10="=" gosub wrchr let b10=b2 gosub wrchr let b10=b4 gosub wrchr let b10=b6 gosub wrchr let b10=$f4 gosub wrchr w0=0 w1=0 w2=0 w3=0 w5=0 swr: let w5=w4 if w6=0 then swr10 'if resistance(w6)=0 then display SWR>10 if w6<50 then swr1 'if resistance is<50R then use modified 'equations to avoid negative numbers if w6=50 then swr3 'if the resistance is 50R, use SWR3 to avoid 'square root of zero in equations if w6<150 then swr5 'if resistance is <150R but >50R, use standard 'equations for max. accuracy swr7: 'if resistance is >150R, use modified standard w6=w6/6 'standard equations to avoid 16 bit overflows w5=w5/6 w4=w6+8 w4=w4*w4 w2=w5*w5 w4=w4+w2 gosub squrtw4 w3=w6-8 w3=w3*w3 w2=w5*w5 w3=w3+w2 gosub squrtw3 w4=w4 w3=w3 goto calcswr: swr1: if w5<150 then swr2 goto swr10 swr2: w4=w6+50 w4=w4*w4 w2=w5*w5 w4=w4+w2 gosub squrtw4 w3=50-w6 w3=w3*w3 w2=w5*w5 w3=w3+w2 gosub squrtw3 goto calcswr: swr3: if w5=0 then swr4 if w5>150 then swr10 w3=w5 w4=w6+50 w4=w4*w4 w2=w5*w5 w4=w4+w2 gosub squrtw4 goto calcswr swr4: w5=0 w4=100 goto calcswr swr5: if w5<150 then swr6: goto swr7 swr6: w4=w6+50 w4=w4*w4 w2=w5*w5 w4=w4+w2 gosub squrtw4 w3=w6-50 w3=w3*w3 w2=w5*w5 w3=w3+w2 gosub squrtw3 goto calcswr: calcswr: 'routine for calculating SWR from 'SWR=w4+w3/w4-w3. if w4=w3 then swr10 'covers case where w4=w3 due to huge ratios 'existing between R and X and R+X squared= 'R-X squared (forced by integers) w1=w4+w3 w1=w1*100 w2=w4-w3 w1=w1/w2 if w1>999 then swr10 swrprint: w0=w1 w1=w0/100 'Recover individual digits from w0 (SWR) w2=w0//100 w2=w2/10 w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 let b1=200 'Format and display SWR starting at centre gosub wrins 'of line 2 (address $C8) let b10="S" gosub wrchr let b10="W" gosub wrchr let b10="R" gosub wrchr let b10="=" gosub wrchr let b10=b2 gosub wrchr let b10="." gosub wrchr let b10=b4 gosub wrchr let b10=b6 gosub wrchr goto main swr10: let b1=200 'Format and display error message at gosub wrins 'centre of line 2 (address $C8) let b10="S" gosub wrchr let b10="W" gosub wrchr let b10="R" gosub wrchr let b10=">" gosub wrchr let b10="1" gosub wrchr let b10="0" gosub wrchr goto main squrtw3: 'square root routine (using Naperian let w2=w3 'successive approximation) let w1=0 let w0=w3/2 opta: let w0=w2/w0 let w0=w3+w0 let w0=w0/2 if w0=w1 then optb 'square root found-return to program let w1=w1+1 'With integer values routine does not always if w0=w1 then optb 'converge to a single value,but can oscillate let w1=w0 'by plus or minus one. let w3=w0 goto opta optb: return squrtw4: 'comments as for squrtw3 let w2=w4 let w1=0 let w0=w4/2 optc: let w0=w2/w0 let w0=w4+w0 let w0=w0/2 if w0=w1 then optd let w1=w1+1 'With integer values routine does not always if w0=w1 then optd 'converge to a single value,but can oscillate let w1=w0 'by plus or minus one. let w4=w0 goto optc optd: return init: 'INITIALISE DISPLAY subroutine let pins=0 'clear all output lines let b3=0 'reset variable b3 pause 800 'wait 200ms for lcd to reset let pins=48 'set to 8 bit operation pulsout 3,4 'send data by pulsing enable line pause 40 'wait 10ms pulsout 3,4 'send data by pulsing enable line pulsout 3,4 'send data by pulsing enable line let pins=32 'set to 4 bit operation pulsout 3,4 'send data by pulsing enable line pulsout 3,4 'send data by pulsing enable line let pins=128 'set to 2 line operation pulsout 3,4 'send data by pulsing enable line let b1=14 'screen on, cursor on operation gosub wrins 'write instruction to lcd return 'return to main program wrchr: 'WRITE CHARACTER subroutine let pins=b10&240 'mask high nibble of b1 into b2 high 2 'make sure RS is high(character mode) pause 4 pulsout 3,4 'send data by pulsing enable line let b3=b10*16 'put low nibble of b1 into b2 let pins=b3&240 'mask the high nibble of b2 high 2 'make sure RS is high pause 4 pulsout 3,4 'send data by pulsing enable line return 'return to main program wrins: 'WRITE INSTRUCTION subroutine let pins=b1&240 'mask high nibble of b1 into b2 low 2 'make sure RS is low(instruction mode) pause 4 pulsout 3,4 'send data by pulsing enable line let b3=b1*16 'put low nibble of b1 into b2 let pins=b3&240 'mask the high nibble of b2 low 2 'make sure RS is low pause 4 pulsout 3,4 'send data by pulsing enable line high 2 'back to character mode pause 4 return 'return to main program leadzero: 'LEADING ZERO SUPPRESSION subroutine if w1<>48 then subend 'return if first digit not zero w1=" " 'replace zero with ASCII space if w2<>48 then subend 'return if second digit not zero w2=" " 'replace zero with ASCII space subend: return