Smart Port | Wave POD |
;************************************************************************* ; Arbitrary WaveForm Generator - High Precision ;************************************************************************* ; ; DESCRIPTION 32 step arbitrary 8 bit pattern generator ; with sub-hertz period control ; ; This Module uses the values in WAV_16..47 to set output values in PB0..7. ; The position index into this table is the top 5 bits of a running 29 bit ; counter (Phase Accumulator) with a 32 bit Phase increment. A 8uS loop per ; step (125KHz step freq) results in a frequency control of about 0.01 Hz ; REGISTER MAP ; WAV_8,11 29 bit phase index (int.frac 5.24) ; WAV_12,15 32 bit phase increment (int.frac 8.24) ; VMR_16 Output value for step 0 ; VMR_... ; VMR_47 Output value for step 31 ; OPERATION ; ; Top 5 bits of phase accumulator points into 32 byte table and the ; lower 24 bits of the phase accumulator are fractional phase ; Phase increment is full 32 bit - allowing phase steps greater than ; a single table location. If the phase increment is greater than 32 ; it is also possible to step backwards through the table. ; ; While the average frequency of the waveform generated is accurate to < 0.01Hz, ; the sample rate of the generator is 125KHz, which means there may be ; jitter on the waveform of up to 8uS. If this Waveloop is used to generate ; reference signals, a low pass filter after the DAC is recommended. ; ; This WaveLoop operates until the PIC is reset ; HOW TO - change the Wave shape ; ; calculate 32 points in your waveform, remembering that 00 corresponds to ; the most negative output of the DAC and ff the most positive output. ; Alter the code in "init_wav" to your calculated values. In the case ; where you wish to use this loop to generate a logic sequence, make a ; Logic State table of 32 values and edit these into the code. ; The 32 values will be repeated indefinitely, at the rate determined by the ; Phase Increment register. ; HOW TO - set the loop frequency ; ; The control registers for this WaveLoop are the Phase accumulator and ; the Phase Increment register. Both of these registers are 32 bits (4 bytes) ; in the form of integer.fraction binary numbers. This means that the msb (most ; signifigant byte) represents a integer number of steps through the 32 byte ; wave table, and the other 3 bytes represent a 24 bit binary fraction of a step. ; The Phase accumulator is usually set at 0.000 - as the initial value is of ; no interest. For a logic sequencer this may not be true and it should be ; set accordingly. ; The Phase Increment parameter represents the exact number of steps (a.bcd) ; that the phase accumulator is advanced each loop (8uS). The value to advance ; 1 step per loop is 1.000. This will result in all 32 table entries being output ; in 32 x 8uS (256uS or F=3.90625KHz) ; In general, this means that the frequency of the waveform will be calculated ; ; F = 3906.25 x Phase_Inc Hz ; ; OR ; ; Phase_Inc = F / 3906.25 ; ; To make a 100Hz waveform, we would calculate the Phase Increment as:- ; ; Phase_Inc = 100/3906.25 ; = 0.0256 ; ; Convert this to a binary number - 16,777,216 x 0.0256 = 429497 ; Which is 0.068db9 - the binary (int.frac) corresponding to 0.0256 ; What will happen here is that about every 39 loops, the Phase accumulator ; will advance by one step. ; ; To make a 1000Hz waveform, we would calculate the Phase Increment as:- ; ; Phase_Inc = 1000/3906.25 ; = 0.256 ; ; Convert this to a binary number - 16,777,216 x 0.0256 = 4,294,967 ; Which is 00.418937 - the binary (int.frac) corresponding to 0.256 ; What will happen here is that about every 4 loops, the Phase accumulator ; will advance by one step. ; HOW TO - make a very slow logic sequencer ; ; If the Phase Increment registers are set to 00.000001 (hex), this will mean that ; each step through the 32 entry table will require 2^24 (16,777,216) 8uS loops ; to execute. This is 134.2 seconds - quite a long time. At this rate it will ; take just over an hour to step through all 32 table entries. ; APPLICATIONS ; ; counter, pattern generator ; with DAC arbitrary waveform generator ; 32 step oscillator, 8 uS step ; frequency synth waveloop_15 ; initialize the 32 registers with ; the wave table (sine wave) ; put in the values of a full scale sine wave init_wav movlw 128 ; WAV-0 movwf WAV_16 ; put it in RAM table movlw 153 ; WAV-1 movwf WAV_17 ; put it in RAM table movlw 177 ; WAV-2 movwf WAV_18 ; put it in RAM table movlw 199 ; WAV-3 movwf WAV_19 ; put it in RAM table movlw 219 ; WAV-4 movwf WAV_20 ; put it in RAM table movlw 234 ; WAV-5 movwf WAV_21 ; put it in RAM table movlw 246 ; WAV-6 movwf WAV_22 ; put it in RAM table movlw 253 ; WAV-7 movwf WAV_23 ; put it in RAM table movlw 255 ; WAV-8 movwf WAV_24 ; put it in RAM table movlw 253 ; WAV-9 movwf WAV_25 ; put it in RAM table movlw 246 ; WAV-10 movwf WAV_26 ; put it in RAM table movlw 234 ; WAV-11 movwf WAV_27 ; put it in RAM table movlw 219 ; WAV-12 movwf WAV_28 ; put it in RAM table movlw 199 ; WAV-13 movwf WAV_29 ; put it in RAM table movlw 177 ; WAV-14 movwf WAV_30 ; put it in RAM table movlw 153 ; WAV-15 movwf WAV_31 ; put it in RAM table movlw 128 ; WAV-16 movwf WAV_32 ; put it in RAM table movlw 103 ; WAV-17 movwf WAV_33 ; put it in RAM table movlw 79 ; WAV-18 movwf WAV_34 ; put it in RAM table movlw 57 ; WAV-19 movwf WAV_35 ; put it in RAM table movlw 37 ; WAV-20 movwf WAV_36 ; put it in RAM table movlw 22 ; WAV-21 movwf WAV_37 ; put it in RAM table movlw 10 ; WAV-22 movwf WAV_38 ; put it in RAM table movlw 3 ; WAV-23 movwf WAV_39 ; put it in RAM table movlw 1 ; WAV-24 movwf WAV_40 ; put it in RAM table movlw 3 ; WAV-25 movwf WAV_41 ; put it in RAM table movlw 10 ; WAV-26 movwf WAV_42 ; put it in RAM table movlw 22 ; WAV-27 movwf WAV_43 ; put it in RAM table movlw 37 ; WAV-28 movwf WAV_44 ; put it in RAM table movlw 57 ; WAV-29 movwf WAV_45 ; put it in RAM table movlw 79 ; WAV-30 movwf WAV_46 ; put it in RAM table movlw 103 ; WAV-31 movwf WAV_47 ; put it in RAM table ; initialize the phase accumulator and the phase offset movlw 0x00 ; Phase Accumulator msb movwf WAV_11 ; put in register movlw 0x00 ; Phase Accumulator movwf WAV_10 ; put in register movlw 0x00 ; Phase Accumulator movwf WAV_9 ; put in register movlw 0x00 ; Phase Accumulator lsb movwf WAV_8 ; put in register ; put in here the example values to give a 1KHz wave movlw 0x00 ; Phase increment msb movwf WAV_15 ; put in register movlw 0x41 ; Phase increment movwf WAV_14 ; put in register movlw 0x89 ; Phase increment movwf WAV_13 ; put in register movlw 0x37 ; Phase increment lsb movwf WAV_12 ; put in register ; all the initial values of the registers are now set. ; this is the main loop which takes 8uS to complete. l_15_1 movlw 0x1f ; mask for 5 bits of phase andwf WAV_11,W ; get the 5 msbs into W addlw WAV_16 ; offset from VMR-16 movwf FSR ; put in reg pointer movf INDF,W ; put the reg in W movwf PORTB ; that is it! ; next step is to increment the phase ; 32 bit addition for phase + increment -> phase movf WAV_12,W ; get the lsb of increment addwf WAV_8,F ; add it to the lsb of phase clrz ; explicitly clear Z bit skpnc ; did we get a carry? setz ; yes - mirror it in Z bit ; ripple it up the 3 higher bytes skpnz ; incf WAV_9,F ; skpnz ; incf WAV_10,F ; skpnz ; incf WAV_11,F ; movf WAV_13,W ; get next byte addwf WAV_9,F ; add to phase clrz ; explicitly clear Z bit skpnc ; carry? setz ; yes - mirror it in Z bit ; ripple it up 2 bytes skpnz ; incf WAV_10,F ; skpnz ; incf WAV_11,F ; movf WAV_14,W ; get the next byte addwf WAV_10,F ; add to phase clrz ; explicitly clear Z bit skpnc ; carry? setz ; yes - mirror it in Z bit ; ripple it up last byte skpnz ; incf WAV_11,F ; movf WAV_15,W ; get the MSB addwf WAV_11,F ; and put in phase ; we don't care about C nop nop nop goto l_15_1 ; loop again ; loop is 40 instructions (8uS) |
Copyright © 2023 BitScope Designs