#define FN (50.0) //Rate motor frequency
#define P (UN/FN) // et.al specifies the proportion of voltage to the rated frequency
#define T_PWM (0.000355) //period of PWM signal - set by prescaler counters
#define T_MAX (4.0) //Determination of the maximum period of the output voltage
#define T_MIN (0.03) //the minimum period of the output voltage
#define K_MAX floor(T_MAX/T_PWM) //the number of values for the period of T_MAX
#define K_MIN ceil(T_MIN/T_PWM) //the number of values for the period of T_MIN
volatile static unsigned int dlugosc_tab_sin; //variable containing the number of values in full
//the period of the output voltage
static unsigned int i = 0; //variable auxiliary
volatile static unsigned int licznik_glowny = 0;//Variables in periodically interrupted
//^ wath time T_PWM increasing its value by 1
static unsigned int next_value_sin = 0; //variable whose value should calculate sin
static double t_param=100; //parameter specifies the period of the output voltage
static float t = T_PWM; //T_PWM
static float omega_t; //pulsation of the output voltage multiplied by T_PWM
static float t_out; //Output voltage period
static float U_o_param; //size parameter specified output voltage
//^ calculated on the basis t_out and U_in
static unsigned int ocr0a, ocr0b, ocr1a;//auxiliary variables for storing calculated filling material
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in; //variable containing the parameter of the function sin
static double blad = 1; // variable deck used to stop generating voltage of overloading
static unsigned int analog=0; //variable containing the measured value
static double U_in = 0; //variable stores the measurement voltage cardiovascular middleware
static double U_rms_max; //the maximum currently possible after generation of the effective voltage
static bool a=0; //Boolean to perform two alternate measurements
int main()
{
io_init(); //initialization inputs and outputs
timers_init(); //initializing the counter PWM
adc_init(); //initialization transducer ADC
while(1) //infinite loop of the main program
{
if (i==185) //the condition concerning the entry to change function
{ //parameters of the output voltage , the call approximately every 100 ms
zmien_predkosc(); //change function parameters of the output voltage
i=0;
}
next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoๆ sinusa do obliczenia
sin_in=omega_t*next_value_sin;
/*obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg*/
ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr0b = ocr0a - 1;
ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
ocr1b = ocr1a - 1;
ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr2b = ocr2a - 1;
/*uaktualnienie wartosci w rejestrach*/
cli(); //prohibit to handle interrupts in case
//when you upgrade an interrupt
OCR0A = ocr0a; //pin 6
OCR0B = ocr0b; //pin 5
OCR1AL = ocr1a; //pin 9
OCR1BL = ocr1b; //pin 10
OCR2A = ocr2a; //pin 11
OCR2B = ocr2b; //pin 3
sei(); //Permission to interrupt service
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//launching transducer
ADCSRA |= _BV(ADPS2);//setting prescaler
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// voltage reference set as a voltage supply
ADMUX |= ADMUX &= 0b11110000; //selecting ADC0 input 0 to measure
}
void timers_init()
{
cli(); // service interrupts prohibited
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01); //preskaler 8
TIMSK0 |= _BV(TOIE0); //flag of value 0 switched on
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(CS11); //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS21); //preskaler 8
//reset value of the counter
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei(); //permission to interrupt service
}
void io_init()
{
pinMode(6, OUTPUT); //OC0A
pinMode(5, OUTPUT); //OC0B
pinMode(9, OUTPUT); //OC1A
pinMode(10, OUTPUT);//OC1B
pinMode(11, OUTPUT);//OC2A
pinMode(3, OUTPUT); //OC2B
pinMode(2, INPUT);
pinMode(4, INPUT);
pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect) //interruption of the value of the counter 00
{
analog = ADC;
if(a)
{
U_in = 0.0709*analog;
ADMUX |= _BV(MUX0); //select input ADC1 to measure the current
}
else
{
ADMUX |= ADMUX &= 0b11110000; //select input ADC0 to measure voltage
if(analog>579)
{
blad = 0; // If the overload voltage generation Exclusion
digitalWrite(12, HIGH); //diode led สีแดงขา 12
}
}
ADCSRA |= _BV(ADSC);// start reading measurement
a=a^1; //bramka XOR neguje wartosc logiczna a
licznik_glowny++;
if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
U_rms_max = U_in*0.62; //0.62 value determined experimentally
bool up; //boolean informs about holding down the button increases the frequency
bool down; //boolean inform the button is pressed , reduce frequency
up = digitalRead(4); //read:if pressed increases the frequency
down = digitalRead(2); //read:if you pressed the button reduce the frequency
if(up==1) t_param--; //If you press the button increases the frequency decrease the period
if(down==1) t_param++; //If you press the button to decrease the frequency increases the service life
if(t_param<0) t_param=0; //protection exceeding the extreme values
if(t_param>100) t_param=100;//^
dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/50+K_MIN);//number of padded values in one period
t_out = T_PWM*dlugosc_tab_sin; //calculation of period of the output voltage
omega_t = t*2*PI/t_out; //calculate the output ripple voltage
U_o_param = (P/t_out)/U_rms_max; //calculation of the parameter defining an output voltage
if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //the voltage at the output at low frequency 10V
if(U_o_param>1) U_o_param=1; //protection exceeding the extreme values
}
ไม่มีความคิดเห็น:
แสดงความคิดเห็น