The PWM and ADC are working separately fine, but not working simultaneously.
I am using AVR studio 4 with compiler optimization disabled.
The program is running timer 2 fast PWM mode in non-inverting mode, and adc channel 0 for feedback from the design, the multimeter shows correct feedback voltage value but controller gives flicker in the design.
The OCR2 must be in the range of 200 to 220 for the correct operation of the design.
below is my code:
I am using AVR studio 4 with compiler optimization disabled.
The program is running timer 2 fast PWM mode in non-inverting mode, and adc channel 0 for feedback from the design, the multimeter shows correct feedback voltage value but controller gives flicker in the design.
The OCR2 must be in the range of 200 to 220 for the correct operation of the design.
below is my code:
Rich (BB code):
#include<avr/io.h>
#include<avr/interrupt.h>
void adcinit()
{
ADMUX &= ~(1 << REFS0);
ADMUX &= ~(1 << REFS1); // Aref is selected, internal vref is disabled
ADMUX &= ~(1 << MUX3);
ADMUX &= ~(1 << MUX2);
ADMUX &= ~(1 << MUX1);
ADMUX &= ~(1 << MUX0);
ADCSRA |= (1 << ADEN); // enable the adc
ADCSRA &= ~(1 << ADSC);
ADCSRA &= ~(1 << ADFR);
ADCSRA &= ~(1 << ADIF);
ADCSRA &= ~(1 << ADIE);
ADCSRA |= (1 << ADPS2);
ADCSRA |= (1 << ADPS1);
ADCSRA |= (1 << ADPS0); // division factor 128
return;
}
unsigned int adcread(unsigned char ch)
{
ADMUX = (ch & 0x07); // if all the pins in admux are zero no need to apply a bitwise or operation, while a masking is already done by a bitwise and operation.
ADCSRA |= (1 << ADSC);
while( ADCSRA & ( 1 << ADSC )); // wait for conversion completes
return ADC;
}
void msdelay(unsigned int itime)
{
unsigned int i,j;
for(i=0;i<itime;i++)
{
for(j=0;j<100;j++)
{
}
}
return;
}
void PWM_on()
{
TCCR2 |= (1 << COM21); // set pwm on non inverting mode
TCCR2 |= (1 << WGM21) | (1 << WGM20);
// set fast pwm mode
TCCR2 |= (1 << CS20);
// start the pwm with prescalar 1
return;
}
int main()
{
unsigned char duty=0;
unsigned int feedback=0;
DDRB=0xFF;
DDRD=0xFF;
adcinit();
PWM_on();
OCR2=128;
while(1)
{
feedback=adcread(0);
if(feedback<200)
{
duty++;
}
if(feedback>220)
{
duty--;
}
OCR2=duty;
msdelay(500);
}
return 0;
}
Last edited by a moderator: