Wednesday, 1 August 2018

microcontroller - PWM with ADC - ATMega16


I want to write code where I move the wiper of the potentiometer clockwise so it applies PWM on a pin, and when I move it counter-clockwise it applies PWM on another pin.


I could do it with Arduino, but I would like to do the same with ATMega16.


#include 

#include
#include
#include
#include
short i = 0, i1;
short Reading[4];
short Reader(short ch){
ADMUX = ch;
ADMUX &= ~((1 << REFS0) | (1 << REFS1)|(1 << ADLAR)) ;
ADCSRA |= (1<
while(ADCSRA & (1< return ADC;
}
ISR(ADC_vect){
_delay_ms(100);
ADCSRA &= ~(1 << ADSC);
if(Reading[i] > 553){
TCNT0 = 0; TCCR0 |= (1 << CS01);
i1 = (i * 2 + 1); OCR0 = 255 * ((ADC - (1023 - 553))/553);
}

else if(Reading[i] < 435){
TCNT0 = 0; TCCR0 |= (1 << CS01);
i1 = (i * 2); OCR0 = 255 * ((453 - ADC)/453);
}
else{
TCCR0 &= ~(1 << CS01);
}
if(i < 4) {Reading[i] = Reader(i); i++;}
else {i = 0; Reading[i] = Reader(i); i++;}
}

ISR(TIMER0_OVF_vect){
PORTD = (1 << i1);
}
ISR(TIMER0_COMP_vect){
PORTD = 0;
}
int main(){
DDRA = 0x00; DDRB = 0xff; DDRC = 0xff; DDRD = 0xff;
PORTC = 0;
Reader(0);

sei();
TIMSK |= (1 << TOIE0) | (1 << OCIE0);
ADCSRA |= (1 << ADEN)|(1 << ADATE)|(1 << ADPS0)|(1 << ADIE);
SFIOR &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0) | (1 << 4)); // free running mode
ADMUX &= ~((1 << REFS0) | (1 << REFS1)|(1 << ADLAR)) ;
TCNT0 = 0;
while (1);
return 0;
}


When I checked by adding some blinking LED code in the ISR(ADC_vect) it worked, which means the ISR(ADC_vect) is called but PWM doesn't work; though I could get it working on its own in another poject when I checked after I doubted that I didn't know how to get PWM applied, but it worked.


So please if anyone can detect a logical error here or any error please mention it, and if you can write a simple code for me to achieve this I will be more than grateful.


enter image description here


enter image description here


enter image description here




Update:


#include 
#include
#include

#include
#include

short Reader(short);
int main(void){
sei();
SFIOR &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0) | (1 << 4)); // free running mode

TIMSK |= (1 << OCIE0)|(1 << TOIE0);


ADCSRA |= (1 << ADEN)|(1 << ADATE)|(1 << ADPS0)|(1 << ADIE) ;

DDRC = 0xff; DDRB = 0xff;


while(1){

Reader(0);

}


return 0;
}

ISR(TIMER0_OVF_vect){
PORTB = (1 << PB0);
PORTC = (1 << PC0);
}
ISR(TIMER0_COMP_vect){
// PORTC = 0x00;

PORTC &= ~(1 << PC0);
PORTB &= ~(1 << PB0);
}

ISR(ADC_vect){
if(ADC > 553){
TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02));
TCCR0 |= (1 << CS01)|(1 << CS00);
OCR0 = 254 * ((ADC - 553)/(1023 - 553));
//OCR0--;

//_delay_ms(5);
}
else if(ADC < 453){
TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02));
TCCR0 |= (1 << CS01)|(1 << CS00);
OCR0 = 254 * ((453 - ADC)/453);
}
else{PORTC = 0; PORTB = 0; TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02)); }
}



short Reader(short ch){
ADMUX = (ADMUX & 0xf8) | ch;
ADCSRA |= (1 << ADSC);
while(ADCSRA & (1< if(ADC > 553){
TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02));
TCCR0 |= (1 << CS01)|(1 << CS00);
OCR0 = 254 * ((ADC - 553)/(1023 - 553));
}

else if(ADC < 453){
TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02));
TCCR0 |= (1 << CS01)|(1 << CS00);
OCR0 = 254 * ((453 - ADC)/453);
}
else{PORTC = 0; PORTB = 0; TCCR0 &= ~((1 << CS00)|(1 << CS01)|(1 << CS02)); }
return ADC;
}

It worked, but the LEDs light doesn't vary according to these two lines:



OCR0 = 254 * ((453 - ADC)/453);

and


OCR0 = 254 * ((ADC - 553)/(1023 - 553));

It is either one or zero.


How can I make it vary?




No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...