Author Topic: PWM with atmega324pa  (Read 2395 times)

0 Members and 1 Guest are viewing this topic.

Offline MarkoAnte

  • Regular Contributor
  • *
  • Posts: 71
PWM with atmega324pa
« 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?

 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PWM with atmega324pa
« Reply #1 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.
================================
https://dannyelectronics.wordpress.com/
 

Offline filip_cro

  • Regular Contributor
  • *
  • Posts: 71
  • Country: hr
Re: PWM with atmega324pa
« Reply #2 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.
 

Offline Lajon

  • Contributor
  • Posts: 31
  • Country: se
Re: PWM with atmega324pa
« Reply #3 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.
 

Offline filip_cro

  • Regular Contributor
  • *
  • Posts: 71
  • Country: hr
Re: PWM with atmega324pa
« Reply #4 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.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf