# How to create sine wave by avr

#### aamir1

##### Member
dear friends ive made the circuit and code for a 50HZ sinewave but i dont get it on output ive attached the code and proteus simulation some one guide me please

#### Attachments

• 295.4 KB Views: 1,112

#### Winterstone

##### Banned
aamir1, is it really necessary to attach the circuit as a *.rar file?
Why do you complicate possible answers?

#### aamir1

##### Member
it contains all the material code etc.....i ve attached the picture and also the code is written down please help me

-----------------AVR ATMEGA48 CODE---------------------------------------------
.include "m48def.inc"
.org $0000 RJMP MAIN .org$00E
RJMP TIMER2

.ORG $0030 MAIN: LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 LDI R16, 0 OUT PORTD, R16 OUT PORTB, R16 LDI R16,$FF
OUT DDRB, R16
OUT DDRD, R16

LDI R16, $83 OUT TCCR0A, R16 LDI R16,$0A
OUT TCCR0B, R16

LDI R16, $02 STS TIMSK0, R16 LDI ZL,low(Pos_cycle*2) LDI ZH,high(Pos_cycle*2) SEI A: RJMP A TIMER2: LDI R17,$01
IN R18, PORTB
EOR R18, R17
OUT PortB, R18

LPM R16, Z+
OUT OCR0A, R16

LDI R18, 0
OUT TCNT0, R18

CPI R16, 255
BRNE B

LDI ZL,low(Pos_cycle*2)
LDI ZH,high(Pos_cycle*2)

LPM R16, Z+
OUT OCR0A, R16

B:
RETI

Pos_cycle:
.DB 00,03,06,10,12,15,21,24,27,30,33,36,42,45,48,51,54,57,60,63,69,72,75,78,81,84,87,93,96,99,102,105,108,114,117,120,123,126,129,132,135,141,144,147,150,153,156,159,160,163,169,172,175,178,181,184,187,193,196,199,202,205,208,211,214,217,220,223,226,229,232,235,238,241,245,248,251,254

#### aamir1

##### Member
How can you get a sine wave out of a single bit... The mega hasn't got a dac... Are you trying to produce the sine wave externally?
i am using the pwm technique for generating sine wave........ya i want it externally......actually i want to make a sine wave inverter i know the programming of at mega but i some where lack in sine wave generation by pwm technique please let me know what should i do for that

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
i am using the pwm technique for generating sine wave........ya i want it externally......actually i want to make a sine wave inverter i know the programming of at mega but i some where lack in sine wave generation by pwm technique please let me know what should i do for that

The two ways of creating a sine wave from a square wave are

a) phase shifting http://www.electro-tech-online.com/custompdfs/2013/02/sbfa003.pdf
Or
b) Using an inductor in your filter.

Either way you need a perfect square wave out... So you need to change the period AND duty cycle of the pwm to keep the sine clean ( well cleanish)

#### ()blivion

##### Active Member
Well, *IF* the PWM frequency is high enough, and I mean really high, you can use it just like any DAC and thus create a sine wave with it. You can technically recreate any arbitrary wave, because it is just a DAC. The PWM frequency needs to be something like 10x-100x your output wave though.

*HERE* is a simulation of a crude circuit that turns a waveform to PWM and back to waveform again. Feel free to right click the waveform input and change it to something else, then watch the output follow it. Note that I made this quite "quick-and-dirty" like, and that shows in the quality of output. A good design can make perfectly respectable waveforms though.

Here is a screen shot for those that don't like long cryptic links. (it's actually the net list)

As for doing such things with code...
Take the filter circuit from above, or make your own low pass filter with a sharper roll-off. Put the filter on a GIOP of the μC. Set the pin up to be an output driven as PWM. Then load duty cycle register with the points of your waveform. It's much the same as what you would do with the DAC method. You may want to interpolate in sync with each PWM cycle if you can. That would probably create the best possible waveform.

Edit: *HERE* is a better sim, using a higher order filter and giving a closer look at the waveform.

Last edited:

#### aamir1

##### Member
generating sine wave through avr microcontroller

Hi Dear Friends !! i want to generate a sine wave through avr microcontroller using pwm technique i have some knowledge of it that i have to make a look up table of sine value and adjust the top value of the timer at every interrupt but i am confused that how can i adjust the frequency through it what is the calculation behind it please let me know someone thanks......

#### dougy83

##### Well-Known Member
You adjust the frequency by adjusting the rate at which you step through the entries in the lookup table. For a low frequency, you step through slowly; for a higher frequency, you step through more quickly.

Every time you update the output pwm value, you could use a function that performs something like the following pseudocode:
Code:
index = index + step
if index >= numEntriesIn(pwm_lookup) then index = index - numEntriesIn(pwm_lookup)
setOutput(pwm_lookup[index])

#### misterT

##### Well-Known Member
Make a 256 point lookup table and use 16 bit phase counter to control the frequency.

Every update step would look like this.

C:
uint16_t counter;
uint16_t step;
int8_t lookup[256];

update_pwm()
{
counter = counter + step;
PWM_VALUE = lookup[counter>>8];
}`
The bigger the "step" value, the faster the sine frequency. The lookup table cycles through naturally because the upper byte flows over when the value exceeds 255.. the upper limit of the table.
This video explains it in more detail: http://www.youtube.com/watch?feature=player_detailpage&list=ECD7F7ED1F3505D8D5&v=pGiD96zY7-M#t=965s

Last edited:

#### aamir1

##### Member
Please tell me the calculation behind frequency adjustment a mathematical formula or something

#### misterT

##### Well-Known Member
Please tell me the calculation behind frequency adjustment a mathematical formula or something
I think that was explained quite well in the video. Did you watch it?

The following is only correct if you use the method I described. Or the method described in the video.
First you need to know your sampling frequency Fs. (How often you execute the "update_pwm()" -function).

Your output sine wave frequency will then be:
F = (step * Fs) / (2^16)

From that you can calculate the value of "step" for certain frequency:
step = (2^16) * F / Fs

Last edited:

#### Mike odom

##### Active Member
frequency = 1/cycle time... 60 Hz = 16.667msec (16667usec) 50 Hz = 20msec, 10 Hz = 100msec, etc...

#### aamir1

##### Member
my question is how do i do it with avr im using atmega 48 timer0 in toggle mode and using the mode 7 which has configurable top value option which means i can put the value of comparison in ocr as top value ive attached the code also please tell me what changes should i do for 50hz.........

.include "m48def.inc"

.org $0000 RJMP MAIN .org$00E
RJMP TIMER_2

MAIN:
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16

LDI R16, 0
OUT PORTD, R16
OUT PORTB, R16

LDI R16, $FF OUT DDRD, R16 OUT DDRB, R16 LDI ZL,low (Pos_cycle*2) LDI ZH,high(Pos_cycle*2) LDI R16,$02
STS TIMSK0, R16

LPM R16, Z+
OUT OCR0A, R16

LDI R16, $8F OUT TCCR0A, R16 LDI R16,$09
OUT TCCR0B, R16

SEI

A:
RJMP A

TIMER_2:
LPM R16, Z+
OUT OCR0A, R16

CPI R16, 254
BRNE B

LDI ZL,low(Pos_cycle*2)
LDI ZH,high(Pos_cycle*2)

LPM R16, Z+
OUT OCR0A, R16

B:
RETI

Pos_cycle:
.db 00,03,06,10,12,15,21,24,27,30,33,36,42,45,48,51,54,57,60,63,69,72,75,78,81,84,87,93,96,99,102,105,108,114,117,120,123,126,129,132,135,141,144,147,150,153,156,159,160,163,169,172,175,178,181,184,187,193,196,199,202,205,208,211,214,217,220,223,226,229,232,235,238,241,245,248,251,254

#### aamir1

##### Member
please answer me any 1 what should i do to get a sine wave of 50hz ive attached the code below also

.include "m48def.inc"

.org $0000 RJMP MAIN .org$00E
RJMP TIMER_2

MAIN:
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16

LDI R16, 0
OUT PORTD, R16
OUT PORTB, R16

LDI R16, $FF OUT DDRD, R16 OUT DDRB, R16 LDI ZL,low (Pos_cycle*2) LDI ZH,high(Pos_cycle*2) LDI R16,$02
STS TIMSK0, R16

LPM R16, Z+
OUT OCR0A, R16

LDI R16, $8F OUT TCCR0A, R16 LDI R16,$09
OUT TCCR0B, R16

SEI

A:
RJMP A

TIMER_2:
LPM R16, Z+
OUT OCR0A, R16

CPI R16, 254
BRNE B

LDI ZL,low(Pos_cycle*2)
LDI ZH,high(Pos_cycle*2)

LPM R16, Z+
OUT OCR0A, R16

B:
RETI

Pos_cycle:
.db 00,03,06,10,12,15,21,24,27,30,33,36,42,45,48,51,54 ,57,60,63,69,72,75,78,81,84,87,93,96,99,102,105,10 8,114,117,120,123,126,129,132,135,141,144,147,150, 153,156,159,160,163,169,172,175,178,181,184,187,19 3,196,199,202,205,208,211,214,217,220,223,226,229, 232,235,238,241,245,248,251,254