Help with DDS and PWM

Go To Last Post
86 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Get it to sweep the frequency. Then marvel in the magic of dds!

The waveform gets more ragged the higher in frequency you go.

Last Edited: Thu. Jul 11, 2019 - 02:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is not a filter fault ! 

If a filter makes it better it's because it blur the sw error.

Find the error first. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm experiencing a little jitter with higher frequencies. I have a 1.2khz pwm frequency using internal prescaler (/8 prescaler). Clock is a 20Mhz crystal mounted in the crystal socket of STK500. from 50/60hz onwards, the resulting sine starts to get some jitter

 

Setup photo

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your filter values are too low - this is loading the output too much. You can see this in the scope trace of the pwm.

Nevertheless, with dds, as the ratio of the output freq gets closer to the sample freq the ‘quality’ of the waveform gets worse. This is because you have larger jumps through your sine table. Eg: 1200Hz sample, 50Hz output is a ratio of 24:1. This means you skip, say, every 10 samples in the sinetable. Depending on the integer roundup of the dds calc, cycle to cycle you use different samples. By tweeking the phase-inc value slightly, you can see the effect this has on the ‘glitching’. This is an artifact of a sampled time system. You should be able to simulate all of this on your PC using matlab or the likes thereof.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd be curious to see the code that's producing the waveform in #54.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Changed filter values, now output stage is less loaded. However waves still are a little "jumpy" at higher frequencies. I tried to "fix" this lowering crystal to 10Mhz and getting back prescaler to 1. That gives 4Khz PWM, but the problem persists...

I don't remember to have this problem with 8 bit PWM. I will give it a try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the isr, copy bit 31 of the phase_acc to a port pin. Trigger off that. See if you still get jitter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
In the isr, copy bit 31 of the phase_acc to a port pin. Trigger off that. See if you still get jitter.

If this code does that

ISR(TIMER1_COMPA_vect)
{
  	static uint32_t phase_acc = 0;
	phase_acc += phase_inc;
	OCR1A= sine[phase_acc>>24]/gain;
	PORTD=(phase_acc>>24);
	//counter++;
}

(with probe connected at PORTD7) Jitter is less, but still present.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How much jitter? Engineers talk in numbers. Is the jitter in the output waveform or in the PORTD.7 signal?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is this number difference between pulse widths? Now I'm with 20Mhz back, 10bit normal PWM, and /8 prescaler.

I have PORTD.7 pulses of 3.2ms, 3.60ms, 3.7ms, so 0.5ms of jitter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're going to have to do some detective work. 500us is how many pwm periods? It is unlikely the pwm hardware is missing ticks, so that might suggest that you're missing interrupts.  Toggle a port pin in your isr and see if you're missing interrupts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ColdfireMC wrote:

ISR(TIMER1_COMPA_vect)
{
  	static uint32_t phase_acc = 0;
	phase_acc += phase_inc;
	OCR1A= sine[phase_acc>>24]/gain;
	PORTD=(phase_acc>>24);
	//counter++;
}

 

The jitter is perhaps caused by the ISR triggering

on COMPA which is not constant.  You want to use

a regular interval such as overflow (OVF) or COMPB

(set to a single value) for this routine.

 

Also, calculate the next value after updating the

current value like this:

 

ISR(TIMER1_COMPB_vect) {
    static uint32_t phase_acc = 0;
    static uint16_t next_output = 0;

    OCR1A = next_output; // jitter-B-gone!

    phase_acc += phase_inc;
    next_output = sine[phase_acc>>24]/gain;
}

 

This introduces a delay in your output by one sample

period.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nice catch Mike! I didn't spot that one. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

done. Jitter went down, however is still present (480us). I have some doubts about what mode of pwm is the correct.

 

void pwm_setup(void)
{
        TIMSK1=(1<<OCIE1A);
	TCCR1A |= (1 << COM1A1);
	TCCR1A |= (1 << WGM11) | (1 << WGM10);
	TCCR1B |= (0 << CS10) | (1 << CS11) | (0 << CS12) | (0 << WGM13) | (1 << WGM12);
}

This supposedly is PWM 10 bit phase correct, /8 prescaler, output compare mode (mode 7). Now i'm generating the interrupt using the output compare. Is this the recommended way to do it, or there's some other way to do it?
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You’re still using compare A for the interrupt source. Use the ovf (overflow) interrupt. The reason is the interrupt is generated at a consistent point in the pwm cycle. When you were using compa this would interrupt at a variable point in the pwm cycle dependent on the actual pwm value. The other (potential) issue is the update of the pwm value. By the time the interrupt fires and you enter the isr, your code executes and updates the ocr1a value. Depending on the window of opportunity, you might miss updating the pwm on the next cycle. So the point hat Mike makes is to update the ocr1a value early in the isr. The other point Mike makes is you can use ocr1b to fire an interrupt at a point in the pwm cycle to ensure you update ocr1a at the required time.

Now - don’t do this all at once as you’ll tie yourself up in knots if it doesn’t work as planned. First just change your code to use timer1_ovf. Change the isr vector name and the timer interrupt enable bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mode 7 is 10-bit Fast PWM.  OCR1x is buffered so

changes happen at the right moment (BOTTOM).

 

For a nice smooth output waveform, you need to

update OCR1A exactly once per timer period. It

looks like you're still using the COMPA interrupt

to make changes to the OCR1A value.  This isn't

a good idea because if OCR1A is near to the TOP

value, your interrupt might not update OCR1A to

the next output value quickly enough.  Better to

use the overflow or COMPB interrupt (with a low

enough value) to ensure OCR1A is updated before

the timer wraps around.

 

--Mike

 

EDIT: Too slow!

 

Last Edited: Fri. Jul 12, 2019 - 09:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And I’d just woken up!!!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ISR(TIMER1_OVF_vect)
{
	static uint16_t next_reg = 0;
	static uint32_t phase_acc = 0;

	OCR1A=next_reg;
	phase_acc += phase_inc;
	next_reg=sine[phase_acc>>24]/gain;
	PORTD=(phase_acc>>24);
	//counter++;
}

ISR changed. At some frequencies almost dissapear, but from 60hz onwards is present. I'm triggering using the 31st bit as trigger.

 

void pwm_setup(void)
{
	//TIMSK1=(1<<OCIE1A);
	TIMSK1=(1<<TOIE1);
	TCCR1A |= (1 << COM1A1);
	TCCR1A |= (1 << WGM11) | (1 << WGM10);
	TCCR1B |= (0 << CS10) | ( 1 << CS11) | (0 << CS12) | (0 << WGM13) | (0 << WGM12);
}

 

 

This is PORTB7. The narrowest pulse is 480us, the widest is 580us. 93Hz

 

Last Edited: Sat. Jul 13, 2019 - 12:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take out the gain division for the moment. On an AVR divides are expensive, so for gain you would multiply as the AVR has multiply hardware then divide by shifting right a multiple of 8 bits.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EDIT: I was wrong in measurements

Well, I not have the 210 here, but the jitter is visible. Every 2 seconds, waveform jitters 0.8ms, something like that. Retired division from code. No code is executing in main loop. 93 hz again. With a 16bit phase accumulator Jitter can be less?

Last Edited: Sat. Jul 13, 2019 - 09:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if you have 93Hz, then your scope scale that your showing must be 2ms/division

You probably can't really see 50us jitter on a 2ms scale...that would only be 1/40 of one square!

 

What are you triggering on?  If the wave is jagged, each sweep it can trigger at a slightly different point 

 

 Every 2 seconds, waveform jitters 50us  

 How would you know that using the scope as shown?

 

I'm not saying you don't have jitter, i'm saying it can be hard to measure & you can fool yourself.   If you have a known solid reference (to trigger recording each repetition) that makes it easier, but that assumes the reference is jitter-free

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ColdfireMC wrote:

Every 2 seconds, waveform jitters 50us

 

Probably due to dropping the lower 24 bits of phase_acc.

 

Ideally you'd use those bits to interpolate the sample

output between the surrounding two values.  Linear

interpolation is straightforward to implement, but

does require some time to calculate.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

or tweek the phase increment.

 

If the end use for this is to drive an induction motor, then 50us is trivial.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have I lost the plot?
The OP just wants to create a 50Hz sine wave using PWM and low pass filter.
Surely this is one lookup table with about 20 lines of code for the software.
And one RC for the low pass filter hardware.
How do you get 74 messages?
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
How do you get 74 messages?
.

 

Some need a little more help than others......

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

please show the code you use (inclusive, sine-table and how you make the trigger signal).(any other ISR's enabled?, empty main ? how "empty" :) )

 

How long does the ISR take, set a port pin as first and last thing in the ISR (which optimizer level do you use ? -O2 )

If speed really matter then place the two static variables in registers that should at least speed it up with a factor of 2 (in ASM the hole ISR would take about 20 clk so 1us) 

 

I fear that you still have some sw errors, so my comment in #53 still count, I fear that you just blur a bad signal with a filter.

 

I have not read the datasheet for this setup, but are you sure that when you do :

OCR1A=next_reg;

that the timer haven't passed the switch value ? (if it's buffered it's not at problem!).

 

 

a note to David, I think OP have at lot to learn, at I hope he will learn some from this thread.

If it's just was 50Hz sinewave it would take me less than an hour to code (I would do this kind of stuff in ASM, HW close things are easier that way), but it could easy take hours to understand the settings of PWM and timers etc. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I second the call to see the full software listing.  Right now we are all just looking at different parts of the elephant.  It's not even clear to me that the jitter being reported is real, as opposed to an artifact of the triggering scheme.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <math.h>
#include <util/delay.h>
#include <stdint.h>
#define F_CPU 20000000UL
#define DEFAULT_STEP 1
#define DEFAULT_INC 65535UL*10000UL
volatile uint32_t phase_inc=DEFAULT_INC;
volatile uint8_t gain=1;
void pwm_setup(void);
void timer_setup(void);
uint32_t get_tick_count(void);

const __flash uint16_t sine[256]={511, 524, 536, 549, 561, 574, 586, 599, 611, 623, 635, 648, 660, 672, 683, 695, 707, 718, 730, 741, 752, 763, 774, 785, 795, 806, 816, 826, 836, 845, 855,
    864, 873, 882, 890, 899, 907, 915, 922, 930, 937, 944, 950, 956, 963, 968, 974, 979, 984, 989, 993, 997, 1001, 1004, 1008, 1011, 1013, 1015, 1017, 1019, 1021, 1022, 1022, 1023, 1023,
    1023, 1022, 1022, 1021, 1019, 1017, 1015, 1013, 1011, 1008, 1004, 1001, 997, 993, 989, 984, 979, 974, 968, 963, 956, 950, 944, 937, 930, 922, 915, 907, 899, 890, 882, 873, 864, 855,
    845, 836, 826, 816, 806, 795, 785, 774, 763, 752, 741, 730, 718, 707, 695, 683, 672, 660, 648, 635, 623, 611, 599, 586, 574, 561, 549, 536, 524, 512, 499, 487, 474, 462, 449, 437,
    424, 412, 400, 388, 375, 363, 351, 340, 328, 316, 305, 293, 282, 271, 260, 249, 238, 228, 217, 207, 197, 187, 178, 168, 159, 150, 141, 133, 124, 116, 108, 101, 93, 86, 79, 73, 67,
    60, 55, 49, 44, 39, 34, 30, 26, 22, 19, 15, 12, 10, 8, 6, 4, 2, 1, 1, 0, 0, 0, 1, 1, 2, 4, 6, 8, 10, 12, 15, 19, 22, 26, 30, 34, 39, 44, 49, 55, 60, 67, 73, 79, 86, 93, 101, 108,
    116, 124, 133, 141, 150, 159, 168, 178, 187, 197, 207, 217, 228, 238, 249, 260, 271, 282, 293, 305, 316, 328, 340, 351, 363, 375, 388, 400, 412, 424, 437, 449, 462, 474, 487, 499};
/*
const uint8_t sine[256]={127, 130, 133, 136, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 187, 190, 193, 195, 198, 201, 203, 206, 208, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 233, 235, 237, 238, 240, 241, 243, 244, 245, 246, 248, 249, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 249, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 233, 232, 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, 195, 193, 190, 187, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 143, 140, 136, 133, 130, 128, 125, 122, 119, 115, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 70, 68, 65, 62, 60, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, 27, 25, 23, 22, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, 20, 22, 23, 25, 27, 29, 31, 33, 35, 37, 40, 42, 44, 47, 49, 52, 54, 57, 60, 62, 65, 68, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 119, 122, 125};
*/
int main(void)
{
    OCR1A=0;
    //DDRC|=0xFF;
    DDRD|=0xFF;
    DDRB|=0xFF;
    
    OCR1A=1;
    pwm_setup();
    timer_setup();
    PORTB=0;
    sei();
    PORTD=0;
    while (1)
    
    {
        
        
        //if (poll_key==1)
        //{
        //checkbutton();
        //}
        
        //empty
        //counter_main=get_tick_count(); (4294967296-1)/4)
    }
    return 0;
}

ISR(TIMER1_OVF_vect)
{
    static uint16_t next_reg = 0;
    static uint32_t phase_acc = 0;
    
    OCR1A=next_reg;
    phase_acc += phase_inc;
    next_reg=sine[phase_acc>>24];
    //PORTD=(phase_acc>>24);
    //PORTD=next_reg;
    //counter++;
}

void timer_setup(void)
{
    //TIMSK0=(1<<OCIE0A);
    TCCR0A |= (1 << COM1A1);
    TCCR0A |= (1 << WGM11) | (0 << WGM00) | (1<<COM0A0) | (0<<COM1A0);
    TCCR0B |= (0 << CS10) | (0 << CS11) | (1 << CS12) | (0 << WGM02);
    OCR0A=16;
    //    OCR0B=64;
}
void pwm_setup(void)
{
    //TIMSK1=(1<<OCIE1A);
    TIMSK1=(1<<TOIE1);
    TCCR1A |= (1 << COM1A1);
    TCCR1A |= (1 << WGM11) | (1 << WGM10);
    TCCR1B |= (0 << CS10) | ( 1 << CS11) | (0 << CS12) | (0 << WGM13) | (0 << WGM12);
}

The current code. Supposedly, TIMER0 is initialized, but no interrupt is enabled. Now I'm using O3, release option.

 

Kartman wrote:

or tweek the phase increment.

 

If the end use for this is to drive an induction motor, then 50us is trivial.

That was the question.

 

avrcandies wrote:

if you have 93Hz, then your scope scale that your showing must be 2ms/division

You probably can't really see 50us jitter on a 2ms scale...that would only be 1/40 of one square!

 

What are you triggering on?  If the wave is jagged, each sweep it can trigger at a slightly different point 

 

 Every 2 seconds, waveform jitters 50us  

 How would you know that using the scope as shown?

 

I'm not saying you don't have jitter, i'm saying it can be hard to measure & you can fool yourself.   If you have a known solid reference (to trigger recording each repetition) that makes it easier, but that assumes the reference is jitter-free

 

I was wrong, corrected.

Last Edited: Sat. Jul 13, 2019 - 09:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Have I lost the plot? The OP just wants to create a 50Hz sine wave using PWM and low pass filter. Surely this is one lookup table with about 20 lines of code for the software. And one RC for the low pass filter hardware. How do you get 74 messages? . David.

Sine appears now. I knew that the code would be short, but has to be the correct code.

Last Edited: Sat. Jul 13, 2019 - 10:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was wrong, corrected.

This seems a bit obtuse--how can we know what you mean...wrong about what?  What was corrected? Do you mean you no longer see jitter?  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

I was wrong, corrected.

This seems a bit obtuse--how can we know what you mean...wrong about what?  What was corrected? Do you mean you no longer see jitter?  

I edited that post. I was worng aobutr 50us. Added the "I think" correct measurement. The bit 31 of the Phase accumulator jitters. I'm using that as external trigger and sine wave.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I edited that post. I was worng aobutr 50us. Added the "I think" correct measurement. The bit 31 of the Phase accumulator jitters. I'm using that as external trigger and sine wave.

Ok, now why do you think you see jitter?  What are you triggering off of as a reference?  Can you capture several cycles that clearly shows it?  If you capture 4 cycles at a time , you may get lucky (after a few tries) to capture one that is different and be able to see what is going on.

 

If you listen to your sinewave, do you hear anything going wrong? 

 

I wonder if you get a rounding "residual"  when you shift by 24 bits...maybe round up 

 

You say you have 93Hz with 0.8ms jitter??...that's 26.8 degrees variation?

 

Before you even try making a sine, ensure your IRQ is rock solid...each IRQ toggle a pin & check the toggling.  You can squeeze a bunch of toggles on the scope screen & see if any look out of place.

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. Jul 14, 2019 - 01:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Change 65535 to 65536 to remove some jitter.

 

Also, the update of OCR1A is buffered, but the

write to PORTD is not, so they are out of sync.

 

Not sure you can do any better, though maybe

write the "old" PORTD value just after setting

OCR1A (before incrementing phase_acc).

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have put a speaker, without filter, just with decoupling cap. Obviously tons of harmonic noise, over the fundamental, but I thin that it hears stable.

 

This is using no prescaler. Switch frequency here is high so I will not use it with those settings

 

https://1drv.ms/u/s!AjVt5WQyiI6mgq5zY4fSlDmvYvB3pQ

 

 

Here's the current code (93 Hz, prescaler /8), buffered PORTD)

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <math.h>
#include <util/delay.h>
#include <stdint.h>
#define F_CPU 20000000UL
#define DEFAULT_STEP 1
#define DEFAULT_INC 65536UL*5000UL
volatile uint32_t phase_inc=DEFAULT_INC;
volatile uint8_t gain=1;
void pwm_setup(void);
void timer_setup(void);
uint32_t get_tick_count(void);

const __flash uint16_t sine[256]={511, 524, 536, 549, 561, 574, 586, 599, 611, 623, 635, 648, 660, 672, 683, 695, 707, 718, 730, 741, 752, 763, 774, 785, 795, 806, 816, 826, 836, 845, 855,
	864, 873, 882, 890, 899, 907, 915, 922, 930, 937, 944, 950, 956, 963, 968, 974, 979, 984, 989, 993, 997, 1001, 1004, 1008, 1011, 1013, 1015, 1017, 1019, 1021, 1022, 1022, 1023, 1023,
	1023, 1022, 1022, 1021, 1019, 1017, 1015, 1013, 1011, 1008, 1004, 1001, 997, 993, 989, 984, 979, 974, 968, 963, 956, 950, 944, 937, 930, 922, 915, 907, 899, 890, 882, 873, 864, 855,
	845, 836, 826, 816, 806, 795, 785, 774, 763, 752, 741, 730, 718, 707, 695, 683, 672, 660, 648, 635, 623, 611, 599, 586, 574, 561, 549, 536, 524, 512, 499, 487, 474, 462, 449, 437,
	424, 412, 400, 388, 375, 363, 351, 340, 328, 316, 305, 293, 282, 271, 260, 249, 238, 228, 217, 207, 197, 187, 178, 168, 159, 150, 141, 133, 124, 116, 108, 101, 93, 86, 79, 73, 67,
	60, 55, 49, 44, 39, 34, 30, 26, 22, 19, 15, 12, 10, 8, 6, 4, 2, 1, 1, 0, 0, 0, 1, 1, 2, 4, 6, 8, 10, 12, 15, 19, 22, 26, 30, 34, 39, 44, 49, 55, 60, 67, 73, 79, 86, 93, 101, 108,
    116, 124, 133, 141, 150, 159, 168, 178, 187, 197, 207, 217, 228, 238, 249, 260, 271, 282, 293, 305, 316, 328, 340, 351, 363, 375, 388, 400, 412, 424, 437, 449, 462, 474, 487, 499};
/*
const uint8_t sine[256]={127, 130, 133, 136, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 187, 190, 193, 195, 198, 201, 203, 206, 208, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 233, 235, 237, 238, 240, 241, 243, 244, 245, 246, 248, 249, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 249, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 233, 232, 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, 195, 193, 190, 187, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 143, 140, 136, 133, 130, 128, 125, 122, 119, 115, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 70, 68, 65, 62, 60, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, 27, 25, 23, 22, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, 20, 22, 23, 25, 27, 29, 31, 33, 35, 37, 40, 42, 44, 47, 49, 52, 54, 57, 60, 62, 65, 68, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 119, 122, 125};
*/
int main(void)
{
	OCR1A=0;
	//DDRC|=0xFF;
	DDRD|=0xFF;
	DDRB|=0xFF;
	
	OCR1A=1;
	pwm_setup();
	timer_setup();
	PORTB=0;
	sei();
	PORTD=0;
	while (1)
	
	{
		
		
		//if (poll_key==1)
		//{
		//checkbutton();
		//}
		
		//empty
		//counter_main=get_tick_count(); (4294967296-1)/4)
	}
	return 0;
}


ISR(TIMER1_OVF_vect)
{
	static uint16_t next_reg = 0;
	static uint32_t phase_acc = 0;
	static uint8_t next_port_out = 0;
	
	OCR1A=next_reg;
	PORTD=next_port_out;
	phase_acc += phase_inc;
	next_reg=sine[phase_acc>>24];
	next_port_out=(phase_acc>>24);
	//PORTD=next_reg;
	//counter++;
}

void timer_setup(void)
{
	//TIMSK0=(1<<OCIE0A);
	TCCR0A |= (1 << COM1A1);
	TCCR0A |= (1 << WGM11) | (0 << WGM00) | (1<<COM0A0) | (0<<COM1A0);
	TCCR0B |= (0 << CS10) | (0 << CS11) | (1 << CS12) | (0 << WGM02);
	OCR0A=16;
	//	OCR0B=64;
}
void pwm_setup(void)
{
	//TIMSK1=(1<<OCIE1A);
	TIMSK1=(1<<TOIE1);
	TCCR1A |= (1 << COM1A1);
	TCCR1A |= (1 << WGM11) | (1 << WGM10);
	TCCR1B |= (0 << CS10) | ( 1 << CS11) | (0 << CS12) | (0 << WGM13) | (0 << WGM12);
}

 

Last Edited: Mon. Jul 15, 2019 - 04:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have put a speaker, without filter, just with decoupling ca

 

What exactly are you talking about???!!  Didn't it have an amplifier like some old computer speakers or your stereo? 

 

You are trying to examine/verify (listen to) the filtered output for any problems!!  

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Jul 15, 2019 - 04:23 AM

Pages