Arduino - ATmega328 - PWM Signal.c
Arduino - ATmega328 - PWM Signal.c
Arduino - ATmega328 - PWM Signal.c
#include "WProgram.h"
void setup();
void loop();
int i; //for cycle
int analogPin = 0; //No. of input pin
int Input=1023; //this value is from ADC: it can be in range:0 - 1023 (0-5V)
float K;
// Constant : is equal Input/1023
float ph0;
// For calculating value of phase 1
float ph1;
// phase 2
float ph2;
// phase 3
//setting of sin table for half-period, 78 samples
//this realization is uneffective due to used memory - because it is possible t
o keep only values of first 60 degrees and
//+only for first phase. Others can be calculated.
//But this microchip hase a lot of memory and his only one role is to generate
PWM. We need to have values up time, and calculations
//which would be necessary (for calculating samples for phase 2 and 3, and for
angles of whole sine wave) are time-consuming
int sinus0[]={0,10,20,31,41,51,61,71,81,91,101,110,119,128,137,146,154,163,
170,178,185,192,199,205,211,217,222,227,231,236,239,243,246,248,25
0,252,
253,254,254,254,254,253,252,250,248,246,243,239,236,231,227,222,21
7,211,
205,199,192,185,178,170,163,154,146,137,128,119,110,101,91,81,71,6
1,
51,41,31,20,10,0};
int sinus1[]={220,225,230,234,238,242,245,247,250,251,253,254,254,254,254,254,25
2,251,
249,246,244,240,237,233,228,224,219,213,207,201,194,188,180,173,16
5,157,
149,140,131,122,113,104,94,85,75,65,55,44,34,24,13,3,6,17,
27,38,48,58,68,78,88,98,107,116,126,134,143,152,160,168,175,183,
190,197,203,209,215,220};
int sinus2[]={220,215,209,203,197,190,183,175,168,160,151,143,134,125,116,107,9
7,88,
78,68,58,48,37,27,17,6,3,14,24,34,45,55,65,75,85,94,
104,113,123,132,140,149,157,165,173,181,188,195,201,207,213,219,2
24,229,
233,237,241,244,247,249,251,252,254,254,255,254,254,253,251,250,2
47,245,
242,238,234,230,225,220};
void setup()
{
//for default settings
//=====setting of timer for fast PWM method====
//frequency PWM is fosc/(8*256) (by 16MHz oscil. = 7812,5)
//timer 0, 8-bit timer, pins 5,6(+) 128us
TCCR0A=0b10110011; // generate inverted PWM signals in output
TCCR0B=0b00000010; // set of source of clock signal + prescaller
//timer 2, 8-bit timer, pins 9,10(+) = same settings as timer0 - 128us
TCCR2A=0b10110011; // generate inverted PWM signals in output
TCCR2B=0b00000010;
//timer 1, 16-bit timer, pins 3, 11(+)
TCCR1A=0b11100001; // set for generate negative values first
TCCR1B=0b00001010;
//setting of PWM ports to output
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(3,OUTPUT);
}
void loop()
{
//whole our code processed in infinity cycle
delay(64);
//change of polarity of phase 1
TCCR0A = TCCR0A ^ 0b01010000;
//cycle for half period
for(i=0; i<78;i++)
{
//reading the value of input voltage
Input=analogRead(analogPin); //Input=1023;
K = Input / 1023.00;
//now Input value is in range: 0-1
//generating of value OCR0x,OCR1x,OCR2x , where for same counter are values
the same
ph0=sinus0[i]*K; //this value should be float
//setting of OCR0x
OCR0A=byte(ph0);
OCR0B=byte(ph0);
//for 2. phase:
if(i==52){
//passed 52 samples, it means, that values of phase two will be negative =>
the setting of generating signals must be changed
//TCCR2A=0b1011 0011; => 0b1110 0011 => for XOR =mask: 0101 0000
TCCR1A = TCCR1A ^ 0b01010000;
}
ph1=sinus1[i]*K;
OCR1A=byte(ph1);
OCR1B=byte(ph1);
//for 3.phase
if(i==26){
//26 samples - change positive to negative and vice versa
TCCR2A = TCCR2A ^ 0b01010000;
}
ph2=sinus2[i]*K;
OCR2A=byte(ph2);
OCR2B=byte(ph2);
//wait for end of now processing cycle - than generate new samples for next
cycle
// flag TOV1=1 when PWM period ends
while(TOV1 != 1){
//check it every 16 micro seconds - with changes in timer, it is 64 times
bigger value
delayMicroseconds(1024);
delay(64);
}
}
}
int main(void)
{
init();
setup();
for (;;)
loop();
return 0;
}