Go Down

Topic: Arbitrary waveform generation on a microcontroller (including sine) (Read 2084 times) previous topic - next topic


This demonstrates generating of Arbitrary waveforms including sine waves on a microcontroller.
It uses a wave lookup table, PWM and a low pass filter to make decent waveforms.
Code: [Select]

#define F_CPU 110000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
void setpwm(unsigned char x){
if(!x){TCCR0A &= ~ (1<<COM0B1);}
else {TCCR0A |= (1 << COM0B1);}
OCR0B = x;
int main(){
uint8_t tkr = 0;
        static uint8_t PROGMEM lookup[64] = {
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x18, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1E,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A,
        0x18, 0x17, 0x16, 0x14, 0x13, 0x11, 0x10, 0xF, 0xD, 0xC, 0xA, 0x9, 0x8, 0x6,
0x5, 0x4, 0x3, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x3,
0x4, 0x5, 0x6, 0x8, 0x9, 0xA, 0xC, 0xD, 0xF};
DDRB = 0x1A & ~_BV(PB3);
int CB = 0;
PORTB = 0x10 | _BV(PB3);
TCCR0A |= (1<<WGM00) | (1<<WGM01);
TCCR0B |= (1<<WGM02) | (1<<CS00);
OCR0A = 0x20;
setpwm(pgm_read_byte(lookup +tkr));
if(tkr > 64){tkr = 0;}

This generates about a 60hz sine wave on PB1 with a 128khz clock

Changing the lookup table as follows (as well as change the 64 to a 16) results in a saw tooth wave:
Code: [Select]

static uint8_t PROGMEM lookup[18] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
     13, 14, 15};


The filter is just a dead simple RC low pass filter.
I used 2.2K with .56uf but change this based on operating frequency.
Avoid throwing electronics out as you or someone else might need them for parts or use.
Solid state rectifiers are the only REAL rectifiers.
Resistors for LEDS!

Go Up