Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

WAVEFORM GENERATION using PWM technique

Status
Not open for further replies.

SWETA

Newbie level 6
Newbie level 6
Joined
Apr 17, 2008
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,394
i wud b glad if anyboby cud help me in providin a solution 2 dis querry of mine..
m using ATmega 8L for making a function generator..dere m usin PWM technique for generatin sin(4m luk up table),square and a ramp wave..i hv managed to develop all d 3,bt m facing problem in generatin waves of amplitude and frequency as per user's requirement..
what changes can i do to the timer's and control register's value,if requirin variable frequency and amplitude?
or i just need to use switch cases instead making changes as mentioned above?
 

Would it be fine if I give you suggestion for based on Atmel 89c52 controller, can you implement the logic for your controller. Did this many years back.
 

unsigned char valuePWM, amplitude, variableAmplitude;

// valuePWM (0..0xff to get 0..5 Volts)
// amplitude (0..0xff to get MIN..MAX amplitude)

// to get variable amplitude

variableAmplitude = (valuePWM*(amplitude+1))/256;

// If (amplitude==0xff) then variableAmplitude = valuePWM (MAX VALUE)
// If (amplitude==0x00) then variableAmplitude = valuePWM/256 (MIN VALUE)

// to get variable frequency use DDS Direct Digital Synthesis

/*
Direct Digital Synthesis (DDS) is an electronic method for digitally creating arbitrary waveforms and frequencies from a single, fixed source frequency.

from https://en.wikipedia.org/wiki/Direct_Digital_Synthesis
*/
 

    SWETA

    Points: 2
    Helpful Answer Positive Rating
ok..wil do chek dis code svicent..seems easy..thanks 4 d help..
and yes ckshivaram,plz do dat..although i tried reading its datasheet 2 c if its code cn be used in ATmega 8L,bt wud be fine if u provide me wid ur approach n den i'l confirm if it can b of sum help while workin on ATmega 8L,cuz in any case i wil be workin on the microcontroller as mentioned abuv..
neways thanks.
 

SWETA said:
i wud b glad if anyboby cud help me in providin a solution 2 dis querry of mine..
m using ATmega 8L for making a function generator..dere m usin PWM technique for generatin sin(4m luk up table),square and a ramp wave..i hv managed to develop all d 3,bt m facing problem in generatin waves of amplitude and frequency as per user's requirement..
what changes can i do to the timer's and control register's value,if requirin variable frequency and amplitude?
or i just need to use switch cases instead making changes as mentioned above?

Take a look at these:

Mini DDS

**broken link removed**

Frequency Generator

**broken link removed**
 

m workin on d code which i hv copied here...d logic dt svicent provided me, 2 hv variabl amplitude,requires a lot 2 b changed in ds code..findin cumbersome,cn u suggest 4 d same..
n yes..thru makin changes in d luk up tabl nly,i generated d oder waves..so i hope dose changes wud b applicabl 4 oder waves as wel..
n can sum1 clear dis doubt of mine...OCR1A define the top value for the counter, hence also its resolution.The counter value increases until a Compare Match occurs with OCR1A and then counter is cleared.
i wanted 2 knw wat exactly it means 2 defining d top value of counter,how cum compare match occurs at top value of counter..it can be at any value i guess n dt shud decide PWM's on tim...
plz suggest...
thank you alll..



Code for generation of Sine Wave

#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr/pgmspace.h>
const uint8_t sinewave[] PROGMEM=
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};
uint8_t i=0;
ISR(TIMER1_COMPA_vect){
OCR1A=pgm_read_byte(&sinewave);
i++;
}
int main(void) {
//Port D pins as input
DDRD=0x00;
//Enable internal pull ups
PORTD=0xFF;
//Set PORTB1 pin as output
DDRB=0xFF;
// initial OCR1A value
OCR1A=0x80;
//Output compare OC1A 8 bit non inverted PWM
TCCR1A=0x91;
//start timer without prescaler
TCCR1B=0x01;
//enable output compare interrupt for OCR1A
TIMSK=0x10;
//enable global interrupts
sei();
while (1) {
//loop for ever. Interrupts will do the job.
}
}
 

the timer in that code above will count from zero to the TOP value which is defined by the OCR1A register. There is mechanism that when the value of timer equal with OCR1A register, the timer count will be reset to zero (look like a over flow). Some other event occur such as interupt flag or OC pin, active when the timer reset. And because this interupt is enabled (by TIMSK and sei()) then the program go to the interupt service routine (ISR(TIMER1_COMPA_vect)). In this routine the value of the OCR1A is updated by sinus value (uint8_t sinewave). By doing this, if you filter out the output pin by highpass filter, you will get sinusoidal waveform.
 

    SWETA

    Points: 2
    Helpful Answer Positive Rating
wel..yes it s like dat nly..just dat d filter used ,shud b low pass as a low frequency sinusoidal signal is 2 b extracted 4m PWM's high frequency signal...thanks 4 d help neways..cn u do me another favour...do sugest a way in findin a variable amplitude as wel as a variable frequency output sinusoidal wave 4m dis code..i guess i need 2 change d comlete code 4 d same..cuz 4 havin a varyin amplitude wave at output,changes cant b made 2 d luk up tabl..so do sugest a solution..wub b a gr8 help..
 

It will be difficult to adjust the amplitude by software. You can do scaling in the software, just multiply the value of sinus on the table before you put it to the OCR1A register. But you have to care with overflow issue and other thing.
The easiest way to achieve variable amplitude is by analogue. From the filter you can scale it with Op-Amp by using inverting or non-inverting amplifier circuit. And btw you can also using op-amp to do the filtering.
 

    SWETA

    Points: 2
    Helpful Answer Positive Rating
firstly,thanks inverta 4 d suggestion..bt d issue is i m tld 2 do it al thru programin,except 4d filter dt i wud b usin at d output 2 obtain d desired signals...
i guess i need 2 use a different logic..sum way thru wich i can vary d output's amp by makin changes in d duty cycle of PWM signal...
do comment on dis..
thanks neways...:|
 

SWETA, please use correct English spelling. This is an international forum. Some folks may have difficulty reading your messages.
 

Yes,i do agree...i will do take care of it from now.
 

oh thank you echo47....
at first i found it is interesting way to post the message like that, challenging to find the true meaning of the message....but it has become bothering... :p and i think it make some people lazy to respond.

to sweta, you are right by saying varying the duty cycle will vary the PWM output. That what exactly the program above do. Sinusoidal waveform is not constant signal, its vary over the time. Thats why the program change the duty cycle (OCR2 register) periodically. btw i think i made a mistake by saying the timer will reset when the compare match occur. read the avr data sheet carefully, especially in the timer section. I think the explanation in that data sheet is readable and easy to follow.
 

What you just talked about the "Timer Resetting",i am v.much aware of it already(through datasheet only) that it does not Reset but it counts till it does not reach the TOP value.. and when it reaches there,the OC1A pin toggles (which is set at toggle mode),means its high as long as timer's or counter's value is less than the value given by OCR1A pin through periodic interrupts on reaching TOP value everytime..and thereafter the timer counts till final value of timer and then it again comes to bottom(that is completes timer's cycle)...thus we can say that the duty cycle is being varied by changing the value at OCR1A pin from luk up table(as the PWM high wave frequency signal is being obtained at OC1A pin)....and this duty cycle obviously gives the average analog DC output...
But my concern has always been in asking for the logic that can impliment this..
i am asking for a code if you can provide me with..
And yes..i did feel that my posts could have been misunderstood,when echo47 pointed it..and i do respect his opinion.. but inverta saying, using short forms in posts makes people lazy to respond ...i guess, it does not matter to the one who knows the solution to a problem and believes in sharing his/her knowledge for the same..
but yes i do agree that it was my ignorance and i am very much not bothering people now through my spellings..
tc
 

at your previous reply you just said need comment.... :D :D :D
well firstly i'll tell you that varying the amplitude will be great done by analogue because its analogue, i mean the amplitude span can be made much longer than digital, because digital is discrete. :D:D:D

but if you insist to done that in the software, i think you just have to modified your program, firstly you have provide routine to accept the input of desired amplitude of your wave form, its up to you the method for accept the input (using push button, or potensio through adc, by interupt or polling periodically). for shortly let just say you put that value in AMP.
then in the interupt rutin for the timer, you just scale the updated value for ocr2a, so the code would be

OCR1A=AMP*pgm_read_byte(&sinewave);

thats all, as i mentioned before, you have to be care about the overflow and other. and also, maybe you need to modified the sinus table.

thank you
cmiiw (Correct Me If I'm Wrong)
 

WELL..that is a really good suggestion you have made..i will try implimenting it soon but would take time to, as i have started another project on FAT file system as a part of internship program..
might need your help later...thanks anyways..
and there is no correction required..
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top