[TUT] [C] Newbie's Guide to AVR Timers

Go To Last Post
482 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That should be fine, however, there's one more thing you're not accounting for - atomic access of the variables.

It's possible for your COMPA interrupt to fire in between the reading of a multi-byte global variable, which results in corrupted data being used. The solution is to read the volatile value into a normal local variable while interrupts are disabled in your main code:

volatile unsigned int verticalspeed = 0;
volatile int reference=0;
volatile int altitudeR_int=0;

int main(void)
{
// initialise interrupt here
while(1)     
{
// at here the altitudeR_int  changes according to our sensor

cli(); // Read in the globals here with interrupts disabled to prevent the ISR from updating them while reading the values
unsigned int verticalspeed_LCL = verticalspeed;
int reference_LCL = reference;
int altitudeR_int_LCL = altitudeR_int;
sei();

printf("Pump ON \n" );
printf("Altitude= %d ft \n", altitudeR_int_LCL);
printf("reference= %d mb \n",reference_LCL);
printf("verticalspeed:%u ", verticalspeed_LCL);
}

}


ISR(TIMER1_COMPA_vect)
{
verticalspeed=((altitudeR_int-reference)*60);
      
reference = altitudeR_int;
     
}

The added benefit of this in your code, is that since all globals are cached locally with the interrupts disabled, you prevent the update from also occuring between the variable reads. Without this you might get the corrupt data as above, but also correct data, but with half the variables from one sample, and half from another.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dean,

Just to note that when you want to interrupt protect access to a variable you may not always know that the current interrupt state is SEI or CLI so rather than wrapping the access in a cli() before and an sei() afterwards it sometimes makes sense to define a 'uint8_t sreg_state' then do 'sreg_state = SREG; cli();' before the access and then 'SREG = sreg_state;' afterwards which recovers the pre-existing interrupt state rather than making the assumption that it was SEI.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Right as always Cliff, I was oversimplifying for his example, which seemed to always need interrupts enabled. The "correct" way to do it is to save and restore SREG:

uint8_t SREG_Save = SREG;
cli();
// Atomic variable access here
SREG = SREG_Save;

Which I wrapped up into a handy macro and submitted to the avr-lib-c project, so it's going to be part of the library in the next avr-lib-c release or so.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi Dean,
thanks for ur help ... we are not sure if we have disable our interrupt correctly...

int main (void)
{	
	TCCR1A= (1 << WGM12); 				TCCR1B = 0x04;	// prescaler 256		
	TIMSK |= (0 << OCIE1A); 	disable the interrupt				
	sei(); //  Enable global interrupts 

function1(); //
function2(); // interrupt start and end here 
funciotn3(); //
}

function2()
{

                TIMSK |= (1 << OCIE1A); 
		OCR1A  = 625;     // we set the 20ms  interrupt here 	
while(1)      
{ 
// at here the altitudeR_int  changes according to our sensor 

cli(); // Read in the globals here with interrupts disabled to prevent the ISR from updating them while reading the values 
unsigned int verticalspeed_LCL = verticalspeed; 
int reference_LCL = reference; 
int altitudeR_int_LCL = altitudeR_int; 
sei(); 

printf("Pump ON \n" ); 
printf("Altitude= %d ft \n", altitudeR_int_LCL); 
printf("reference= %d mb \n",reference_LCL); 
printf("verticalspeed:%u ", verticalspeed_LCL); 
} 
	TIMSK |= (0 << OCIE1A);  // disable CTC interrupt  
}

ISR(TIMER1_COMPA_vect) 
{ 
verticalspeed=((altitudeR_int-reference)*60); 
      
reference = altitudeR_int; 
      
} 

is this a correct way to disable and enable the interrupt? and another problem is even we intend to set to 20ms interrupt but the program seem to perform one second interrupt? did we set the interrupt interval correctly ?

Location : Singapore

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's correct for the atomic access, assuming that you want interrupts on at all times except for the global reads (otherwise you need to save and restore SREG as discussed above).

This line:

TIMSK |= (0 << OCIE1A);    disable the interrupt

Does nothing - I suggest you read the "Bit Manipulation" tutorial. The correct code is:

TIMSK &= ~(1 << OCIE1A);    disable the interrupt

Although since that bit is cleared when the AVR is reset, it *still* doesn't achieve anything.

What clock speed are you feeding into the AVR? It comes with it's internal 1MHz RC oscillator enabled by default, you need to change the fuses to use an external crystal/clock source.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great tutorial! I successfully ran several of the code examples in this tutorial on an Olimex AVR MT 128 board (ATMega 128-based) after changing the timer prescale to 1/1024 to match a 16MHz system clock. I also changed the pin assignment to Port E Pin 2 because that pin on my board is adjacent to a ground pin. I'm just starting out with the AVR, and code from your tutorials is the first code I've successfully run on an AVR.

You write very well. You definitely have the right mindset when you write these tutorials - assume NOTHING of the reader. That's where many tutorials fall short. I teach for a living, and I've seen many "introductory" books in several different areas that miss this point. If you ever do get the time to write the book everyone is suggesting, I'll certainly buy it.

Ken

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the great tutorial. Using your tutorial alone, I've just wrote my very first interrupt implementation, to drive a servo with PWM signal in software, on a atmega8. Loaded it up, and it worked first time. Great tutorial! I'm very impressed. You've taught me how periodic interrupts work.

Thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FYI, the PDF of this tutorial is not in sync with the online version at the top of the thread. I just spent two hours chasing a mistake in the PDF that was fixed online a while ago. Once I figured out that the PDF was old, I fixed it in minutes. On the flip side, I have spent two hours reading the mega168 datasheet trying to figure this mess out :) .

Dean, is there a plan to update the PDF? If not, it might be a good idea to either take it offline or add a disclaimer at the beginning that the document is not up to date.

The tutorial was great even though I had problems. Thanks for putting it together.

You can have my mac when you pry my cold dead fingers off of it.

Kevin McEnhill -- mcenhillk@gmail.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kevin,

Sorry about that, my fault. I'm going to remove the PDF version for the meantime, while I try to find an automated solution; maintaining two formats is a pain in the rear and I want to simplify things. Ideally I'd want to go from BBCode from the post straight to a formatted PDF, but that's a pipe-dream. I think the best I can hope for is a BBCode-HTML converter, then a HTML to PDF converter. I'll have a look around.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually, I've been thinking today about the comments others have made about me writing a book. Books on AVR and the C language has been done, and I don't want to take away money from hungry mouths like Smokey (and that, as he will tell you, is a big mouth :lol:). However, I think that a book that is essentially a set of worked examples using the different AVR peripherals might fill a niche while not treading on any toes. A bit like a book of my tutorials, but ones that flow from one to the next. Thoughts?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, speaking from my days of having to tackle that cursed Perl language, the Perl Cookbook was a lifesaver. The reference books (i.e. datasheets) are not a good place to learn the basics. The beginner books (i.e. turorials) are not much good once you have run through them once because the examples are too simple. Something like a cookbook that illustrates each function helps bridge the gap.

For example, as of right now, I would KILL for an example of a working input capture counter! I am not ready to give up and go to the AVR Forum yet but a cookbook would be high on my list to Santa right now.

You can have my mac when you pry my cold dead fingers off of it.

Kevin McEnhill -- mcenhillk@gmail.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey All,

I have made a simple timer program that would toggle 3 LEDs after set time. I am using tiny13 uc. The program works perfect if I simulate it using AVR simulator or debug it using JTAGICE mk II but doesn't work at all if I flash program using ISP. All 3 LEDs stay ON instead of toggling after a set time.

I don't think there is an error with ISP. I have developed few other programs (not shown below) and they work fine when I flash them using ISP.

Any idea whats wrong ? I have tried playing with different clock prescales and different time delays (as explained using variable elapstedtimeseconds for longer time delays) but it didn't really help.

Below is program code :

[/code:1]

#include <avr/io.h>
#include "fuelgauge.h"


void main(void)
{

  unsigned char counter;

  init();				  // Initialize the controller

  TCCR0A |=  (1<< WGM01) | (0 << WGM00);

  OCR0A= 0xFF; 
  
  TCCR0B |= ((0 << CS02) | (0 << CS01) | (1 << CS00)); // Set up timer at Fcpu/1024

  
  for (;;) 
   { 

   counter=TCNT0;


   if (TIFR0 & (1 << OCF0A)) 
      { 
          PINB = 0x07; // Toggle the LED 

          TIFR0 = (1 << OCF0A);

	   }

   } 

}

void init(void)
{

  CLKPR = (1 << CLKPCE);
  CLKPR = 0;


  DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB4) ;
  PORTB = (1<<PB0)|(1<<PB1)|(1<<PB2);
  PINB = 0x00;
}

</pre></blockquote>
</div>
<div class="bb-quote">
<blockquote class="bb-quote-body">
<pre>
[code:1]

Thanks for all your help !!!

- Umesh

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Umesh,

If the LEDs appear to be on all the time it suggests that on/off toggling is simply happening too fast for you to see it (which is the difference between the simulator and real life - one is hundreds of times slower than the other). For one thing start by increasing the clock prescaler to the highest setting - you comment says "Fcpu/1024" but that's not what you are setting - I'll bet you speeded it up so you could see something happening in the simulator!

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi
guys can any one tell me how do i start my AVR studies i m bit confused plz help me with this k where i should i start my AVR program......some of my frends said to start studies of AVR 4m ATMEGA8 datasheet....plz tell me or give any brief or supporting tutorial
thanx....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uzairsaeed wrote:
hi
guys can any one tell me how do i start my AVR studies i m bit confused plz help me with this k where i should i start my AVR program......some of my frends said to start studies of AVR 4m ATMEGA8 datasheet....plz tell me or give any brief or supporting tutorial
thanx....

FIRST READ: General Information about Posting in the AVR Forum
http://www.avrfreaks.net/index.p...

ESPECIALLY THE LINK:
http://www.catb.org/~esr/faqs/sm...

After reading those, then start a new thread in the AVR Forum, not the tutorials forum, and give it an informative title like: "How to start with AVR?"

Wilbur

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

:-D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I tried the short LED Toggling Programm on my CM-5 Atmega 128. But i don´t know which LED is mean with DDRG? Could i see this one on my CM-5 case?

Could you help me let my LED´s on CM-5 like AUX/TXD blink? :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Added part eight - "Overflow as CTC". Writing PWM section now, just need to figure out the best way to go about it.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the new year gift Dean.
Thanks a lot for ur dedicated work on even the new years eve.
i have a doubt.i simulated the code in part part five of ur tutorial in avrstudio.i am not able to see the counting in the tcnt registers.
is it so that the count is not visibile while using interrupts?

#include  
#include  

int main (void) 
{ 
   DDRB |= (1 << 0); // Set LED as output 

   TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 

   TIMSK |= (1 << OCIE1A); // Enable CTC interrupt 

   sei(); //  Enable global interrupts 

   OCR1A   = 15625; // Set CTC compare value to 1Hz at 1MHz AVR clock, with a prescaler of 64 

   TCCR1B |= ((1 << CS10) | (1 << CS11)); // Start timer at Fcpu/64 

   for (;;) 
   { 

   } 
} 

ISR(TIMER1_COMPA_vect) 
{ 
   PORTB ^= (1 << 0); // Toggle the LED 
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Studio has a number of known issues when simulating timers, depending on the version. Check your version's help file -- see if there are any timer-related issues. It should indeed show the timer counting correctly.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks dean.

i was breaking my head over this.
when i programmed mega16 with this code it worked properly.
only problem was with simulation.
i checked up the help page.there is a problem with tcnt buffering wen we use 16 bit timer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

in part eight of ur tutorial you mentioned to use prescale of 64 and in the code you used prescale of 8.

Quote:
Let's go with the previous example in part two: a 1Hz flasher, using a 1MHz clock and a prescale of 64. We found the timer count to be 15625 for those conditions.

TCCR1B |= (1 << CS11); // Start timer at Fcpu/8 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fixed, copied the wrong code template. Thanks for the good bug-spotting.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi
want to ask about the timer

Why I'm getting problem with the TIMSK? The code is like below using m169

//****************************************  
  TCCR1B = _BV(WGM12) + _BV(CS10);  // clear timer on compare match, no prescaler
  OCR1A  =  XTAL/DEBOUNCE;		   		// timer = 5 msec . 40000000/200 = 200000??
  TIMSK  = _BV(OCIE1A);            	// enable Output Compare 1 overflow interrupt
//****************************************

The error i always get is:

../bla.c:385: error: 'TIMSK' undeclared (first use in this function)
../bla.c:385: error: (Each undeclared identifier is reported only once
../bla.c:385: error: for each function it appears in.)

How i want to solve this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Shouldn't it be TIMSK1 instead of just TIMSK?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are not using a mega 16 I guess? Here is an answer to a similar question (from this thread actually):

Quote:
TIFR or TIFR1 depends on the AVR, Dean is writing for mega 16 where the register is shared between timers and is called TIFR.
/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been playing with the following code on an atmega168@18.432MHz.

#include  
#include  

int main (void) 
{ 
   DDRC |= (1 << 0); // Set LED as output on port c0


// Waveform generation bits - see table 14-8 on page 104 of datasheet atmega168
   TCCR0B |= (0 << WGM02); // Configure timer 0 for CTC mode 
   TCCR0A |= (1 << WGM01) | (0 << WGM00);


   TIMSK0 |= (1 << OCIE0A); // Enable CTC interrupt 

   sei(); //  Enable global interrupts 

   OCR0A   = 1; // Set CTC compare value 

   TCCR0B |= ((1 << CS00) | (0 << CS01) | (0 << CS02)); // Start timer at Fcpu/1 table 14-9

   for (;;) 
   { 

   } 
} 

ISR(TIMER0_COMPA_vect) 
{ 
  
   PORTC ^= (1 << 0); // Toggle the LED on port c0
   // sei(); 
//  if sei(); is omitted then the maximum freq is lower. 
//  Using a 18.432 MHz x-tal, the max freq is 236 kHz (no sei() - with sei() in isr: 368 kHz
} 

I would like to have a faster timer. Why is it so slow? Any idea what to do?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't put the sei() in the ISR - the compiler takes care of that for you.

The ISR takes quite a few clock cycles to execute, about 9 just to get to it, plus a whole bunch more to execute your code, and the ISR overhead. 368KHz sounds about right for the maximum ISR speed.

You can do two things.

1) If your ISR is very basic, and has no side-effects, register or otherwise, you can make the ISR "naked" and ommit all the prologue and epilogue code. That'll speed it up, but will cause problems if your ISR tries to modify any of the registers or CPU flags.

2) Switch over to the hardware CTC method I outline. The timer circuitry can toggle the hardware compare pin as fast as the compare flag triggers, with no CPU overhead. That's the preferable option.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks,

I thought about the issue and it seems that the isr routine needs about 80 cycles to run. A naked one could be ok. I'll try the hardware one.

Oh, thanks for the tutorial.
I ran your examples and monitoring things on my digital scope. One one monitor I had the datasheet and on the other your tutorial and avr studio. The datasheet is quite cryptic and contains hardly any quick to use info. I've been looking at the microchip website lately and they have much more info about different things. Atmel is quite sparse with info.

How far are you with the the pwm tutorial? :wink:

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah bugger, I've had the PWM section on my "ToDo" list for months, but can never quite seem to bring myself to sit down and really type it out. I lack motivation, and six seasons of Stargate on DVD doesn't help much.

Part Six: Pure Hardware CTC is the section you want to read on the hardware-only toggling solution.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well I know the feeling... Ever heard of Firefly? just one season and a film called Serenity.

Anyway, I would like to have 3 pwm timers in an atmega168. Plenty of questions and the datasheet is cryptic. Perhaps if you just wrote something about the scope of this (strategy of what to use and perhaps why). Then I have enough to work on.

Thanks in advance.

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been playing with the pure hardware ctc routine. I used the two outputs on an atmega 168.

#include  
#include  

int main (void) 
{ 
   	DDRD |= (1 << 6); // set port PD6 as output. (led-> Timer 0 output on port OC0A (PD6, pin 12))
   	DDRD |= (1 << 5); // set port PD5 as output. (led-> Timer 0 output on port OC0B (PD5, pin 11))
	DDRC |= (1 << 0);

// Waveform generation bits - see table 14-8 on page 104 of datasheet atmega168
// Configure timer 0 for CTC mode 
   	TCCR0B |= (0 << WGM02); 
   	TCCR0A |= (1 << WGM01) | (0 << WGM00);

   	OCR0A   = 10; // Set Clear Timer on Compare Match mode (CTC) value - also known as TOP
   	OCR0B   = 1;  // Set Clear Timer on Compare Match mode (CTC) value 

// set OC0A and OC0B to toggle on compare match. page 102/103
	TCCR0A |= ((1<< COM0A0) | (0 << COM0A1) | (1<< COM0B0) | (0 << COM0B1)); 

// Start timer at Fcpu/64 See prescaler table 14-9 on page 106
	TCCR0B |= ((1 << CS00) | (1 << CS01) | (0 << CS02)); 


	
   for (;;) 
   { 

   } 
} 

OCR0B = 0..10. At 10 the phase relation between OC0A and OC0B is 100% If OCR0B >10 then the output on OC0B is zero.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Each timer can only have *one* CTC channel operating at a time - if you use both, the timer will clear when the first channel compares, and the second one will never be reached. The point of the multiple channels is for PWM mode, where you can have dual channels operating simultaneously.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks,

Now I've been playing with pwm on timer 0 using two outputs. I would like to get a possibility to set the freq and duty cycle of both outputs independently. But alas. I can only do one channel or use two channels with a fixed freq.
I do not yet understand it completely.
Perhaps you can have a look at the following code and tell me what I'm missing:

/*

PWM on atmega168 @ 10 MHz
two outputs OC0A (Port D6, pin 12) and OC0B (Port PD5, pin 11)

1) case WGM02=0 Mode 1 (table 14-8), PWM, Phase correct, TOP=0xFF

If WGM02=0 
Fixed freq: 39.0 kHz if fast is on (WGM01=1) or 19.6 kHz if fast is off (WGM01=0)
duty cycle set by OCR0A and OCR0B for both output ports.


2) case WGM02=1 Mode 5 (table 14-8), PWM, Phase correct, TOP=OCRA

If WGM02 = 1 then behavior is different: One (1) output only: OCR0B. Output OCR0A is constant high.
Frequency is determined by OCR0A: e.g.

OCR0A   = 100 : freq = 50.0 kHz (fast off)
OCR0A   = 200 : freq = 25.0 kHz (fast off)
OCR0A   = 100 : freq = 99.0 kHz (fast on)
OCR0A   = 200 : freq = 49.75 kHz (fast on)
OCR0A   = 199 : freq = 50.0 kHz (fast on)

The duty cycle of the output is: (OCR0B / OCR0A). 
e.g. OCR0A = 200, OCR0B = 35. Duty cycle=(35/200) * 100% = 17.5%

*/

#include  
#include  

int main (void) 
{ 
   	DDRD |= (1 << 6); // set port PD6 as output. (led-> Timer 0 output on port OC0A (PD6, pin 12))
   	DDRD |= (1 << 5); // set port PD5 as output. (led-> Timer 0 output on port OC0B (PD5, pin 11))
	DDRC |= (1 << 0);

// Waveform generation bits - see table 14-8 on page 104 of datasheet atmega168
// Configure timer 0 for PWM, Phase Correct 
   	TCCR0B |= (1 << WGM02); 
   	TCCR0A |= (0 << WGM01) | (1 << WGM00);

   	OCR0A   = 200; // Set Clear Timer on Compare Match mode (CTC) value - also known as TOP
   	OCR0B   = 9;  // Set Clear Timer on Compare Match mode (CTC) value 

// set OC0A and OC0B . page 102/103
	TCCR0A |= ((0<< COM0A0) | (1 << COM0A1) | (0<< COM0B0) | (1 << COM0B1)); 

// Start timer at Fcpu/1 See prescaler table 14-9 on page 106
	TCCR0B |= ((1 << CS00) | (0 << CS01) | (0 << CS02)); 


	
   for (;;) 
   { 
// Take a hike
   } 
} 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As far as I am aware, you set the frequency per-timer, then the duty-cycle per channel. Different frequencies require different timers - but most of the time muti-channel PWM applications all use the same frequency anyway (e.g. robots with servos, LED light controllers, etc).

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

frequency per-timer, duty-cycle per channel

I could not create that for both outputs, its either - or.

How many outputs per timer is normally used?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Added the start of the PWM chapter. Not entirely certain that I like it so far, so might be scrapped again (this is the second revision, I lost the first one!) depending on my mood and feedback.

I hate having things in public view that are unfinished, so hopefully this will serve me as a good motivator to finish it off this week.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

frequency per-timer, duty-cycle per channel

I could not create that for both outputs, its either - or.

How many outputs per timer is normally used?

One for CTC modes, and up to as many as it has for PWM. Phase and Frequency correct PWM should allow you to vary both the duty cycle of each channel (UPDATE value), and the frequency (TOP value).

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dean,

Can you update pdf, please.

Thanks for fine tutorial.

Pop

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey, Dean.

Just wanted to thank you for all your work on this great resource in the hope that a kind word might add to your motivation to push-on through the PWM section. Looks like you are off to a great start!

As an AVR newbie this site, and especially your timer guide, has been an invaluable resource to me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As a newbie, this is THE most informative guide I have found yet relating timers. WOW, before most the code was greek to me but after the explanations, I can actually understand what is going on. Thanks! I hope you find the motovation soon, I cannot wait until you get the PWM section done!!!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anyone know where I can find an easy to follow guide for PWM until this tutorial is done?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Atmel's AVR335 app note talks about PWM (in the context of producing sound in fact)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi , this is another great work. i cant describe how its useful. thanks..
I am trying with this tutorial because it doesn't require any tools beside my mega162 and small programmer.
I read the first four parts and try it , i fail :(
i changed anything with respect to my avr. here is the code:

TCCR1B |= ( 1 << CS12) ; // set up timer at Fcpu/256
	for(;;)
	{	
		// Check timer value in if statement, true when count 			//matches 1 second
		if (TCNT1 >= 31250)
		{
			TCNT1 = 0; // Reset timer value 
         		ElapsedSeconds++;
			if ( ElapsedSeconds == 30 ) // Check if 1/2 minute 							    //has elapsed
			{
				
				ElapsedSeconds = 0; // Reset counter variable
				PORTC ^= ( 1 << 0);	//Toggle the LED
				
			}
		}
	}
	
}

another thing to notice is that my programmer has a 4MHZ crystal. but in the program i am asuming i am suing the internal 8mhz.. after programmed i use it in my board without any crystal.!
does it make sense!??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:

Quote:

It was a right pain formatting all the code snippets, but it's done and attached to the original post. Enjoy!
- Dean :twisted:

Even after logging in I could not locate the to download the pdf version at original post. My eyes are missing the same.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, the PDF was subsequently removed as it was outdated. I would update the PDF, but the data is currently sitting on a backup disk awaiting the repair of my laptop.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

man this is an awesome tutorial it completely cleared my fundamentals cant wait for the pwm section to come in but i got one doubt i worked ont the principle u had given and i made led flash at a frequency of 0.5 hz that means 2 times in a sec the code i had written is as follows
# include
int main(void)

{
DDRD|=(1<<2);
TCCR1B|=((1<<CS10)|(1<<CS11));
while(1)
{

if(TCNT1>=31250)

{
PORTD^=(1<<2);
TCNT1=0;
}
}
return(1);
}
but when i connected the led nothing happened instead og toggling it never lit on (the led is fine) is something wrong in the code

oh yes iam using atmega16

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

iwas silly enough to connect to the wrong port and see the output but i so much appreciate ur effort but when will the pwm section come coz i need it as soon as possible coz i need to make a robot

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
Sorry, the PDF was subsequently removed ... sitting on a backup disk awaiting the repair of my laptop.
- Dean :twisted:

Thanks for your kind reply.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

superchiku wrote:
i made led flash at a frequency of 0.5 hz that means 2 times in a sec
No, 0.5 Hz means that it flashs once every 2 seconds. "2 times in a sec" means 2 Hz.

Pages