Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Output two different sine waves with 16F88 and CCS C?

Status
Not open for further replies.
When you switch to the 20MHz crystal you need to increase the value in PR2 from 124 to 249 so that the interrupts still happen every 200uS.

Mike.
 
Right, I double the prescaler to fit the 20MHz frequency, but then with 10MHz crystal the values are still wrong though, why is that?

It worked fine with 8MHz, and it seems 20MHz is dead on, yet with 10MHz it's all off?

And what about the LED flashing part, is that still correct for the 64 value sine table?

Thanks.
 
Last edited:
3dluvr said:
Right, I double the prescaler to fit the 20MHz frequency, but then with 10MHz crystal the values are still wrong though, why is that?

It worked fine with 8MHz, and it seems 20MHz is dead on, yet with 10MHz it's all off?
I think your getting confused as we changed both the crystal frequency and the output frequency.

When we were using 8MHz and 500us (2KHz) then timer 2 was,
setup_timer_2(T2_DIV_BY_4, 249, 1); // 500us = 1/8000000 * 4 * 4 * (249+1) = 1000 clock cycles

With 20MHz and 200uS (5KHz) it's
setup_timer_2(T2_DIV_BY_4, 249, 1); // 200us = 1/20000000 * 4 * 4 * (249+1) = 1000 clock cycles

With 10MHz and 200uS (5KHz) it's
setup_timer_2(T2_DIV_BY_4, 124, 1); // 200us = 1/10000000 * 4 * 4 * (124+1) = 500 clock cycles

And what about the LED flashing part, is that still correct for the 64 value sine table?

The LED is the same as it is on when the signals are out of phase.

Mike.
 
What I was referring to as being off is the factor used to compute the step parameter, N = F * factor

10MHz crystal would be:
factor = 200us * 32bit * 65536 possible values, 200*10e-6 * 32 * 65536

thus my step parameter formula equals
N = F * 419.43

for 200Hz that is 83886 and yet when I use that frequency on output frequency is actually ~80Hz.

Please tell me if my calculation is correct and if I'm doing something wrong for 10MHz so that output does not match the input?
 
Can you post your complete code as there are a few things that can effect frequency.

Mike.
 
Here's the code I use for 10MHz, I have commented out the PlayTone part since the dynamic frequency output is wrong anyway so makes no difference.

Code:
#include <16F88.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=10000000)

int timeCount;
long TempA, TempB, hundreths;
long long step, step2, position, position2;

CONST unsigned int SineTab[64] = {
    7,8,8,9,10,10,11,11
    12,12,13,13,13,14,14,14
    14,14,14,14,13,13,13,12
    12,11,11,10,10,9,8,8
    7,6,6,5,4,4,3,3
    2,2,1,1,1,0,0,0
    0,0,0,0,1,1,1,2
    2,3,3,4,4,5,6,6};
    
#INT_TIMER2
void interrupt(){
    position+=step;
    TempB=SineTab[(position>>16)&63];
    output_b(TempB);
    position2+=step2;
    TempA=SineTab[(position2>>16)&63];
    output_a(TempA);
    
    if((TempA&8)!=(TempB&8)){
        output_bit(PIN_A4, 1);
    }
    else{
        output_bit(PIN_A4, 0);
    }
    
    if(timeCount++ == 50){
        timeCount=0;
        hundreths++;
    }
}

void PlayTone(long long Freq1, long long Freq2, long Duration) {
    signed long long work;
    hundreths=0;
    While(hundreths<Duration) {
        if (Freq2 >= Freq1) { // ramp up
    	    work = Freq2 - Freq1;
    	    work *= hundreths;
    	    work /= Duration;
    	    step = work + Freq1; 
        } else { // ramp down
	    work = Freq1 - Freq2;
	    work *= hundreths;
    	    work /= Duration;
    	    step = Freq1 - work;    
        }
    }
}

void main(void) {
    setup_comparator(NC_NC_NC_NC);
    set_timer2(0);
    setup_timer_2(T2_DIV_BY_4, 124, 1); // 200us = (1/10000000 * 4 * 4 * 124+1)
	
    step = 88542; // dynamic frequency PortB 211.1Hz
    step2 = 83886; //167772; // static frequency PortA 200Hz
    enable_interrupts(INT_TIMER2);
    enable_interrupts(GLOBAL);    
	
    while(TRUE) {
        //PlayTone(88542,88542,500);
	//PlayTone(88542,86403,500);
	//PlayTone(86403,86403,500);
    	//PlayTone(86403,88542,500);
	delay_us(1);
    }
    disable_interrupts(INT_TIMER2);
}

Thanks.
 
You are still doing your calculations for a 32 entry sine table.

It should be 200*10^-6*64*65536

Which is 838.86

So for 200Hz the value would be 167772.

However, this does not explain you getting 80Hz, it should have been 100Hz. The only explanation I can think of is that somehow the internal oscillator is still being used. Could the external oscillator be faulty and the Fail safe clock monitor is switching to the internal oscillator?

Mike.
 
I use the same source code for the 20MHz clock with the change in the delay/oscillator and PR2, and that works fine when calculated.

Yet, for 10MHz it's all wrong, even with 64 instead of 32 I get values that are 1/3 or 1/2 of what they should be??

If the internal oscillator was kicking-in, wouldn't that affect the 20MHz setup as well?

I'll go look for another 10MHz crystal and try with it just to make sure it's not a hardware fault.
 
Well, I'm such a dope. All this time I have been using a 1MHz resonator instead of 10MHz one. I have no idea why I even read it as 10MHz when my other resonators (4 and 8MHz) had higher number than the one I called 10MHz.

In any case, I have found a real 10MHz crystal with a small footprint and will use that one, and it works just fine...

Next step is to see if I can script out session sequences or convert them the way they originally did in Perl, but adapted for my MCU.
 
PIC PWM is very very hard to use. Some time, I see people using software PWM instead of using the PIC hardware, so is the I2C and SPI on PICs.
 
Actually I wasn't using PWM because I needed two independent channels and most PICs have only one PWM. The original design was on an AVR which apparently has two PWM...figures.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top