DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?


Closed Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 77
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Just wondering if anyone has dabbled with the DAC aspect on the latest range of PICS.

    IFor example a PIC16F1824.....I'm figuring that it having a DAC onboard is going to be a significant win over say using a PWM & low pass filter?

    My goal is to generate sine waves to a reasonable level of accuracy up to about 3Khz. (ie plus/minus 0.3Hz)

    Never having dabbled with PIC DACS previously (or any DAC!), would anyone have any example code or setups?

  2. #2


    Did you find this post helpful? Yes | No

    Default dac

    it looks like that so-called dac is just the 5-bit Vref part.
    I don't know why they won't put a 10 bit dac in a pic, there is just about everything else available in the pics.

    waiting,
    don

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default

    Hi Hank,
    I've never played with them but I'd say it depends on what kind of resolution you need as the DAC in the 16F1824 only has 5 bits of it. This means that you will only be able to get 32 discrete voltage levels which may, or may not, be enough.

    /Henrik.

    Edit: Don beat me to it, I was reading the datasheet while writing.

  4. #4
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi Hank,
    I've never played with them but I'd say it depends on what kind of resolution you need as the DAC in the 16F1824 only has 5 bits of it. This means that you will only be able to get 32 discrete voltage levels which may, or may not, be enough.

    /Henrik.

    Edit: Don beat me to it, I was reading the datasheet while writing.
    Actually 5 bits would probably ok for my needs, but I need to be able to resolve the frequency to 0.1% (eg plus or minus 1Hz @1khz & so on)

    I can see now that is's a very very basic DAC (just a 32 step pot really)...hey, ho.

    Thanks for your input though.

  5. #5
    Join Date
    Oct 2005
    Location
    Loveland CO USA
    Posts
    83


    Did you find this post helpful? Yes | No

    Default

    The DAC is very high impedance. You will need a buffer. Normally I use a 2 pole low pass filter to remove the digital noise.

  6. #6
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Hi Hank,

    Not exactly what you asked for, but... have you considered using the PWM module with a low pass filter on the CCP1 output? You may need to amplify the signal as well.

    I was toying with this idea a while back for a CTCSS Access Tone Generator but I never got around to building and testing it.

    This example (free/lite version of BoostC) uses a 12F683 and an 8.388608-MHz crystal to generate CTCSS sine wave tones spanning 100 to 250-Hz with 0.000625-Hz frequency resolution. If you were to use a 12F1822 with that crystal and 4xPLL, or any other device with 4xPLL, you could bump the upper frequency range to about 1000-Hz with 0.0025-Hz frequency resolution.

    Food for thought.

    Cheerful regards, Mike McLaren, K8LH


    PS: A quick search came up with this interesting old thread; Generating tones with decimals using PWM

    Code:
    /********************************************************************
     *                                                                  *
     *  Project: CTCSS 12F683                                           *
     *   Source: CTCSS_12F683.c                                         *
     *   Author: Mike McLaren, K8LH                                     *
     *     Date: 26-Nov-10                                              *
     *  Revised: 26-Nov-10                                              *
     *                                                                  *
     *  untested 12F683 DDS(PWM) CTCSS Tone Generator with 24-bit       *
     *  Phase Accumulator (Fosc = 8.388608-MHz)                         *
     *                                                                  *
     *      IDE: MPLAB 8.56 (tabs = 4)                                  *
     *     Lang: SourceBoost BoostC v7.01, Lite/Free version            *
     *                                                                  *
     ********************************************************************
     *
     *    CTCSS tone frequencies
     *
     *     67.0 Hz    69.3 Hz    71.9 Hz    74.4 Hz    77.0 Hz
     *     79.7 Hz    82.5 Hz    85.4 Hz    88.5 Hz    91.5 Hz
     *     94.8 Hz    97.4 Hz   100.0 Hz   103.5 Hz   107.2 Hz
     *    110.9 Hz   114.8 Hz   118.8 Hz   123.0 Hz   127.3 Hz
     *    131.8 Hz   136.5 Hz   141.3 Hz   146.2 Hz   151.4 Hz
     *    156.7 Hz   159.8 Hz   162.2 Hz   165.5 Hz   167.9 Hz
     *    171.3 Hz   173.8 Hz   177.3 Hz   179.9 Hz   183.5 Hz
     *    186.2 Hz   189.9 Hz   192.8 Hz   196.6 Hz   199.5 Hz
     *    203.5 Hz   206.5 Hz   210.7 Hz   218.1 Hz   225.7 Hz
     *    229.1 Hz   233.6 Hz   241.8 Hz   250.3 Hz   254.1 Hz
     *
     */
    
    #include system.h
    
    #pragma DATA _CONFIG, _MCLRE_OFF, _WDT_OFF, _HS_OSC
    
    #pragma CLOCK_FREQ 8388608      // using an 8.388608-MHz crystal
    
    //--< function prototypes >------------------------------------------
    //--< type definitions >---------------------------------------------
    
    typedef unsigned char u08;
    typedef unsigned int u16;
    typedef unsigned long u32;
    
    #define r08 rom char*
    
    //--< variables >----------------------------------------------------
    
    u32 accum;                  // phase accumulator
    u32 phase;                  // phase offset (DDS tuning word)
    
    r08 sinetbl =   { 100,102,104,107,109,112,114,117,119,121,
                      124,126,129,131,133,135,138,140,142,144,
                      147,149,151,153,155,157,159,161,163,165,
                      167,168,170,172,174,175,177,178,180,181,
                      183,184,185,187,188,189,190,191,192,193,
                      194,194,195,196,197,197,198,198,198,199,
                      199,199,199,199,200,199,199,199,199,199,
                      198,198,198,197,197,196,195,194,194,193,
                      192,191,190,189,188,187,185,184,183,181,
                      180,178,177,175,174,172,170,168,167,165,
                      163,161,159,157,155,153,151,149,147,144,
                      142,140,138,135,133,131,129,126,124,121,
                      119,117,114,112,109,107,104,102, 99, 97,
                       95, 92, 90, 87, 85, 82, 80, 78, 75, 73,
                       70, 68, 66, 64, 61, 59, 57, 55, 52, 50,
                       48, 46, 44, 42, 40, 38, 36, 34, 32, 31,
                       29, 27, 25, 24, 22, 21, 19, 18, 16, 15,
                       14, 12, 11, 10,  9,  8,  7,  6,  5,  5,
                        4,  3,  2,  2,  1,  1,  1,  0,  0,  0,
                        0,  0,  0,  0,  0,  0,  0,  0,  1,  1,
                        1,  2,  2,  3,  4,  5,  5,  6,  7,  8,
                        9, 10, 11, 12, 14, 15, 16, 18, 19, 21,
                       22, 24, 25, 27, 29, 31, 32, 34, 36, 38,
                       40, 42, 44, 46, 48, 50, 52, 55, 57, 59,
                       61, 64, 66, 68, 70, 73, 75, 78, 80, 82,
                       85, 87, 90, 92, 95, 97 };
    
    //--< defines >------------------------------------------------------
    
    //--< isr >----------------------------------------------------------
    
    /*
     *  12F/16F1xxx DDS-PWM CTCSS "Access Tone Generator" Notes
     *  =======================================================
     *
     *  using an 8.388608 MHz crystal
     *
     *    Tcy = 1 / 8388608 * 4 = 476.837158203125 nsecs
     *
     *  using a 200 cycle PWM period provides a DDS frequency of
     *
     *    Fdds = 1 / (200 Tcy) = 10,485.76 Hz
     *
     *  frequency resolution using a 24 bit phase accumulator is
     *
     *    Fres = Fdds / 2^24
     *    Fres = 10485.76 / 16777216 = 0.000625 Hz
     *
     *  dds tuning word (phase offset) can be calculated a couple
     *  different ways.  since the dds frequency resolution (Fres)
     *  is basically 0.01-Hz divided by 16, you can calculate the
     *  phase offset by mulitplying desired Fout output frequency
     *  by 1600.  the phase offset for an Fout of 254.1-Hz is;
     *
     *    phase = (Fout  * 100) * 16
     *          = (254.1 * 100) * 16 = 406560
     *
     *    phase =  25410 << 4 = 406560
     *
     *  or you can also calculate phase offset like this (yuch!);
     *
     *    phase = Fout / Fres
     *          = 254.1 / 0.000625 = 406560
     *
     *    phase = Fout * 2^24 / Fdds
     *          = 254.1 * 16777216 / 10485.76 = 406560
     *
     *  the highest CTCSS frequency (254.1 Hz) will produce the
     *  smallest number of sine wave D/A output points per cycle;
     *
     *    INT(10485.76 / 254.1) = 41 output points per cycle
     *
     *  use the most significant 8 bits of the 24-bit phase
     *  accumulator as the sine table index.
     *
     */
    
    void interrupt()                // 200-cycles (10485.76-Hz)
    { pir1.TMR2IF = 0;              // clear TMR2 interrupt flag
      accum += phase;               // add phase offset to accum
      ccpr1l = sinetbl[accum>>16];  // sine duty cycle value for
    }                               // next PWM period
    
    //--< main >---------------------------------------------------------
    
    void main()
    {
      cmcon0 = 7;                   // comparator off, digital I/O
      ansel = 0;                    // a2d module off, digital I/O
      trisio = 0b00111011;          // GP2 output, all others input
     /*
      *  setup PWM module for 200 cycle interrupts (10485.76-Hz using
      *  an 8.388608-MHz clock)
      *
      */
      ccp1con = 0b00001100;         // 00001100
                                    // --00---- DC1B<1:0>, duty cycle b1:b0
                                    // ----1100 CCP1M<3:0>, pwm mode
      t2con = 0b00000000;           // 00000000
                                    // -0000--- TOUTPS<3:0>, postscale 1
                                    // -----0-- TMR2ON, timer off
                                    // ------00 T2CKPS<1:0>, prescale 1
                                    // for 476.837158203125 nsec 'ticks'
      pr2 = 200-1;                  // for 95.367431640625 usec interrupts
      ccpr1l = 0;                   // 0% duty cycle
      pie1.TMR2IE = 1;              // enable Timer 2 interrupts
      pir1 = 0;                     // clear all peripheral interrupt flags
      intcon.PEIE = 1;              // enable peripheral interrupts
      intcon.GIE = 1;               // enable global interrupts
      t2con.TMR2ON = 1;             // turn TMR2 on
    
      phase = 25410 << 4;           // phase offset for 254.1-Hz tone
    
      while(1);                     // loop forever
    }
    Last edited by Mike, K8LH; - 15th January 2011 at 18:36.

  7. #7
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi Mike,

    yes I've done that....I just got a bit over excited at the prospect of an onboard DAC, but I now realise it's pretty poor....looks as if it's meant to generate a ref voltage, but being high impedance, I'd be better off using two resistors and an opamp!

  8. #8
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Do you think it might be possible to add 2 (or more) bits of precision to the DAC?

    Code:
    Interval  #1  #2  #3  #4
         DAC  00  00  00  00  -> 0.00v
         DAC  00  00  00  01  -> 0.04v
         DAC  00  00  01  01  -> 0.08v
         DAC  00  01  01  01  -> 0.12v
    
         DAC  01  01  01  01  -> 0.16v
         DAC  01  01  01  02  -> 0.20v
         DAC  01  01  02  02  -> 0.24v
         DAC  01  02  02  02  -> 0.28v
    
         DAC  02  02  02  02  -> 0.32v
         ........

  9. #9
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by Mike, K8LH View Post
    Do you think it might be possible to add 2 (or more) bits of precision to the DAC?

    Code:
    Interval  #1  #2  #3  #4
         DAC  00  00  00  00  -> 0.00v
         DAC  00  00  00  01  -> 0.04v
         DAC  00  00  01  01  -> 0.08v
         DAC  00  01  01  01  -> 0.12v
     
         DAC  01  01  01  01  -> 0.16v
         DAC  01  01  01  02  -> 0.20v
         DAC  01  01  02  02  -> 0.24v
         DAC  01  02  02  02  -> 0.28v
     
         DAC  02  02  02  02  -> 0.32v
         ........
    This must have slipped past me - I'm not understanding what you're getting at?

    I was actually wondering myself whether it's possible in practise to squeeze another 2 bits of effective' resolution by switching the fixed voltage reference supply into the DAC resistor divider chain (ie feed 1.024V in for the first 32 voltage level steps, then 2.048, then 4.096V) - it might be a bit spikey (due to the FVR switching voltages), but if not that should mean we can squeeze 7 bits out of the PIC's DAC pin.

  10. #10
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Use a DDS chip.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  11. #11
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by rmteo View Post
    Use a DDS chip.
    They're overkill for my needs (I only want an audio waveform at about 5khz frequency max! They typically go up to Mhz...so i'm paying handsomely for a feature I don't need) - I also want intricate 'control' over how to select the final waveform via my own control set (not be forced to follow theirs) ....plus if we all simply used dedicated hw ICs (at $15 a pop!) what would we ever learn?
    Last edited by HankMcSpank; - 26th August 2011 at 15:30.

  12. #12
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Using the right tool for the job is half the battle won - that is what you learn. Here is a 20KHz Sine Wave generated by using the built-in 12-bit DAC of the MCU which like any peripheral (such as a timer or ADC) uses little to no CPU resources once set up. Without a proper DAC, generating waveforms will consume substantial amounts of CPU resources. However, for any practical application, I would still use a DDS chip.
    Attached Images Attached Images  
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  13. #13
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by rmteo View Post
    Using the right tool for the job is half the battle won - that is what you learn.
    Agreed, and paying $15 for a DDS IC, that I can (hopefully) get a $1 PIC to fulfill my (modest) needs means I am indeed trying to use the right tool for the job - i wouldn't use a rotavator to dig over my garden when for my tiny bit of soil a spade is just fine (while a rotavator clearly turns soil over, I'd say it wasn't the right tool for the job in that instance)

    Quote Originally Posted by rmteo View Post
    Here is a 20KHz Sine Wave generated by using the built-in 12-bit DAC of the MCU which like any peripheral (such as a timer or ADC) uses little to no CPU resources once set up.
    Again, I don't need to generate 20khz (that's 4 times higher than I need), I don't need 12 bits resolution (that's about 5 or 6 bits more than I need).

    But more importantly, I don't learn a thing if I go & buy a DDS IC (& at the end of the day, isn't that why most of us do this type of stuff?)
    Last edited by HankMcSpank; - 26th August 2011 at 16:08.

  14. #14
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Well I did use a $1 MCU to generate that sine wave. So by your logic, that would be the right tool for the job.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  15. #15
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Im with you Hank, I want to see what you can make it do!

  16. #16
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by rmteo View Post
    Well I did use a $1 MCU to generate that sine wave. So by your logic, that would be the right tool for the job.
    Apologies...I misread you...if you paid a $1 (vs $15 for a DDS IC) & all you wanted was a 20Khz sine wave or less, then yes, by my logic that would be the right tool to do the job! (even if you had to dedicate the PIC to nothing else, due to the burden placed on it). They sell Aston Martins here in London...but I wouldn't buy one to go to the corner shop - my bike will do!

    After just a short bit of dabbling, I've approximated a sine wave using DDS principles & the 16f1828's meagre inbuilt 5 bit DAC & a modest 16 bit accumulator (& no filtering cap),



    Sure, the tops are a little pointy (16 levels per swing isn't much!) & I doubt it'll win any distortion/noise figure awards, but if I can squeeze another 2 bits resolution by getting creative with the FVR, then that'll probably do me. If not, I'll just go the 10 bit PWM method....but that method uses a filtering cap, so the amplitude will change with frequency - I was really after a fixed output amplitude no matter what the output frequency (& without going the R2R ladder way)
    Last edited by HankMcSpank; - 26th August 2011 at 16:47.

  17. #17
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Actually, the CPU load is zero while that $1 microcontroller is generating the 20KHz sine wave. You can just as easily generate any frequency up to about 250KHz with that device. Here is staircase waveform on the same MCU - great for doing things like testing power supplies, etc.
    Attached Images Attached Images  
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  18. #18
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Which PIC16F chip are you using rmteo?

  19. #19
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by scalerobotics View Post
    Which PIC16F chip are you using rmteo?
    I said it was a a $1 device - didn't say it was a PIC16.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  20. #20
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by rmteo View Post
    I said it was a a $1 device - didn't say it was a PIC16.
    Oh, it must be one of those new PIC12F's or maybe the PIC18F's? Because those are the only ones compatible with PBP, on the top bar of the forum.....

  21. #21
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by scalerobotics View Post
    Oh, it must be one of those new PIC12F's or maybe the PIC18F's? Because those are the only ones compatible with PBP, on the top bar of the forum.....
    I doubt it.
    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!!

  22. #22
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    rmteo,

    It is interesting that 99.9% of the posters here talk about .... well the topic of the forum ... Pic Basic Pro. Your posts are often misleading, because newer users assume you are talking on-topic, rather than about some 16 or 32 bit chip which can not be programmed in PBP. If you are going to give advice that 100% of our users didn't ask for, and 95% of our users can't use, you should probably mention that your solution can't be used with the tools which this forum is based on.

  23. #23
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    even if you had to dedicate the PIC to nothing else, due to the burden placed on it
    Hank, this is a great idea. Seems like you should be able to do it with any basic device if this is all you want it to do. The comm's to it will be the only thing to worry with. So lets be clear what you want here -
    1Hz-5KHz sine wave
    fixed amplitude
    A way to get its attention to change the freq.

    Do I have this correct?

    just remembered one thing, did you say NO passive devices?
    Last edited by cncmachineguy; - 26th August 2011 at 18:56.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  24. #24
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Hi Bert,

    Quote Originally Posted by cncmachineguy View Post
    Seems like you should be able to do it with any basic device
    Agreed...even though I'm using a 16f1828 to practise with, my favourite low chip end of the moment is an 8 pin 12f1822. So a simple DDS program + servicing an odd interrupt (for frequency change)...should be a walk in the park. I also think even a low end 12f chip is going to be much more capable of outputting more than 5Khz...but I mentioned that frequency, only because it's all I need.

    Quote Originally Posted by cncmachineguy View Post
    1Hz-5KHz sine wave
    fixed amplitude
    A way to get its attention to change the freq.

    Do I have this correct?
    Correct, I would add, granularity to 0.01Hz or better (this is perhaps the most important requirement for me). That's where the larger accumulator is needed
    (see my other post - http://www.picbasic.co.uk/forum/show...887#post106887 )

    Without want to teach granny to suck eggs, the output frequency granularity is established from this formula...

    interrupt frequency/ accumulator

    So for an interrupt rate of say 20khz & a 16 bit accumulator, it'd be

    20,000/65536 = 0.30Hz granularity which is insufficient for my needs, which means either making the accumulator larger, or the sample rate smaller....I don't want to do the latter, hence wanting to make the accumulator larger, but I then start hitting my knowledge boundary dealing in 17 bit+ numbers witin the confines of picbasic.

    Also, there's likely to be a fair degree of floating point...which I'll have to work around. For example to set the required freqency, it's

    (required frequency/sinterrupt rate)*accumulator , so for 1500Hz

    (1500Hz/20,000) * 65536 ........clearly the first part of that equation is going to result in a decimal, so quite a few things impeding me at the moment!

    re no passive devices ...well, ideally no reactive passive devices (on account they alter the amplitude as the frequency changes)....using an R2R ladder would be cool, except the take up a lot of space & that's something I always try to avoid (I can't seem to locate anyone that sells prefabbed R2R ladders here in the UK)
    Last edited by HankMcSpank; - 26th August 2011 at 19:55.

  25. #25
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    On the passives, I was thinking about the fact we can only output 2 levels, Vcc and Vdd, so the "sine" wave won't be. I have found R2R sips before, but that would also require enough I/O to service it in parallel.

    What do we do about the not analog output?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  26. #26
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    I think we're at crossed wires a little.

    My first (present) plan of attack is to use the 5 bit internal DAC to get an anlogue output... (that's what my screenscrape was earlier - using the PIC's internal DAC to get a rough analogue output) clearly 32 steps is insufficent for sine waves, so I was trying to add an extra 2 bits by creatively using the PIC Fixed voltage reference (the PIC FVR output canfeed the DAC and the voltagae output can be set to 1.024V, 2.048V or 4.096V) - I might not be grasping a fundamental issue here, so I need to ponder this one until I have an "Oops, that was an embarrassing idea" moment!

    If the above comes to nothing then I'll relent & use HPWM and a filter (I only had a brief go at this a year or so ago & didn't actually test how much the reactance of the cap in such an arrangement impacts the amplitude...over the range I'm interested (0-5khz) it mght not be that much. I'm of the opinion that I'll end up having to go this way...then all I have to crack is the accumulator problem (need more than 16 bits) & the little bit of floating point (to get the accumulator value needed for the required frequency)

    Clearly if I end up going the R2R route, then I'll need to bring a 14 pin PIC into service (likely to be a 16f1824)

  27. #27
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by HankMcSpank View Post
    My first (present) plan of attack is to use the 5 bit internal DAC to get an anlogue output... (that's what my screenscrape was earlier - using the PIC's internal DAC to get a rough analogue output) clearly 32 steps is insufficent for sine waves, so I was trying to add an extra 2 bits by creatively using the PIC Fixed voltage reference (the PIC FVR output canfeed the DAC and the voltagae output can be set to 1.024V, 2.048V or 4.096V) - I might not be grasping a fundamental issue here, so I need to ponder this one until I have an "Oops, that was an embarrassing idea" moment!
    Well, I reckon this one is doomed ...I've only just realised for my plan to work, I would need to be able to shift the 'negative ref' of the DAC to the FVR module output (I'd then get 32 steps between gnd & FVR ref, then another 32 steps between FVR & Vref) - the 16f1828 DAC control register doesn't allow this...hey ho.

    Ok, so HPWM and a filter it is then...at least I'll see what impact there is on amplitude as the frequency rises!

  28. #28
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Ok, so I am now up to speed with you who is up to speed with me. We can now plod along blindly together - LOL. I was thinking of doing this all with software so as not to be dependent on HPWM. Chasing the single low cost PIC for 1 purpose, I was assuming HPWM may not be available.

    Quick question, what is the fastest time needed? ie, 5,000hz has a time of .2mS, but 5,000.01 has a time of .199999mS. so you want .1uS, .01uS,1uS,bla bla bla. on the other hand 100hz is 10mS while 100.01Hz is 9.9999mS.

    As you can see, I am having conceptual trouble here with the .01Hz spec.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  29. #29
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by cncmachineguy View Post
    Ok, so I am now up to speed with you who is up to speed with me. We can now plod along blindly together - LOL. I was thinking of doing this all with software so as not to be dependent on HPWM. Chasing the single low cost PIC for 1 purpose, I was assuming HPWM may not be available.

    Quick question, what is the fastest time needed? ie, 5,000hz has a time of .2mS, but 5,000.01 has a time of .199999mS. so you want .1uS, .01uS,1uS,bla bla bla. on the other hand 100hz is 10mS while 100.01Hz is 9.9999mS.

    As you can see, I am having conceptual trouble here with the .01Hz spec.
    Maybe I'm too ambitious with the .01Hz accuracy, maybe .1hz is more achievable (initially)....as it goes, I actually only need that accuracy at the lower end of the 60hz-5,000Hz frequency range (where obviously 0.1Hz error of say 60hz is a whole lot more in percentage terms than .1Hz for 5khz) but with DDS you have to decide on the acceptable resolution then be stuck with it across the frequency band. so yes, say 50.01Hz, 50.02Hz, 50.3Hz thru 5,000Hz is what I hope to achieve here.

    I've read that DDS 'interrupt rate' should be at least twice the targetted/required highest freqency, which since I want 5Khz, should mean a minimum interrupt of 10khz...but I thought 20Khz might be better. So with a 16 bit accumulator, we get....

    audio ouput frequency granularity = 20,000/65536 or 0.31hz (which is not enough) ...even dropping the interrupt rate to 10khz means granularity of 0.15Hz)

    That said, for proof of concept, maybe I just go with that initially ....ie 10,000 interrupts per second and a simple 16 bit accumulator - once that's been proven, then we can stride out a bit!
    Last edited by HankMcSpank; - 27th August 2011 at 00:30.

  30. #30
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    hank, your PM is full
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  31. #31
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    HenrikOlsson, kindly offered up this code he put together as a solution how to get an accumulator large than 16 bit (see this thread http://www.picbasic.co.uk/forum/show...943#post106943 ) ...

    Code:
    LSW  VAR WORD              ' Least significat word of accumulator
    MSW  VAR WORD              ' Most significatn word of accumulator
     
    ADDL VAR WORD              ' Least significant work of value to add
    ADDH VAR WORD              ' Most significant word of value to add 
     
    Out VAR BYTE                    ' This is the actual output from the lookup table
     
    Temp VAR WORD
     
    OverFlow VAR BIT             ' Gets set when 32bit accumulator overflows.
     
    i VAR WORD
     
    Init:
      LSW = 0 
      MSW = 0
      AddL = 500
      AddH = 2000   ' 50*256+500=768500
     
    Pause 3000
     
    Main:
    For i = 1 to 1000
      OverFlow = 0
      TMR1H = 0
      TMR1L = 0
     
      Gosub Add
      Gosub GetValue
     
      HSEROUT["Count: ", DEC4 i, "  MSW: ", DEC5 MSW, "   LSW: ", DEC5 LSW, "   Overflow: ", BIN Overflow, "  Out: ", DEC Out, "  Ticks: ", DEC5 TMR1H*256+TMR1L, 13]
      Pause 5
    NEXT
     
    END
     
    Add:
      T1CON = 1             ' This is just used to measure the execution time
     
      Temp = LSW            ' Remember least significant word
      LSW = LSW + ADDL      ' Add low word 
     
      If LSW < Temp Then ' Did we wrap around/overflow?
        MSW = MSW + 1       ' Increment high word
        If MSW = 0 Then OverFlow = 1  ' Did we overflow high word?
      ENDIF
     
      Temp = MSW            ' Remember high word
      MSW = MSW + ADDH      ' Add high word 
     
      If MSW < Temp Then ' Did we wrap around/overflow?
        OverFlow = 1     ' Set flag
      ENDIF
     
    T1CON = 0
    RETURN
     
    GetValue:
    Lookup MSW.HighBYTE, [$80,$83,$86,$89,$8C,$8F,$92,$95,$98,$9C,$9F,$A2,$A5,$A8,$AB,$AE,$B0,$B3,$B6,$B9,$BC,$BF,$C1,$C4,_
    $C7,$C9,$CC,$CE,$D1,$D3,$D5,$D8,$DA,$DC,$DE,$E0,$E2,$E4,$E6,$E8,$EA,$EC,$ED,$EF,$F0,$F2,$F3,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FC, _
    $FD,$FE,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FE,$FD,$FC,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F3,$F2,$F0,$EF,$ED,$EC, _
    $EA,$E8,$E6,$E4,$E2,$E0,$DE,$DC,$DA,$D8,$D5,$D3,$D1,$CE,$CC,$C9,$C7,$C4,$C1,$BF,$BC,$B9,$B6,$B3,$B0,$AE,$AB,$A8,$A5,$A2,$9F,$9C, _
    $98,$95,$92,$8F,$8C,$89,$86,$83,$7F,$7C,$79,$76,$73,$70,$6D,$6A,$67,$63,$60,$5D,$5A,$57,$54,$51,$4F,$4C,$49,$46,$43,$40,$3E,$3B, _
    $38,$36,$33,$31,$2E,$2C,$2A,$27,$25,$23,$21,$1F,$1D,$1B,$19,$17,$15,$13,$12,$10,$0F,$0D,$0C,$0A,$09,$08,$07,$06,$05,$04,$03,$03, _
    $02,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$02,$03,$03,$04,$05,$06,$07,$08,$09,$0A,$0C,$0D,$0F,$10,$12,$13, _
    $15,$17,$19,$1B,$1D,$1F,$21,$23,$25,$27,$2A,$2C,$2E,$31,$33,$36,$38,$3B,$3E,$40,$43,$46,$49,$4C,$4F,$51,$54,$57,$5A,$5D,$60,$63, _
    $67,$6A,$6D,$70,$73,$76,$79,$7C],Out
    RETURN
    Not sure I'll get time over this weekend, but intend trying it soon.

    If it works (& I've no doubt it will!), then that just leaves on issue-ette - how to get a PIC to convert the required frequency (say arriving in from a serial port from a human or other pic), into the 'tuning word'.

    required frequency/interrupt rate * accumulator size

    so for a required frequency of 4971.21Hz involving a 32 bit accumulator & and say an interupt rate of 20,000Hz

    (4971.21/20000) * 4294967296

    the first part of the equation results in a decimal & then multiplying the decimal by a 32 bit number....woah! (can this even be done?!)
    Last edited by HankMcSpank; - 27th August 2011 at 11:53.

  32. #32
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Hi Hank,
    Starting with your last question in the other thread. Yes, that's basically the code that would go into your ISR. But you can remove the TMR1 stuff and the whole overflow flag business, that was just a debug aid.

    Here's it is repackaged:
    Code:
    Add:
        Lookup MSW.HighBYTE, [$80,$83,$86,$89,$8C,$8F,$92,$95,$98,$9C,$9F,$A2,$A5,$A8,$AB,$AE,$B0,$B3,$B6,$B9,$BC,$BF,$C1,$C4,_
        $C7,$C9,$CC,$CE,$D1,$D3,$D5,$D8,$DA,$DC,$DE,$E0,$E2,$E4,$E6,$E8,$EA,$EC,$ED,$EF,$F0,$F2,$F3,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FC, _
        $FD,$FE,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FE,$FD,$FC,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F3,$F2,$F0,$EF,$ED,$EC, _
        $EA,$E8,$E6,$E4,$E2,$E0,$DE,$DC,$DA,$D8,$D5,$D3,$D1,$CE,$CC,$C9,$C7,$C4,$C1,$BF,$BC,$B9,$B6,$B3,$B0,$AE,$AB,$A8,$A5,$A2,$9F,$9C, _
        $98,$95,$92,$8F,$8C,$89,$86,$83,$7F,$7C,$79,$76,$73,$70,$6D,$6A,$67,$63,$60,$5D,$5A,$57,$54,$51,$4F,$4C,$49,$46,$43,$40,$3E,$3B, _
        $38,$36,$33,$31,$2E,$2C,$2A,$27,$25,$23,$21,$1F,$1D,$1B,$19,$17,$15,$13,$12,$10,$0F,$0D,$0C,$0A,$09,$08,$07,$06,$05,$04,$03,$03, _
        $02,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$02,$03,$03,$04,$05,$06,$07,$08,$09,$0A,$0C,$0D,$0F,$10,$12,$13, _
        $15,$17,$19,$1B,$1D,$1F,$21,$23,$25,$27,$2A,$2C,$2E,$31,$33,$36,$38,$3B,$3E,$40,$43,$46,$49,$4C,$4F,$51,$54,$57,$5A,$5D,$60,$63, _
        $67,$6A,$6D,$70,$73,$76,$79,$7C],Out
     
    ' Here you should move the value to where it should be, DAC, PWM, R2R now.
     
        Temp = LSW            ' Remember least significant word
        LSW = LSW + ADDL      ' Add low word 
     
        If LSW < Temp Then    ' Did we wrap around/overflow?
            MSW = MSW + 1     ' Increment high word
        ENDIF
     
        Temp = MSW            ' Remember high word
        MSW = MSW + ADDH      ' Add high word 
    RETURN
    This thing, including the lookup table runs in about 75 cycles which I think is pretty good. It's not near the 35 cycles quoted in the doc you linked to but I think it's plenty for your needs.


    I played around a bit and I'm not sure this is going to work for you (due to the high resoultion of 2 decimal places you need) but it might be worth a try.
    Your formula: 4971.21 / 20000 * 2^32 = 1067559218 can be reorganised so it reads 4971.21 * (2^32/20000) or 4971.21 * 214748.36.

    Since your maximum frequency is 5000Hz we can multiply that side of the equation by 10 and still have it fit in a WORD, when we do that we can divide the other side of the equation by 10 which makes IT TOO fit in a WORD so now we have 49712 * 21475 = 1067565200 which obviosuly won't fit.....

    I then tried to extract the 32bit intermediate result of that 16 by 16 bit multiplication and it seems like it might work. If I'm not mistaken the high word is stored in system variable R0 and the low word in R2 so if we could extract those immediately after doing the multiplication we're pretty much good to go:

    Code:
    Frequency VAR WORD
    Temp VAR WORD
     
    Frequency = 49712   ' 4971.2Hz
    Temp = Frequency * 21475    ' Produce the 32bit intermediate result
    AddH = R0                           ' Get high word from R0
    AddL = R2                           ' and low word from R2
    Gosub PrintIt                       ' Display it
     
    Pause 100
    END
     
    PrintIt:
      HSEROUT["Frequency: ", DEC Frequency/10, ".", DEC Frequency//10, "   AddValue: ", DEC AddH, " , ", DEC AddL,13] 
    RETURN
    The above shows AddH as 15699 and AddL as 60536. That's 15699 * 65536 + 60536 = 1028910200 when it "should" be 1028902365, not perfect but close.


    Play with it, see if it works. If not you might want to look into Darrels N-Bit math routines, they should be pretty straight forward for this I think.

    /Henrik.
    Last edited by HenrikOlsson; - 27th August 2011 at 13:46.

  33. #33
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Thanks once again Henrik...I definitely *will* use what you've done here (though if I'm blunt, there's some digesting to do!), but for the first run, I'm scaling everything back (just to get all my HPWM config/timers/program sorted before bringing in the larger number!) ...ie 16 bit accumulator for the first run!

  34. #34
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,802


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by HenrikOlsson View Post
    Code:
    Frequency VAR WORD
    Temp VAR WORD
    
    Frequency = 49712 ' 4971.2Hz
    Temp = Frequency * 21475 ' Produce the 32bit intermediate result
    AddH = R0 ' Get high word from R0
    AddL = R2 ' and low word from R2
    Gosub PrintIt ' Display it
    
    Pause 100
    END
    
    PrintIt:
    HSEROUT["Frequency: ", DEC Frequency/10, ".", DEC Frequency//10, " AddValue: ", DEC AddH, " , ", DEC AddL,13] 
    RETURN
    If there are interrups involved, maybe it is a good idea to disable just before the routine, so R0 and R2 are not messed up.

    Ioannis

  35. #35
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by Ioannis View Post
    If there are interrups involved, maybe it is a good idea to disable just before the routine, so R0 and R2 are not messed up.

    Ioannis
    From my limited understanding...the whole premise of generating waveforms via DDS is to get in & get out the interrupt routine as fast as possible before the next interrupt arrives (else it all fails badly)...in such an instance, I'd say it'd be better to keep the timer interrupt running all the time (since they're be overhead, however small wrt stopping the interrupts)

    ok, I slapped the most basic (1 pole) filter with a corner frequency set at about 10khz on the HPWM pin, here's 500Hz...



    a bit of noise (could probably do with another filter pole).

    Need to have a bit more play

    Code to date...
    Code:
    @ __CONFIG _CONFIG1, _FCMEN_OFF & _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOREN_OFF & _PWRTE_OFF & _LVP_OFF
    @ __CONFIG _CONFIG2, _LVP_OFF
    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    Osccon = %01111010   'sets the internal oscillator to 16Mhz
    DEFINE  OSC 16
    TrisC.5 = 0     'Pin2 (HPWM) an output     
    CM1CON0 = 0   ' COMPARATORS OFF
    CM2CON0 = 0   ' COMPARATORS OFF
    tuning_word         VAR word
    accumulator         VAR WORD
    out                 VAR BYTE
    'HPWM SETTINGS uses timer 2
    CCP1CON  = %00001100     'Turn HPWM on on CCP1
    CCPR1L.6 = 0             'only using 8 bit PWM so clear the top two bits 
    CCPR1L.7 = 0             'only using 8 bit PWM so clear the top two bits
    PR2 = 79                'this PWM frequency of  50khzKHz allows a maximum of 320 values
    T2CON = %00000100        'TIMER2 ON 1:1 PRESCALER 1:1 POSTSCALER
     
    ' setsup an interrupt based on Timer4 overflowing (timer4 will overflow at 20,000 times per second, see further)
    ASM
    INT_LIST  macro ; IntSource,    Label,         Type, ResetFlag?
        INT_Handler  TMR4_INT,  _DDS,  asm,  YES
        endm
        INT_CREATE       ; Creates the interrupt processor
    ENDASM
    T4CON.2 = 1     ' Timer4 on
    PR4 =  199      ' this should yield an exact 'interrupt rate of 20khz' at 16Mhz.
    ACCUMULATOR = 0          ' clear down the accumulator before starting.
    @ INT_ENABLE TMR4_INT
    TUNING_WORD = 1638 ' this sets the required output frequency (tuning_word value = req_freq/20,000 * 65536)  1638 = 500hz
    'CCP1CON.4 = Test.0       'Bit 0
    'CCP1CON.5 = Test.1       'Bit 1
    'CCPR1L    = Test >> 2    'Bit 2-7
    Main:
        pause 1
        goto main
    END
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    DDS:
    'toggle PortA.5
    ACCUMULATOR = ACCUMULATOR + tuning_word
    ' ok, lookup the high byte of the accumulator....
    Lookup Accumulator.HighBYTE, [$80,$83,$86,$89,$8C,$8F,$92,$95,$98,$9C,$9F,$A2,$A5,$A8,$AB,$AE,$B0,$B3,$B6,$B9,$BC,$BF,$C1,$C4,_
    $C7,$C9,$CC,$CE,$D1,$D3,$D5,$D8,$DA,$DC,$DE,$E0,$E2,$E4,$E6,$E8,$EA,$EC,$ED,$EF,$F0,$F2,$F3,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FC, _
    $FD,$FE,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FE,$FD,$FC,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F3,$F2,$F0,$EF,$ED,$EC, _
    $EA,$E8,$E6,$E4,$E2,$E0,$DE,$DC,$DA,$D8,$D5,$D3,$D1,$CE,$CC,$C9,$C7,$C4,$C1,$BF,$BC,$B9,$B6,$B3,$B0,$AE,$AB,$A8,$A5,$A2,$9F,$9C, _
    $98,$95,$92,$8F,$8C,$89,$86,$83,$7F,$7C,$79,$76,$73,$70,$6D,$6A,$67,$63,$60,$5D,$5A,$57,$54,$51,$4F,$4C,$49,$46,$43,$40,$3E,$3B, _
    $38,$36,$33,$31,$2E,$2C,$2A,$27,$25,$23,$21,$1F,$1D,$1B,$19,$17,$15,$13,$12,$10,$0F,$0D,$0C,$0A,$09,$08,$07,$06,$05,$04,$03,$03, _
    $02,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$02,$03,$03,$04,$05,$06,$07,$08,$09,$0A,$0C,$0D,$0F,$10,$12,$13, _
    $15,$17,$19,$1B,$1D,$1F,$21,$23,$25,$27,$2A,$2C,$2E,$31,$33,$36,$38,$3B,$3E,$40,$43,$46,$49,$4C,$4F,$51,$54,$57,$5A,$5D,$60,$63, _
    $67,$6A,$6D,$70,$73,$76,$79,$7C],Out
    ' now use that 'Out' value to change HPWM. duty cycle...
    CCP1CON.4 = Out.0       'Bit 0
    CCP1CON.5 = Out.1       'Bit 1
    CCPR1L    = Out >> 2    'Bit 2-7
    @ INT_RETURN
    Last edited by HankMcSpank; - 27th August 2011 at 15:03.

  36. #36
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,802


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    If your interrupt routine does not touch the R0 and R2 variables just ignore my note.

    Your signal looks good. A better filter is a must for cleaner sin wave, I agree.

    Ioannis

  37. #37
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Ionnis, that's a very good point!
    However, if DT-Ints are used it saves and restores those variables so I don't think there's any risk of corrupting them if an interrupt occurs during the calculation phase. (?)

    If using ON INTERRUPT then you should definitely disable interrupts (or interrupt checking rather) during that calculation operation.

    Hank, what you say is true but Ioannis has a point here. The R0/R2 variables are internal PBB variables used by a host of commands. If you're in the middle of that 32bit calculations and an interrupt comes along it's very likely that the code in the ISR uses those same variables (R0 and R2) so when you return the value previosuly there is now gone and you end up with weird results.

    But like I said, the whole DT-Ints concept builds on saving the PBP system variables on ISR entry and restoring them on exit (if the handler is defined as PBP-handler) so I don't think it's going to be a problem.

    Anyway, that calculation should only be executed when the frequency is changing so even if you SHOULD need to disable interrupts it won't make much difference.

    /Henrik.

    EDIT: Oooh, Hank, I think you're in for some trouble in the long run..... You have your handler defined as ASM yet we're doing a host of "PBP-work" in the handler. If you're not very carefull and know exactly what you're doing that is a very likely cause for trouble and data corruption due what is described above. Either write the handler in ASM or define as it type PBP and include the Re-Enter file.

    EDIT2: Currently it might not be a problem since you're not doing anything in the main loop but as soon as you start doing things there it's going to go havoc.
    Last edited by HenrikOlsson; - 27th August 2011 at 15:14.

  38. #38
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,802


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by HenrikOlsson View Post
    Anyway, that calculation should only be executed when the frequency is changing so even if you SHOULD need to disable interrupts it won't make much difference.
    At 32Mhz no one will notice

    Ioannis

  39. #39
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Quote Originally Posted by HenrikOlsson View Post
    EDIT: Oooh, Hank, I think you're in for some trouble in the long run..... You have your handler defined as ASM yet we're doing a host of "PBP-work" in the handler. If you're not very carefull and know exactly what you're doing that is a very likely cause for trouble and data corruption due what is described above. Either write the handler in ASM or define as it type PBP and include the Re-Enter file.

    EDIT2: Currently it might not be a problem since you're not doing anything in the main loop but as soon as you start doing things there it's going to go havoc.
    Good spot (cut & paste from another program + laziness!) - now changed.

    The frequency is very easy to set though (presently I work out the tuning word value by way of a simple spreadsheet!)

    Higher frequencies look ugly as sin (I even cranked the interrupt rate up - not much better) ...maybe it's just the simple filter I used ....hmm, not sure that PWM is gonna be the solution here (as expected the signal amplitude is related to frequency eg 400hz about 4V peak to peak but 4000hz circa 3.5V peak to peak, it'll be worse with a two pole filter) ...it looks like an R2R ladder is going to be the way forward...damnit!
    Last edited by HankMcSpank; - 27th August 2011 at 15:26.

  40. #40
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: DDS (generating sine waves) with onboard DAC using latest PIC 16F chips?

    Hi Hank,
    There might be also a problem with the code I posted. This is new territory for me as well.

    I think that the PWM is one part of the problem, do try it with a R2R resistor DAC on a port and see what happens?

    However, don't forget how this works.... The lookup table is 256 entries long. At 500Hz output frequency you would need an interrupt rate of 500*256=128kHz to "hit" every entry in the table (thus producing the highest possible quality output). As the frequency goes up more and more of the table entries are skipped, you might "hit" entry 5, 75, 145, 205, 29, 9, 169, 239, 53, 123,193, 7 and so on. Plotting those values and drawing a straight line between them isn't going to produce a very pretty sine-wave.

    I suck at filter desing and analog stuff (too) so I can't help much with the filter desing.

    /Henrik.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts