Sine table code in c

Status
Not open for further replies.
Speaking of devices with built-in D2A, some of the 16F1700 series devices include not only an 8-bit or 10-bit D2A but an Op-Amp that can be driven by the D2A.

While I haven't tried it yet, I think these devices might be a good choice for a nice DDS Signal Generator Design.
 
Speaking of DDS Signal Generators, I found some unfinished experimental code from 2011 for a PWM DDS Signal Generator. It looks like I was using a 16F device with a 20-cycle PWM period and DDS loop with a 32-MHz clock for a 400-kHz PWM and DDS loop frequency to produce 80 PWM steps. It also looks like I used a 10-bit 256 step sine table with PWM duty cycle values stored as words which, when read, would be written directly to the CCPR1L and CCP1CON registers. I suspect I was looking at different ways to implement a fast DDS loop. Here's a couple excerpts;

Code:
;******************************************************************
;  main.loop                                                      *
;******************************************************************
        banksel EEADRL          ; bank 3                          |03
        movlw   high(sine)      ; sine table address high         |03
        movwf   EEADRH          ;                                 |03
        clrf    EEADRL          ; accum+3                         |03
        clrf    accum+1         ;                                 |03
        clrf    accum+0         ;                                 |03
        bcf     EECON1,CFGS     ; CFGS = 0 (Flash)                |03
        bsf     EECON1,EEPGD    ; EEPGD = 1 (Flash)               |03
        movlw   high(CCPR1L)    ; hi(0x291)                       |03
        movwf   FSR0H           ;                                 |03
        movlw   low(CCPR1L)     ; lo(0x291)                       |03
        movwf   FSR0L           ;                                 |03
        movlw   high(CCP1CON)   ; hi(0x293)                       |03
        movwf   FSR1H           ;                                 |03
        movlw   low(CCP1CON)    ; lo(0x293)                       |03
        movwf   FSR1L           ;                                 |03
;
;  20 cycle (2.5 us) 32-bit 400-kHz DDS loop (32 MHz clock)
;
ddsloop
        movf    phase+0,W       ;                                 |03
        addwf   accum+0,F       ;                                 |03
        movf    phase+1,W       ;                                 |03
        addwfc  accum+1,F       ;                                 |03
        movf    phase+2,W       ;                                 |03 <-
        addwfc  accum+2,F       ;                                 |03 <-
        movf    phase+3,W       ;                                 |03
        addwfc  EEADRL,F        ; accum+3 (sine array index)      |03
        bsf     EECON1,RD       ; read into EEDATH & EEDATL       |03
        nop                     ; required nop                    |03
        nop                     ; required nop                    |03
        movf    EEDATH,W        ; the b7-b2 duty cycle bits       |03
        movwf   INDF0           ; CCPR1L = EEDATH                 |03
        movf    EEDATL,W        ; the b1-b0 duty cycle bits       |03
        movwf   INDF1           ; CCP1CON = EEDATL                |03
        nop                     ;                                 |03
        nop                     ;                                 |03
        btfss   INTCON,IOCIF    ; switch IOC? yes, skip, else     |03
        bra     ddsloop         ;                                 |03
;******************************************************************
Code:
;******************************************************************
;  duty cycle bits are placed in each 14 bit array element using
;  pattern '--765432 xx10xxxx' with CCP1CON register bits placed
;  in the 'x' bit positions.  This allows writing the CCPR1L and
;  the CCP1CON registers directly from EEDATH and EEDATL.
;
        radix   dec
sinprep macro   dcy
        dw     (dcy>>2)*256 | (((dcy%4)<<4)|12)
        endm
    
        org     0x700
sine
        sinprep(039)            ; 000  +0
        sinprep(040)            ; 001  +0.24541229e-1
        sinprep(041)            ; 002  +0.49067674e-1
        sinprep(042)            ; 003  +0.73564564e-1
        sinprep(043)            ; 004  +0.9801714e-1
        sinprep(044)            ; 005  +0.12241068
        sinprep(045)            ; 006  +0.14673047
        sinprep(046)            ; 007  +0.17096189
        sinprep(047)            ; 008  +0.19509032
        sinprep(048)            ; 009  +0.21910124
        sinprep(049)            ; 010  +0.24298018
        sinprep(050)            ; 011  +0.26671276
        sinprep(050)            ; 012  +0.29028468
        sinprep(051)            ; 013  +0.31368174
        sinprep(052)            ; 014  +0.33688985
        sinprep(053)            ; 015  +0.35989504
        sinprep(054)            ; 016  +0.38268343
        sinprep(055)            ; 017  +0.40524131
        sinprep(056)            ; 018  +0.42755509
        sinprep(057)            ; 019  +0.44961133
        sinprep(058)            ; 020  +0.47139674
        sinprep(058)            ; 021  +0.49289819
        sinprep(059)            ; 022  +0.51410274
        sinprep(060)            ; 023  +0.53499762
        sinprep(061)            ; 024  +0.55557023
        sinprep(062)            ; 025  +0.57580819
        sinprep(063)            ; 026  +0.5956993
        sinprep(063)            ; 027  +0.61523159
        sinprep(064)            ; 028  +0.63439328
        sinprep(065)            ; 029  +0.65317284
        sinprep(066)            ; 030  +0.67155895
        sinprep(066)            ; 031  +0.68954054
        sinprep(067)            ; 032  +0.70710678
        sinprep(068)            ; 033  +0.72424708
        sinprep(068)            ; 034  +0.74095113
        sinprep(069)            ; 035  +0.75720885
        sinprep(070)            ; 036  +0.77301045
        sinprep(070)            ; 037  +0.78834643
        sinprep(071)            ; 038  +0.80320753
        sinprep(071)            ; 039  +0.81758481
        sinprep(072)            ; 040  +0.83146961
        sinprep(072)            ; 041  +0.84485357
        sinprep(073)            ; 042  +0.85772861
        sinprep(073)            ; 043  +0.87008699
        sinprep(074)            ; 044  +0.88192126
        sinprep(074)            ; 045  +0.8932243
        sinprep(075)            ; 046  +0.90398929
        sinprep(075)            ; 047  +0.91420976
        sinprep(075)            ; 048  +0.92387953
        sinprep(076)            ; 049  +0.9329928
        sinprep(076)            ; 050  +0.94154407
        sinprep(077)            ; 051  +0.94952818
        sinprep(077)            ; 052  +0.95694034
        sinprep(077)            ; 053  +0.96377607
        sinprep(077)            ; 054  +0.97003125
        sinprep(078)            ; 055  +0.97570213
        sinprep(078)            ; 056  +0.98078528
        sinprep(078)            ; 057  +0.98527764
        sinprep(078)            ; 058  +0.98917651
        sinprep(078)            ; 059  +0.99247953
        sinprep(078)            ; 060  +0.99518473
        sinprep(078)            ; 061  +0.99729046
        sinprep(078)            ; 062  +0.99879546
        sinprep(078)            ; 063  +0.99969882
        sinprep(079)            ; 064  +1
        sinprep(078)            ; 065  +0.99969882
        sinprep(078)            ; 066  +0.99879546
        sinprep(078)            ; 067  +0.99729046
        sinprep(078)            ; 068  +0.99518473
        sinprep(078)            ; 069  +0.99247953
        sinprep(078)            ; 070  +0.98917651
        sinprep(078)            ; 071  +0.98527764
        sinprep(078)            ; 072  +0.98078528
        sinprep(078)            ; 073  +0.97570213
        sinprep(077)            ; 074  +0.97003125
        sinprep(077)            ; 075  +0.96377607
        sinprep(077)            ; 076  +0.95694034
        sinprep(077)            ; 077  +0.94952818
        sinprep(076)            ; 078  +0.94154407
        sinprep(076)            ; 079  +0.9329928
        sinprep(075)            ; 080  +0.92387953
        sinprep(075)            ; 081  +0.91420976
        sinprep(075)            ; 082  +0.90398929
        sinprep(074)            ; 083  +0.8932243
        sinprep(074)            ; 084  +0.88192126
        sinprep(073)            ; 085  +0.87008699
        sinprep(073)            ; 086  +0.85772861
        sinprep(072)            ; 087  +0.84485357
        sinprep(072)            ; 088  +0.83146961
        sinprep(071)            ; 089  +0.81758481
        sinprep(071)            ; 090  +0.80320753
        sinprep(070)            ; 091  +0.78834643
        sinprep(070)            ; 092  +0.77301045
        sinprep(069)            ; 093  +0.75720885
        sinprep(068)            ; 094  +0.74095113
        sinprep(068)            ; 095  +0.72424708
        sinprep(067)            ; 096  +0.70710678
        sinprep(066)            ; 097  +0.68954054
        sinprep(066)            ; 098  +0.67155895
        sinprep(065)            ; 099  +0.65317284
        sinprep(064)            ; 100  +0.63439328
        sinprep(063)            ; 101  +0.61523159
        sinprep(063)            ; 102  +0.5956993
        sinprep(062)            ; 103  +0.57580819
        sinprep(061)            ; 104  +0.55557023
        sinprep(060)            ; 105  +0.53499762
        sinprep(059)            ; 106  +0.51410274
        sinprep(058)            ; 107  +0.49289819
        sinprep(058)            ; 108  +0.47139674
        sinprep(057)            ; 109  +0.44961133
        sinprep(056)            ; 110  +0.42755509
        sinprep(055)            ; 111  +0.40524131
        sinprep(054)            ; 112  +0.38268343
        sinprep(053)            ; 113  +0.35989504
        sinprep(052)            ; 114  +0.33688985
        sinprep(051)            ; 115  +0.31368174
        sinprep(050)            ; 116  +0.29028468
        sinprep(050)            ; 117  +0.26671276
        sinprep(049)            ; 118  +0.24298018
        sinprep(048)            ; 119  +0.21910124
        sinprep(047)            ; 120  +0.19509032
        sinprep(046)            ; 121  +0.17096189
        sinprep(045)            ; 122  +0.14673047
        sinprep(044)            ; 123  +0.12241067
        sinprep(043)            ; 124  +0.9801714e-1
        sinprep(042)            ; 125  +0.73564563e-1
        sinprep(041)            ; 126  +0.49067674e-1
        sinprep(040)            ; 127  +0.24541228e-1
        sinprep(039)            ; 128  -0.41020686e-9
        sinprep(038)            ; 129  -0.24541229e-1
        sinprep(037)            ; 130  -0.49067675e-1
        sinprep(036)            ; 131  -0.73564564e-1
        sinprep(035)            ; 132  -0.98017141e-1
        sinprep(034)            ; 133  -0.12241068
        sinprep(033)            ; 134  -0.14673047
        sinprep(032)            ; 135  -0.17096189
        sinprep(031)            ; 136  -0.19509032
        sinprep(030)            ; 137  -0.21910124
        sinprep(029)            ; 138  -0.24298018
        sinprep(028)            ; 139  -0.26671276
        sinprep(028)            ; 140  -0.29028468
        sinprep(027)            ; 141  -0.31368174
        sinprep(026)            ; 142  -0.33688985
        sinprep(025)            ; 143  -0.35989504
        sinprep(024)            ; 144  -0.38268343
        sinprep(023)            ; 145  -0.40524131
        sinprep(022)            ; 146  -0.42755509
        sinprep(021)            ; 147  -0.44961133
        sinprep(020)            ; 148  -0.47139674
        sinprep(020)            ; 149  -0.49289819
        sinprep(019)            ; 150  -0.51410274
        sinprep(018)            ; 151  -0.53499762
        sinprep(017)            ; 152  -0.55557023
        sinprep(016)            ; 153  -0.57580819
        sinprep(015)            ; 154  -0.5956993
        sinprep(015)            ; 155  -0.61523159
        sinprep(014)            ; 156  -0.63439328
        sinprep(013)            ; 157  -0.65317284
        sinprep(012)            ; 158  -0.67155896
        sinprep(012)            ; 159  -0.68954055
        sinprep(011)            ; 160  -0.70710678
        sinprep(010)            ; 161  -0.72424708
        sinprep(010)            ; 162  -0.74095113
        sinprep(009)            ; 163  -0.75720885
        sinprep(008)            ; 164  -0.77301045
        sinprep(008)            ; 165  -0.78834643
        sinprep(007)            ; 166  -0.80320753
        sinprep(007)            ; 167  -0.81758481
        sinprep(006)            ; 168  -0.83146961
        sinprep(006)            ; 169  -0.84485357
        sinprep(005)            ; 170  -0.85772861
        sinprep(005)            ; 171  -0.87008699
        sinprep(004)            ; 172  -0.88192126
        sinprep(004)            ; 173  -0.8932243
        sinprep(003)            ; 174  -0.90398929
        sinprep(003)            ; 175  -0.91420976
        sinprep(003)            ; 176  -0.92387953
        sinprep(002)            ; 177  -0.9329928
        sinprep(002)            ; 178  -0.94154407
        sinprep(001)            ; 179  -0.94952818
        sinprep(001)            ; 180  -0.95694034
        sinprep(001)            ; 181  -0.96377607
        sinprep(001)            ; 182  -0.97003125
        sinprep(000)            ; 183  -0.97570213
        sinprep(000)            ; 184  -0.98078528
        sinprep(000)            ; 185  -0.98527764
        sinprep(000)            ; 186  -0.98917651
        sinprep(000)            ; 187  -0.99247953
        sinprep(000)            ; 188  -0.99518473
        sinprep(000)            ; 189  -0.99729046
        sinprep(000)            ; 190  -0.99879546
        sinprep(000)            ; 191  -0.99969882
        sinprep(000)            ; 192  -1
        sinprep(000)            ; 193  -0.99969882
        sinprep(000)            ; 194  -0.99879546
        sinprep(000)            ; 195  -0.99729046
        sinprep(000)            ; 196  -0.99518473
        sinprep(000)            ; 197  -0.99247953
        sinprep(000)            ; 198  -0.98917651
        sinprep(000)            ; 199  -0.98527764
        sinprep(000)            ; 200  -0.98078528
        sinprep(000)            ; 201  -0.97570213
        sinprep(001)            ; 202  -0.97003125
        sinprep(001)            ; 203  -0.96377607
        sinprep(001)            ; 204  -0.95694034
        sinprep(001)            ; 205  -0.94952818
        sinprep(002)            ; 206  -0.94154406
        sinprep(002)            ; 207  -0.9329928
        sinprep(003)            ; 208  -0.92387953
        sinprep(003)            ; 209  -0.91420976
        sinprep(003)            ; 210  -0.90398929
        sinprep(004)            ; 211  -0.8932243
        sinprep(004)            ; 212  -0.88192126
        sinprep(005)            ; 213  -0.87008699
        sinprep(005)            ; 214  -0.85772861
        sinprep(006)            ; 215  -0.84485356
        sinprep(006)            ; 216  -0.83146961
        sinprep(007)            ; 217  -0.81758481
        sinprep(007)            ; 218  -0.80320753
        sinprep(008)            ; 219  -0.78834643
        sinprep(008)            ; 220  -0.77301045
        sinprep(009)            ; 221  -0.75720885
        sinprep(010)            ; 222  -0.74095112
        sinprep(010)            ; 223  -0.72424708
        sinprep(011)            ; 224  -0.70710678
        sinprep(012)            ; 225  -0.68954054
        sinprep(012)            ; 226  -0.67155895
        sinprep(013)            ; 227  -0.65317284
        sinprep(014)            ; 228  -0.63439328
        sinprep(015)            ; 229  -0.61523159
        sinprep(015)            ; 230  -0.5956993
        sinprep(016)            ; 231  -0.57580819
        sinprep(017)            ; 232  -0.55557023
        sinprep(018)            ; 233  -0.53499762
        sinprep(019)            ; 234  -0.51410274
        sinprep(020)            ; 235  -0.49289819
        sinprep(020)            ; 236  -0.47139674
        sinprep(021)            ; 237  -0.44961133
        sinprep(022)            ; 238  -0.42755509
        sinprep(023)            ; 239  -0.40524131
        sinprep(024)            ; 240  -0.38268343
        sinprep(025)            ; 241  -0.35989504
        sinprep(026)            ; 242  -0.33688985
        sinprep(027)            ; 243  -0.31368174
        sinprep(028)            ; 244  -0.29028468
        sinprep(028)            ; 245  -0.26671276
        sinprep(029)            ; 246  -0.24298018
        sinprep(030)            ; 247  -0.21910124
        sinprep(031)            ; 248  -0.19509032
        sinprep(032)            ; 249  -0.17096189
        sinprep(033)            ; 250  -0.14673047
        sinprep(034)            ; 251  -0.12241067
        sinprep(035)            ; 252  -0.9801714e-1
        sinprep(036)            ; 253  -0.73564563e-1
        sinprep(037)            ; 254  -0.49067674e-1
        sinprep(038)            ; 255  -0.24541228e-1
;******************************************************************

That same source file includes some notes for a DDS Signal Generator engine using a 20-pin 18F14K22 driving an 8-bit R2R ladder that might be interesting to someone;

Code:
;******************************************************************
;  additional DDS musings                                         *
;******************************************************************
;
;  use an 18F14K22 (64-MHz), a 32 cycle (500-kHz) DDS loop, and
;  25.575 bit accumulator and phase variables for a 0.01-Hz DDS
;  frequency resolution (log500000*100/log2).  subtract phase
;  offset each loop and add 500000*100 on accumulator underflow
;  then use upper 9.575 accumulator bits (b25..b16) as an index
;  into a 763 byte (2^9.575) sine array.
;
;  stuff 'phase' offset variable with frequency*100 values (use
;  75000 for 750.00-Hz, 104005 for 1040.05-Hz, etc).  consider
;  limiting upper frequency to 16 samples per cycle (500000/16)
;  which is 31250.00 Hz.  Experiment to determine lower limit.
;
        radix   dec
dds64
        movf    phase+0,W       ; subtract phase offset from
        subwf   accum+0,F       ; the phase accumulator
        movf    phase+1,W       ;
        subwfb  accum+1,F       ; accum bits b15..b08
        movf    phase+2,W       ;
        subwfb  TBLPTRL,F       ; accum bits b23..b16
        movf    phase+3,W       ;
        subwfb  TBLPTRH,F       ; accum bits b25..b24
 ;
 ;  add 500000*100 to accumulator on accumulator underflow
 ;
        movlw   500000*100%0x0000100
        btfsc   TBLPTRH,7       ; negative? no, skip, else
        addwf   accum+0,F       ;
        movlw   500000*100/0x0000100
        btfsc   TBLPTRH,7       ; negative? no, skip, else
        addwfc  accum+1,F       ;
        movlw   500000*100/0x0010000
        btfsc   TBLPTRH,7       ; negative? no, skip, else
        addwfc  TBLPTRL,F       ;
        movlw   500000*100/0x1000000
        btfsc   TBLPTRH,7       ; negative? no, skip, else
        addwfc  TBLPTRH,F       ;
        movf    tbladdr,W       ; tables 1000, 1400, 1800, 1C00
        iorwf   TBLPTRH,F       ; select proper table
        tblrd*                  ; uses 2 cycles
        movff   TABLAT,PORTC    ; 8-bit sine value
        xorwf   TBLPTRH,F       ; restore accumulator value
        nop                     ;
        nop                     ;
        nop                     ;
        bra     dds64           ; must be exactly 32 cycle loop
;******************************************************************
 
Last edited:
DDS Signal Generator Design Kind of what I want make I don't have a Signal Generator I've put together some with a timer but I been playing with something that needs a sine wave.

And I want make some tools to mess around with.

Figured now be the time to really do some stuff I been wanting to do.
 
I have a 16f that has a dac and that wave making I really like to give it ago at this.
 

I built the one out of the EPE magazine... It still serves me very well today


Sitting on top of my old storage scope...
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…