CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Harmonic Distortion in PIC16F1783

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
danielz85



Joined: 22 Sep 2012
Posts: 37

View user's profile Send private message

Harmonic Distortion in PIC16F1783
PostPosted: Wed Jan 02, 2013 3:35 am     Reply with quote

Hi,

I'm trying to produce an 18kHz pure sine wave using an LUT and the PIC's DAC.

I first create an array which holds the the required LUT values, and then I setup timer2 to interrupt every 50cc @32Mhz (160kHz).

When I sample the output, besides seeing the desired 18kHz frequency I also witness 9Khz "harmonic" (harmonics are usually above the original frequency)

Any ideas why this happens and how I can fix this?
Thanks,
Daniel


Code:
#include <16F1783.h>
#byte DACCON1=getenv("SFR:DACCON1")
//#INCLUDE <stdlib.h>
#include "consts.c"
#fuses INTRC_IO, NOWDT, NOBROWNOUT, PUT,NOMCLR
#use delay(clock=32M)
#use rs232(baud=4800,xmit=pin_B7,rcv=pin_B6)
#define Ns 400


int16 index=0;
const int wave[Ns] = {128,205,235,224,......}


//-----------------------------------------------------------------------



#INT_TIMER2
void timer2_ISR()
{
   dac_write(wave[index]);
   //printf("%u,"wave[index]);
   index++;
   if (index==Ns)
      index=0;
     
}

void main()
{
  setup_timer_2(T2_DIV_BY_1,50,1);
  enable_interrupts(INT_TIMER2);
  setup_dac(DAC_VSS_FVR | DAC_OUTPUT1);
  setup_vref(VREF_ON | VREF_COMP_DAC_2v048);
  set_timer2(0);
  enable_interrupts(GLOBAL);
   
  while (1)
  {
     
     
  } 
   

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19544

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 3:59 am     Reply with quote

Seriously, you can't call an interrupt handler every fifty cycles.
It takes typically about 60 cycles to get into and out of an interrupt handler.... The lookup to read a value from the table will take about twenty+ cycles as well.
You are just running out of processor time.
Potentially, if you used int_global, rather than the generic interrupt handling code, you could get 'close', but it'd still be right at the limit for the chip.
Do the work in your main loop instead, but realise the chip won't be able to do anything else. So:
Code:

#include <16F1783.h>
#include "consts.c"
#fuses INTRC_IO, NOWDT, NOBROWNOUT, PUT,NOMCLR
#use delay(clock=32M)
#use rs232(baud=4800,xmit=pin_B7,rcv=pin_B6)
#define Ns 400

int16 index=0;
const int wave[Ns] = {128,205,235,224,......}

void main(void) {
  int8 val_from_table=128;
  setup_timer_2(T2_DIV_BY_1,50,1);
  enable_interrupts(INT_TIMER2);
  setup_dac(DAC_VSS_FVR | DAC_OUTPUT1);
  setup_vref(VREF_ON | VREF_COMP_DAC_2v048);
  set_timer2(0);
 
  while (TRUE)  {
     if (interrupt_active(INT_TIMER2) {
        //interrupt has triggered
        clear_interrupt(INT_TIMER2);
        dac_write(val_from_table);
        index++;
        if (index==Ns)
           index=0;
        val_from_table=wave[index]; //get the next value
     }     
  } 
}

It is still going to be absolutely 'borderline'. Doing a lookup from a 400 element table, implies page switching. Since this is slow, I'm doing it after writing the DAC value, and hopefully this can be done before the interrupt triggers again.

Best Wishes
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 4:12 am     Reply with quote

No digital system can ever produce a "pure" sine wave. Sine waves are continuously varying and cannot be precisely reproduced by sampled systems, nor by quantised systems, and certainly not by sampled & quantised systems. All we can do is go for a close enough approximation to a sinusoidal wave. "Close enough" depending in the application.

The "harmonics" are an essential feature of the quantisation and sampling, and will be there no matter how small the quanta and how fast the sampling. In practice, for any given application, you may be able to find a quanta that's "small enough" and sample rate that's "fast enough" not to have any significant practical effect.

The standard solution is to use analogue filtering after the DAC to attenuate the sampling frequency and its harmonics, but you can never totally remove them. Commonly a low-pass filter designed to give adequate rejection at the sample frequency and above is the normal solution. What "adequate" means is dependant on your application. For example, the human ear is pretty good at detecting even low-level harmonics for fundamentals below a few KHz.

So, you probably need to do some analogue engineering.

RF Developer
Ttelmah



Joined: 11 Mar 2010
Posts: 19544

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 4:21 am     Reply with quote

Agreed.
However he is not seeing 'harmonics' at all (his naming is wrong), but sub frequency artifacts caused by the beating between what the processor can achieve, and the actual time allowed between interrupts.
Every few interrupts, one is getting skipped, since there simply isn't time to complete the task, hence the lower frequency beat.

Best Wishes
danielz85



Joined: 22 Sep 2012
Posts: 37

View user's profile Send private message

PostPosted: Wed Jan 02, 2013 4:36 am     Reply with quote

sub frequency artifacts is the word I was looking for... that's why I put harmonics in quotes.

Thanks, again for the info, I knew it took some time switching to the ISR, I didn't think it was THAT long...

I'll give it a try, and as RF_Developer said, I will put an analogue LPF at the DAC's output.

see where this all gets me...
Thanks as always
Daniel
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group