EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: MarkoAnte on December 26, 2013, 12:36:05 pm

Title: PWM with atmega324pa
Post by: MarkoAnte on December 26, 2013, 12:36:05 pm
Hi,

I'm trying to make a pwm signal and I started by using this code:

/*
 * Voscilnicaosciloskop.c
 *
 * Created: 24.12.2013 15:10:32
 *  Author: Alucard
 */

#define F_CPU   18432000UL   
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


double dutycycle = 0;



int main(void)
{

   DDRB = 0xff;
   
   TCCR0A = (1 << COM0A1) | (1 << WGM00) | (1 << WGM01);
   TIMSK0 = (1 << TOIE0);
   
   OCR0A = (dutycycle/100.0)*255;
   
   sei();
   
   TCCR0B = (1 << CS00);
   
   while(1)
   {
      _delay_ms(100);
      dutycycle += 10;
      
      if(dutycycle > 100)
      {
         dutycycle = 0;
      }
   }
}

ISR(TIMER0_OVF_vect)
{
   OCR0A = (dutycycle/100.0)*255;
}


The problem I have is wiht the delay. I set the fuse bits so that the cpu runs off a external 18.432 Mhz clock and I get a 71.9 kzh pwm output - witch is ok as 18mhz/255(8 bit timer)- is the 72 kzh signal. The problem is that it is really slow on the delay, it hold the same duty cycle for a long time, the problem is fixed when I enter the f_cpu as the 72 khz I'm getting form the pwm output.
Why is this and how do I make it work properly?

Title: Re: PWM with atmega324pa
Post by: dannyf on December 26, 2013, 02:59:22 pm
Quote
Why is this

Easy:

1) compare the code vs. the datasheet to see what it is trying to do;
2) then figure out if it is doing what it is trying to do.

Quote
and how do I make it work properly?

3) if not, try to figure out how to do what you are trying to do.
Title: Re: PWM with atmega324pa
Post by: filip_cro on December 26, 2013, 08:30:56 pm
What kind of signal are you trying to make? 
Now you get change every 100 ms ( by using _delay_ms(100); ) in while loop. Understand?
Why not putting something like OCR0A += 25; in TIMER0_OVF interrupt. And use OCR0A interrupt so you wont lose count if OCR0A = 255.
Title: Re: PWM with atmega324pa
Post by: Lajon on December 26, 2013, 09:18:35 pm
Quote
Now you get change every 100 ms
No far from that - this is the problem OP is having.
The main program (which is mainly the _delay_ms call) is starving because of the heavy computation done in the ISR. There is really no need to use a double in this program - also no need to compute the value for OCR0A inside the ISR. You can add a counter inside the ISR and base the timing in main on that (or use another timer) but the delay_ms will approach 100ms if the ISR is made (a lot) faster.
Title: Re: PWM with atmega324pa
Post by: filip_cro on December 26, 2013, 10:36:34 pm
Quote
Now you get change every 100 ms
No far from that - this is the problem OP is having.
The main program (which is mainly the _delay_ms call) is starving because of the heavy computation done in the ISR. There is really no need to use a double in this program - also no need to compute the value for OCR0A inside the ISR. You can add a counter inside the ISR and base the timing in main on that (or use another timer) but the delay_ms will approach 100ms if the ISR is made (a lot) faster.
Well he wouldn't see difference between 7190 and 7191 times of x% duty cycle. And he said that problem was sold by using smaller delays (by using smaller frequency F_CPU) so he probably want change every time timer is started.