Ghassan Darkool
Newbie level 2
- Joined
- Oct 3, 2014
- Messages
- 2
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 35
Hello ...
I wrote this code for my Atmega 328P to make a PI control (changing the duty cycle of PWM according to the values of load current and voltage)
my code is sensible !! but I don't know why it's not work !!
PLZ help me PLZ
I didn't have any result !
in the main code when you change the OCR2A value for a constant one .. I have a result
for example if I put OCR2B=128*0.5; ... I have a duty cycle of 50% .. but I don't want that!!
PLZ I appreciate any help !
that's my code:
I wrote this code for my Atmega 328P to make a PI control (changing the duty cycle of PWM according to the values of load current and voltage)
my code is sensible !! but I don't know why it's not work !!
PLZ help me PLZ
I didn't have any result !
in the main code when you change the OCR2A value for a constant one .. I have a result
for example if I put OCR2B=128*0.5; ... I have a duty cycle of 50% .. but I don't want that!!
PLZ I appreciate any help !
that's my code:
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 #define F_CPU 16000000 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <Stdlib.h> #include <String.h> double p,i,pi,theLow,theTenBitResult ; int kp=4, ki=0.2; int vref=1024, iref=1024 ,verror, int_verror=0, vreal, ireal; //////////////////////////////////////////////////////////////////////////// void adc_read(void) { ADCSRA|=(1<<ADSC); // start conversion //while (ADCSRA & (1 << ADSC)); // Wait for it to finish //return ADCH; } ////////////////////////////////////////////////////////////////////////// void adc_setup (void) { ADCSRA|=(1<<ADEN);// enable the ADC. ADCSRA|=(1<<ADATE);//enable auto triggering. ADCSRA|=(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); // start the ADC with division factor 128 and activated the interrupt. ADCSRA|=(1<<ADIE);//the ADC Conversion Complete Interrupt is activated. ADMUX|=(1<<REFS0);//AVCC with external capacitor at AREF pin is activated. ADMUX|=(1<<ADLAR); sei(); } ///////////////////////////////////////////////////////////////////////// ISR(ADC_vect) // interrupt service routine function { uint8_t theLow = ADCL; uint8_t first_conversion=1; uint16_t theTenBitResult = ADCH<<8 | theLow; if(ADMUX==101)// ADC5 { if(first_conversion==2) { vreal=theTenBitResult; ADMUX|=(1<<MUX0)|(1<<MUX1); // switch to ADC3 first_conversion=1; } else first_conversion++; } else if (ADMUX==99) // ADC3 { if (first_conversion==2) { ireal=theTenBitResult; ADMUX|=(1<<MUX0)|(1<<MUX2); //switch to ADC5 first_conversion=1; } else first_conversion++; } adc_read(); } //////////////////////////////////////////////////////////////////////// void pwm_setup (void) { TCCR2A|= (1<<COM2A1)|(1<<COM2A0);//Set OC2A on Compare Match TCCR2A|=(1<<WGM20)|(1<<WGM21);//fast PWM OCR2A=BOTTOM AND 0XFF=TOP TCCR2A|=(1<<COM2B1);//Clear OC2B on Compare Match when up-counting. Set OC2B on Compare Match when down-counting. TCCR2B |= (1<<CS20)|(1<<WGM22); // Used no Prescaler TCNT2 = 0; // Reset TCNT2 OCR2A = 128; // Initial the Output Compare register A & B } //////////////////////////////////////////////////////////////////////// int main (void) { DDRD = 0b11111111; DDRB |= (1<<PB5)|(1<<PB0); PORTD = 0x00; OCR2B = 0; adc_setup(); pwm_setup(); while (1) { adc_read(); verror=vreal-vref; p=kp*verror; int_verror+=verror; i=ki*int_verror; pi=p+i; if(ireal>iref) OCR2B=0; else { if(vreal < vref) pi++; else if(vreal > vref) pi--; } OCR2B=pi; } }
Last edited by a moderator: