'************************************************************************************ ' LEGAL RESTRICTIONS ON PROGRAM USE '************************************************************************************ 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 June 2005 '************************************************************************************ ' HD44780 LCD SETUP ROUTINE '************************************************************************************ gosub init 'initialise lcd '************************************************************************************ ' MEASURE BATTERY VOLTS '************************************************************************************ battery: readadc 3,b0 '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. w2=b0*100 'adjust the adc count by multiplication and then division so that w2=w2/100 'the display shows the correct voltage - change say division only w3=w2/100 'Derive individual digits for display w4=w2//100 w4=w4/10 w5=w2//10 w3=w3+48 'convert individual digits to ASCII w4=w4+48 w5=w5+48 b1=1 'ASCII characters are formatted,punctuated,and labelled, gosub wrins 'and fed to 16 character X 2 line alphanumeric display- 'display starts at position 1- Display uses industry 'standard Hitachi HD44780 chip. Display format can be 'simply altered to accomodate 2X20,2X40,4X16 displays b0=0 loop10: lookup b0,("BATTERY=",b6,b8,".",b10,"V"),b1 b0=b0+1 gosub wrchr if b0<13 then loop10 pause 6000 'display battery volts for 1.5 seconds '************************************************************************************ ' MEASURE AND DISPLAY FREQUENCY '************************************************************************************ main: poke 80,0 poke 84,0 poke 88,0 poke 103,0 poke 104,0 if pin2=1 then quick count 3,4093,w0 'Frequency counter routine. 5 digit resolution w2=w0/10000 'Max input frequency is 50KHz on digital input 3 (IC pin14)- w3=w0//10000 'NOTE-careful measurement shows 100KHz published is WRONG. w3=w3/1000 w4=w0//1000 'Routines with w1,w2,w3,w4,w6 recover individual digits from w4=w4/100 'count total w0. Clock rate used is 16MHz. Prescaler divider w5=w0//100 'ratio used to feed input 3 is 1024. w5=w5/10 w6=w0//10 w2=w2+48 'Individual digits are converted to ASCII by adding 48 w3=w3+48 w4=w4+48 w5=w5+48 w6=w6+48 poke 92,b4 poke 93,b6 poke 94,b8 poke 95,b10 poke 96,b12 goto rxcalc: 'These two frequency counting routines produce 5 ASCII 'characters which are formatted,punctuated,labelled, 'and fed to 16 character X 2 line alphanumeric display- 'display starts at position 1- Display uses industry 'standard Hitachi HD44780 chip. Display format can be 'simply altered to accomodate 2X20,2X40,4X16 displays '(loop counter b0,data to display b1,do not use b2) 'display frequency "xx.xxxMHz" at start of display line 1 quick: count 3,409,w0 'Frequency counter routine. 4 digit resolution w2=w0/1000 'Comments as for preceding routine w3=w0//1000 w3=w3/100 w4=w0//100 w4=w4/10 w5=w0//10 w2=w2+48 w3=w3+48 w4=w4+48 w5=w5+48 poke 92,b4 poke 93,b6 poke 94,b8 poke 95,b10 poke 96,48 '************************************************************************************ ' CALCULATE RESISTANCE AND REACTANCE '************************************************************************************ rxcalc: '3 voltages are read from test network via ADC 'inputs AN0(ICpin2),AN1(ICpin3)AN2(ICpin4) and 'used to calculate magnitudes of real and 'complex parts of antenna load attached readadc 0,w2 'w2=network input volts (Vin) readadc 1,w3 'w3=voltage proportional to network current (V50) readadc 2,w4 'w4=network output voltage (Vout) rem let w2=240 'presetting variables to test R/X/SWR calculations rem let w3=207 rem let w4=33 poke 98,b6 'save V50 for later if w2<25 then cactus 'no rf oscillator output to drive network if w3<5 then oc 'no network current.Display "open" on line 2 if w4<5 then sc 'no network output volts-display "short" on line 2 goto rxcontd oc: poke 103,10 'set flag to print "OPEN CCT LOAD" later goto freq sc: poke 104,10 'set flag to print "SHORT CCT LOAD" later goto freq rxcontd: let w5=w3+w4 if w5>w2 then square 'impossible output from network w2>w3+w4 if w5=w2 then square '-modify w2 and treat as pure resistance let w2=w5 square: let w5=w4 'save vout for later let w2=w2*w2 'calculate w2 squared-VIN squared let w3=w3*w3 'calculate w3 squared-V50 squared let w4=w4*w4 'calculate w4 squared-VOUT squared let w6=w3+w4 if w220 (approx) if w2<10 and w6>50 then swr2large if w2<20 and w6>100 then swr2large if w2<50 and w6>150 then swr2large if w6>250 then swr2large if w2>500 then swr2large goto printr swr2large: poke 88,10 'set flag to print "SWR>10" 'inputs w2-ADC output for network input volts (0-255max 240max preferred) ' w3-ADC output for volts across 50 ohm series R (network current) ' w4-ADC output for network output volts (volts across load) 'outputs w2-unknown series load resistance in ohms ' w6-unknown reactance in ohms 'voltage across aerial load resistance is in 97 'voltage across 50 ohm series resistor is in 98 'voltage across aerial load reactance is in 99 printr: if w2>500 then r2large let w0=w2 'recover individual digits from w5 (resistance) let w1=w0/100 let w2=w0//100 let w2=w2/10 let w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 poke 81,b2 poke 82,b4 poke 83,b6 goto printx r2large: poke 80,10 'set flag to print "R>500 ohms" printx: if w6>500 then x2large let w0=w6 'recover individual digits from w5 (resistance) let w1=w0/100 let w2=w0//100 let w2=w2/10 let w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 poke 85,b2 poke 86,b4 poke 87,b6 goto calca x2large: poke 84,10 'set flag to print "X>500 ohms" '************************************************************************************ ' SWR CALCULATIONS '************************************************************************************ calca: peek 88,b10 if b10>0 then freq peek 97,b4 peek 98,b5 peek 99,b6 w4=b6*b6 w5=b5+b4 w5=w5*w5 w4=w4+w5 'w4= A squared in swr equation squrt1: let w5=0 'square root routine (using Naperian let w6=w4/2 'successive approximation) calculates opt1: 'A (=w6) in swr equation from w4. let w6=w4/w6+w6 let w6=w6/2 if w5=w6 then calcb let w5=w5+1 if w5=w6 then calcb w5=w6 goto opt1 calcb: poke 100,b12 'save value of A for later if b4>b5 then calcb1 if b4=b5 then calcb1 w4=b6*b6 w5=b5-b4 w5=w5*w5 w4=w4+w5 goto squrt2 calcb1: w4=b6*b6 w5=b4-b5 w5=w5*w5 w4=w4+w5 'w4=B squared in swr equation squrt2: 'square root routine (using Naperian let w5=0 'successive approximation) calculates let w6=w4/2 'B (=w6) in swr equation from w4. opt2: let w6=w4/w6+w6 let w6=w6/2 if w5=w6 then swr let w5=w5+1 if w5=w6 then swr w5=w6 goto opt2 swr: peek 100,b4 w3=b4+b12 w3=w3*100 w4=b4-b12 w3=w3/w4 printswr: if w3>999 then swr2large1 let w0=w3 'recover individual digits from w5 (resistance) let w1=w0/100 let w2=w0//100 let w2=w2/10 let w3=w0//10 let w1=w1+48 'Convert individual digits to ASCII let w2=w2+48 let w3=w3+48 poke 89,b2 poke 90,b4 poke 91,b6 goto freq swr2large1: poke 88,10 goto freq '************************************************************************************ ' MESSAGE ROUTINES '************************************************************************************ cactus: b1=1 gosub wrins b0=0 'display message "RF OSC KAPUT" at start of display line 1 loop7: lookup b0,("RF OSC KAPUT"),b1 b0=b0+1 gosub wrchr if b0<12 then loop7 goto main freq: b1=1 'display frequency "xx.xxxMHz" at start of display line 1 gosub wrins peek 92,b4 peek 93,b5 peek 94,b6 peek 95,b7 peek 96,b8 b0=0 loop0: lookup b0,(b4,b5,".",b6,b7,b8,"MHz"),b1 b0=b0+1 gosub wrchr if b0<9 then loop0 peek 103,b4 peek 104,b5 if b4>0 then open if b5>0 then short goto rwrite open: b1=192 gosub wrins b0=0 'display message "OPEN CCT LOAD" at start of line 2 loop8: lookup b0,("OPEN CCT LOAD"),b1 b0=b0+1 gosub wrchr if b0<13 then loop8 goto main short: b1=192 gosub wrins b0=0 'display message "SHORT CCT LOAD" at start of line 2 loop9: lookup b0,("SHORT CCT LOAD"),b1 b0=b0+1 gosub wrchr if b0<14 then loop9 goto main rwrite: peek 80,b11 if b11>0 then r2 peek 81,b3 peek 82,b4 peek 83,b5 rem if b3>48 then rwrite1 'leading zero suppression rem if b4=48 then rwrite2 rem goto rwrite3 rem rwrite2: rem b4=32 rem rwrite3: rem b3=32 rwrite1: b0=0 'Append message "R=xxx ohms" to end of display line 1 loop1: lookup b0,(" R=",b3,b4,b5,$f4),b1 b0=b0+1 gosub wrchr if b0<7 then loop1 goto xwrite r2: b0=0 'Append message "R>500 ohms" to end of display line 1 loop2: lookup b0,(" R>500",$f4),b1 b0=b0+1 gosub wrchr if b0<7 then loop2 xwrite: b1=192 gosub wrins peek 84,b11 if b11>0 then x2 peek 85,b3 peek 86,b4 peek 87,b5 rem if b3>48 then xwrite1 'leading zero suppression rem if b4=48 then xwrite2 rem goto xwrite3 rem xwrite2: rem b4=32 rem xwrite3: rem b3=32 xwrite1: b0=0 'display message "X=xxx ohms" at start of display line 2 loop3: lookup b0,("X=",b3,b4,b5,$f4),b1 b0=b0+1 gosub wrchr if b0<6 then loop3 goto swrwrite x2: 'display message "X>500 0hms" at start of display line 2 b0=0 loop4: lookup b0,("X>500",$f4),b1 b0=b0+1 gosub wrchr if b0<6 then loop4 swrwrite: peek 88,b4 peek 89,b5 peek 90,b6 peek 91,b7 if b4>0 then swr10 b0=0 'append message "SWR=x.xx" to line 2 loop5: lookup b0,(" SWR=",b5,".",b6,b7),b1 b0=b0+1 gosub wrchr if b0<9 then loop5 goto main swr10: b0=0 'append message "SWR>10" to line 2 loop6: lookup b0,(" SWR>10"),b1 b0=b0+1 gosub wrchr if b0<7 then loop6 goto main '************************************************************************************ ' HD44780 LCD DISPLAY ROUTINES '************************************************************************************ init: 'INITIALISE DISPLAY subroutine pins=0 'clear all output lines b0=0 'reset variable b0 pause 800 'wait 200ms for lcd to reset 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 b1=14 'screen on, cursor on operation gosub wrins 'write instruction to lcd return 'return to main program wrchr: 'WRITE CHARACTER subroutine pins=b1&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 b2=b1*16 'put low nibble of b1 into b2 pins=b2&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 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 b2=b1*16 'put low nibble of b1 into b2 pins=b2&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 '************************************************************************************ ' PROGRAM STRUCTURE DATA '************************************************************************************ 'FLAG AND REGISTER USE '80 flag>0 indicates print "R>500 ohms" '81 three digits of Rload in ohms '82 '83 '84 flag>0 indicates print "X>500 ohms" '85 three digits of X in ohms '86 '87 '88 flag>0 indicates print "SWR>10" '89 three digits of SWR '90 '91 '92 five digits of frequency data '93 '94 '95 '96 '97 volts across load resistance '98 V50 '99 volts across load reactance '100 A in SWR calculation '101 not used now '102 not used now '103 flag>0 indicates no network current (open circuit load) '104 flag>0 indicates no network output voltage (short circuit load 'code generated 27th June 2005 J.S.T. '************************************************************************************ ' SOFTWARE TEST RESULTS '************************************************************************************ ' CALCULATED RESULT PROGRAM RESULT 'TEST w2 w3 w4 R X SWR R X SWR ' '1 240 120 120 50 0 1.00 50 0 1.00 '2 240 207 33 8 0 6.25 7 0 6.27 '3 240 218 22 5 0 10 5 0 9.90 '4 240 222 18 4 0 12.5 4 0 >10 '5 240 240 0 0 0 INF. SHORT CCT LOAD '6 240 40 200 250 0 5.00 250 0 5.00 '7 240 22 218 500 0 10.0 495 0 9.90 '8 240 18 222 600 0 12.0 >500 0 >10 '9 240 0 240 INF. 0 INF. OPEN CCT LOAD '10 240 239 24 0 5 >10 0 5 >10 '11 240 170 170 0 50 >10 0 50 >10 '12 240 47 235 0 250 >10 1 250 >10 '13 240 24 239 0 500 >10 0 497 >10 '14 240 20 239 0 600 >10 2 >500 >10 '15 240 119 122 50 10 1.22 50 10 1.24 '16 240 197 56 10 10 5.19 9 10 5.20 '17 240 78 164 100 30 2.23 100 30 2.22 '18 240 114 126 55 5 1.14 55 0 1.10 '19 240 173 126 10 35 7.51 9 34 7.69 '20 240 195 67 10 14 5.40 9 14 5.54 '21 240 130 184 10 70 14.93 10 70 >10 '22 240 121 176 20 70 7.67 20 69 7.53 '23 240 103 207 10 100 25.2 9 100 >10 '24 240 67 210 50 150 10.9 50 148 >10 '25 240 50 232 10 230 111.0 12 231 >10 '26 240 44 219 100 230 13.0 98 227 >10 '27 240 57 204 100 150 6.83 97 150 6.96 '28 240 36 209 250 150 6.85 243 158 6.96 '29 0 0 0 RF OSCILLATOR KAPUT '30 240 170 172 0 51 INF. 0 50 >10 '31 240 117 117 50 0 1.00 50 0 1.00 'COMMENTS TEST 18 GIVES X=0 AS w2=w3+w4 (NEAREST APPROX INTEGERS) ' TESTS 30 AND 31 ARE FOR IMPOSSIBLE NETWORK OUTPUTS ' i.e. INCORRECTLY ADJUSTED TRIMPOTS '************************************************************************************