; convdds.asm - a program to generate a tone with the PIC 16F84 using a ; D/A converter with a conventional DDS algorithm. ; ; translated from Motorola HC05 arith. synthesizer app. note (AN1222) ; http://ebus.mot-sps.com/mcu/documentation/pdf/an1222.pdf ; ; 12/29/99 Chuck Olson, WB9KZY ; Jackson Harbor Press ; http://jacksonharbor.home.att.net ; jacksonharbor@att.net ; ; ; VVHATDOESITDO? ; ; This program uses an 8 bit DAC along with a 16F84 PIC microcontroller to ; generate a keyed sine wave. The 16F84 uses an RC clock which can be ; varied (with a suitable potentiometer) to allow a variable frequency ; control for the sine wave output. A key or keyer output can be connected ; to pin 1 of the PIC to control the tone output. ; ; This program uses a conventional DDS (Direct Digital Synthesis) phase ; accumulator type of algorithm. This is fully explained in the Motorola ; application note AN1222 referenced above so instead of re-explaining ; how it works, here are a few important characteristics of this ; algorithm. First, the frequency of the tone is easy to control, ; just change the accumulation constant. In this code this isn't ; really an advantage since the PIC RC clock has been made variable. ; Second, the waveform has a certain jitter or "crawl" to it, which is ; easy to see with an osciioscope. This is due to the fact that the ; algorithm does not hit exactly the same points of the sine table in each ; successive cycle of the waveform. ; Third, because of this preceeding "crawl", it's hard to end the waveform ; at an exact point - you can get close, but it takes multiple PIC cycles to ; calculate and compare the present position with the desired ending point. ; In this program, the waveform just ends when key-up is detected - this ; may increase the key-up thump a bit when the notone routine slams the ; waveform back to midscale. ; These disadvantages of the conventional DDS are dealt with in the ; stepdds.asm program which uses the same hardware setup in a different way ; to generate the tone output. ; ;PIC ;pin name function/connection ;--- ---- ----------------------------------------------- ; 1 ra2 key input, pulled up to +5V with a 10K resistor ; 2 ra3 no connect ; 3 ra4 no connect ; 4 MCLR pulled up to +5V with a 10K resistor ; 5 VSS Ground ; 6 rb0 connected to 20k dac resistor ; 7 rb1 connected to 20k dac resistor ; 8 rb2 connected to 20k dac resistor ; 9 rb3 connected to 20k dac resistor ; 10 rb4 connected to 20k dac resistor ; 11 rb5 connected to 20k dac resistor ; 12 rb6 connected to 20k dac resistor ; 13 rb7 connected to 20k dac resistor ; 14 VDD +5V ; 15 osc2 no connect ; 16 osc1 connected to the RC timing circuit, R = 10k pot, C = 22 pf ; 17 ra0 no connect ; 18 ra1 no connect LIST P=16F84, R=DEC INCLUDE "p16F84.inc" __FUSES _PWRTE_OFF & _CP_OFF & _WDT_OFF & _RC_OSC ;constants ; bit definitions ; memory locations frack equ H'0C' ;fractional accumulate value intk equ H'0D' ;integer accumulate value accuml equ H'0F' ;least signif byte of phase accumulator accumh equ H'10' ;most signif byte of phase accumulator ORG 0x000 start goto init ;reset vector ORG 0x004 noint goto init ;interrupt vector ; init - the initialization power up entry point of the program init movlw b'00000000' ; all outputs on PORTB tris PORTB ; set the tri-state register movlw b'00000100' ; RA2 is an input (key) tris PORTA ; set the tri-state register movlw b'00000000' ; no option bits are relevant option ; set the option register movlw d'3' ;const= 256 * 700 * .000018 = 3.226 movwf intk ;3.226 => 3 : (.226 * 256) = 58 (700 hz @ 18 us) movlw d'58' movwf frack ;just load a 1 (for page 2 higher address byte) and put in PCLATH ; since all the table entries are now in page 2. movlw 1 ;1 9 load up the high order bits of 2nd page movwf PCLATH ;1 10 load the high address into the latch btfsc PORTA,2 ;2 2 see if the sw1 switch is pressed goto notone ;no, goto the notone routine notone movlw 128 ;load up mid scale for the DAC (an "AC" zero) movwf PORTB ;apply the mid scale value to the DAC clrf accuml ;initialize the registers clrf accumh ; tabp3 is the main tone loop ; The first number after the semicolon indicates the number of PIC cycles ; that are used to execute the instruction - the second number after the ; semicolon indicates the cumulative total of PIC cycles that have elapsed ; since the start of the routine. tabp3 btfsc PORTA,2 ;2 2 see if the sw1 switch is pressed goto notone ;2 2 no, loop without tone p3ml2 movf frack,0 ;1 3 yes, get current LSB value ; of the phase accum. addwf accuml,1 ;1 4 The fractional ; constant is added to ; the LSB of the phase ; accumulator. btfsc STATUS,0 ;2 6 check the carry incf accumh,1 ;1 6 it was set, increment the hi-order byte ;it wasn't set, keep adding! movf intk,0 ;1 7 Get current MSB value ; of the phase accum. addwf accumh,1 ;1 8 The integer constant ; is added to the MSB of ; the phase accum. ; Notice the addition ; with carry. movf accumh,0 ;1 9 ACCA contains the ; integer portion of the ; 16-bit phase value. ; We need to move it into ; the w register to do a table ; look-up. call sinetbl ;6 15 Get the sine value ; the call is 2, addwf is 2, retlw is 2 ;not sure why addwf is 2 in the table, but ; it simulates and works that way - strange. movwf PORTB ;1 16 Send it to the DAC goto tabp3 ;2 18 Branch to top of the routine org 0x0FF ; sinetbl - a table of sine wave values - 256 words in length ; the values were generated with the Qbasic program: sine9.bas ; ; Question: Why does this routine start at address FF? ; Answer: Because the table is 256 entries long - the only ; easy/quick way to access the table is to have all the entries on ; the same 256 word memory page. The register PCLATH is preset ; during initialization to always point to page 1 (address 100h) so ; that the result of the addwf to PCL always points to page 1. ; Note that the table could have been trimmed in size by ; using only 1/4 of the waveform and then performing a little ; simple math to recreate the other 3/4 of the table depending on ; where the routine is within a given waveform cycle. This idea ; wasn't used to save cycle time during the routine. ; The fewer cycles taken during one pass through the routine, the ; more sample points during each tone cycle - it sounds better and ; is easier to filter with oversampling. sinetbl addwf PCL,1 ;compute the jump value retlw 128 ; 0 0 retlw 131 ; 1 2.454121E-02 retlw 134 ; 2 4.906764E-02 retlw 137 ; 3 7.356451E-02 retlw 140 ; 4 9.801706E-02 retlw 143 ; 5 .1224106 retlw 146 ; 6 .1467304 retlw 149 ; 7 .1709618 retlw 152 ; 8 .1950902 retlw 155 ; 9 .2191011 retlw 158 ; 10 .24298 retlw 162 ; 11 .2667125 retlw 165 ; 12 .2902845 retlw 167 ; 13 .3136815 retlw 170 ; 14 .3368896 retlw 173 ; 15 .3598948 retlw 176 ; 16 .3826831 retlw 179 ; 17 .405241 retlw 182 ; 18 .4275548 retlw 185 ; 19 .449611 retlw 188 ; 20 .4713964 retlw 190 ; 21 .4928978 retlw 193 ; 22 .5141024 retlw 196 ; 23 .5349972 retlw 198 ; 24 .5555698 retlw 201 ; 25 .5758078 retlw 203 ; 26 .5956989 retlw 206 ; 27 .6152312 retlw 208 ; 28 .6343929 retlw 211 ; 29 .6531724 retlw 213 ; 30 .6715585 retlw 215 ; 31 .6895401 retlw 218 ; 32 .7071064 retlw 220 ; 33 .7242466 retlw 222 ; 34 .7409506 retlw 224 ; 35 .7572084 retlw 226 ; 36 .77301 retlw 228 ; 37 .788346 retlw 230 ; 38 .8032071 retlw 232 ; 39 .8175844 retlw 234 ; 40 .8314692 retlw 235 ; 41 .8448531 retlw 237 ; 42 .8577282 retlw 238 ; 43 .8700866 retlw 240 ; 44 .8819209 retlw 241 ; 45 .8932239 retlw 243 ; 46 .9039889 retlw 244 ; 47 .9142094 retlw 245 ; 48 .9238791 retlw 246 ; 49 .9329925 retlw 248 ; 50 .9415438 retlw 249 ; 51 .9495279 retlw 250 ; 52 .9569401 retlw 250 ; 53 .9637758 retlw 251 ; 54 .970031 retlw 252 ; 55 .9757019 retlw 253 ; 56 .9807851 retlw 253 ; 57 .9852775 retlw 254 ; 58 .9891763 retlw 254 ; 59 .9924794 retlw 254 ; 60 .9951846 retlw 255 ; 61 .9972904 retlw 255 ; 62 .9987954 retlw 255 ; 63 .9996988 retlw 255 ; 64 1 retlw 255 ; 65 .9996989 retlw 255 ; 66 .9987955 retlw 255 ; 67 .9972906 retlw 254 ; 68 .9951848 retlw 254 ; 69 .9924797 retlw 254 ; 70 .9891767 retlw 253 ; 71 .9852779 retlw 253 ; 72 .9807855 retlw 252 ; 73 .9757025 retlw 251 ; 74 .9700316 retlw 250 ; 75 .9637765 retlw 250 ; 76 .9569408 retlw 249 ; 77 .9495286 retlw 248 ; 78 .9415446 retlw 246 ; 79 .9329934 retlw 245 ; 80 .9238802 retlw 244 ; 81 .9142104 retlw 243 ; 82 .90399 retlw 241 ; 83 .893225 retlw 240 ; 84 .8819221 retlw 238 ; 85 .8700878 retlw 237 ; 86 .8577295 retlw 235 ; 87 .8448545 retlw 234 ; 88 .8314706 retlw 232 ; 89 .8175858 retlw 230 ; 90 .8032086 retlw 228 ; 91 .7883475 retlw 226 ; 92 .7730116 retlw 224 ; 93 .7572101 retlw 222 ; 94 .7409524 retlw 220 ; 95 .7242484 retlw 218 ; 96 .7071081 retlw 215 ; 97 .6895419 retlw 213 ; 98 .6715604 retlw 211 ; 99 .6531743 retlw 208 ; 100 .6343948 retlw 206 ; 101 .6152332 retlw 203 ; 102 .5957009 retlw 201 ; 103 .5758098 retlw 198 ; 104 .555572 retlw 196 ; 105 .5349994 retlw 193 ; 106 .5141045 retlw 190 ; 107 .4929 retlw 188 ; 108 .4713986 retlw 185 ; 109 .4496132 retlw 182 ; 110 .4275571 retlw 179 ; 111 .4052433 retlw 176 ; 112 .3826855 retlw 173 ; 113 .3598971 retlw 170 ; 114 .336892 retlw 167 ; 115 .3136839 retlw 165 ; 116 .2902869 retlw 162 ; 117 .266715 retlw 158 ; 118 .2429824 retlw 155 ; 119 .2191035 retlw 152 ; 120 .1950926 retlw 149 ; 121 .1709643 retlw 146 ; 122 .1467329 retlw 143 ; 123 .1224131 retlw 140 ; 124 9.801959E-02 retlw 137 ; 125 7.356703E-02 retlw 134 ; 126 4.907017E-02 retlw 131 ; 127 2.454374E-02 retlw 128 ; 128 2.535182E-06 retlw 124 ; 129 -2.453867E-02 retlw 121 ; 130 -.0490651 retlw 118 ; 131 -7.356197E-02 retlw 115 ; 132 -9.801454E-02 retlw 112 ; 133 -.1224081 retlw 109 ; 134 -.1467278 retlw 106 ; 135 -.1709592 retlw 103 ; 136 -.1950877 retlw 100 ; 137 -.2190986 retlw 97 ; 138 -.2429775 retlw 93 ; 139 -.2667101 retlw 90 ; 140 -.290282 retlw 88 ; 141 -.3136791 retlw 85 ; 142 -.3368872 retlw 82 ; 143 -.3598924 retlw 79 ; 144 -.3826808 retlw 76 ; 145 -.4052387 retlw 73 ; 146 -.4275525 retlw 70 ; 147 -.4496087 retlw 67 ; 148 -.4713942 retlw 65 ; 149 -.4928956 retlw 62 ; 150 -.5141002 retlw 59 ; 151 -.5349951 retlw 57 ; 152 -.5555677 retlw 54 ; 153 -.5758057 retlw 52 ; 154 -.5956969 retlw 49 ; 155 -.6152292 retlw 47 ; 156 -.6343909 retlw 44 ; 157 -.6531705 retlw 42 ; 158 -.6715567 retlw 40 ; 159 -.6895382 retlw 37 ; 160 -.7071046 retlw 35 ; 161 -.7242449 retlw 33 ; 162 -.740949 retlw 31 ; 163 -.7572067 retlw 29 ; 164 -.7730084 retlw 27 ; 165 -.7883444 retlw 25 ; 166 -.8032055 retlw 23 ; 167 -.8175829 retlw 21 ; 168 -.8314677 retlw 20 ; 169 -.8448518 retlw 18 ; 170 -.8577269 retlw 17 ; 171 -.8700853 retlw 15 ; 172 -.8819197 retlw 14 ; 173 -.8932227 retlw 12 ; 174 -.9039878 retlw 11 ; 175 -.9142084 retlw 10 ; 176 -.9238782 retlw 9 ; 177 -.9329916 retlw 7 ; 178 -.9415429 retlw 6 ; 179 -.9495271 retlw 5 ; 180 -.9569393 retlw 5 ; 181 -.9637751 retlw 4 ; 182 -.9700304 retlw 3 ; 183 -.9757013 retlw 2 ; 184 -.9807846 retlw 2 ; 185 -.985277 retlw 1 ; 186 -.989176 retlw 1 ; 187 -.9924791 retlw 1 ; 188 -.9951844 retlw 0 ; 189 -.9972902 retlw 0 ; 190 -.9987953 retlw 0 ; 191 -.9996987 retlw 0 ; 192 -1 retlw 0 ; 193 -.9996989 retlw 0 ; 194 -.9987956 retlw 0 ; 195 -.9972907 retlw 1 ; 196 -.9951851 retlw 1 ; 197 -.99248 retlw 1 ; 198 -.9891771 retlw 2 ; 199 -.9852783 retlw 2 ; 200 -.980786 retlw 3 ; 201 -.975703 retlw 4 ; 202 -.9700322 retlw 5 ; 203 -.9637771 retlw 5 ; 204 -.9569415 retlw 6 ; 205 -.9495295 retlw 7 ; 206 -.9415454 retlw 9 ; 207 -.9329942 retlw 10 ; 208 -.9238811 retlw 11 ; 209 -.9142115 retlw 12 ; 210 -.903991 retlw 14 ; 211 -.8932262 retlw 15 ; 212 -.8819233 retlw 17 ; 213 -.8700891 retlw 18 ; 214 -.8577308 retlw 20 ; 215 -.8448558 retlw 21 ; 216 -.831472 retlw 23 ; 217 -.8175873 retlw 25 ; 218 -.8032101 retlw 27 ; 219 -.7883491 retlw 29 ; 220 -.7730132 retlw 31 ; 221 -.7572117 retlw 33 ; 222 -.7409541 retlw 35 ; 223 -.7242501 retlw 37 ; 224 -.7071099 retlw 40 ; 225 -.6895438 retlw 42 ; 226 -.6715623 retlw 44 ; 227 -.6531762 retlw 47 ; 228 -.6343968 retlw 49 ; 229 -.6152351 retlw 52 ; 230 -.5957029 retlw 54 ; 231 -.5758119 retlw 57 ; 232 -.5555741 retlw 59 ; 233 -.5350015 retlw 62 ; 234 -.5141067 retlw 65 ; 235 -.4929022 retlw 67 ; 236 -.4714009 retlw 70 ; 237 -.4496155 retlw 73 ; 238 -.4275593 retlw 76 ; 239 -.4052456 retlw 79 ; 240 -.3826878 retlw 82 ; 241 -.3598995 retlw 85 ; 242 -.3368944 retlw 88 ; 243 -.3136863 retlw 90 ; 244 -.2902893 retlw 93 ; 245 -.2667174 retlw 97 ; 246 -.2429849 retlw 100 ; 247 -.219106 retlw 103 ; 248 -.1950951 retlw 106 ; 249 -.1709667 retlw 109 ; 250 -.1467354 retlw 112 ; 251 -.1224156 retlw 115 ; 252 -9.802211E-02 retlw 118 ; 253 -7.356956E-02 retlw 121 ; 254 -.0490727 retlw 124 ; 255 -2.454628E-02 END