Dean, thank you. This is an excellent tutorial and has given me a great understanding of timers. The step-by-step and explanation of each line of code that you add is invaluable.
My project(s) are coming, and when I get either somewhere or really stuck I'll post to AVR freaks what I've been up to.
Also hello to the homeland, I live in Canada but I'm from Australia.
One question though, I've implemented the simple code for toggle led once each second on my butterfly and the LED BLINKS in 1Hz. In the code we calculated it to TOGGLE in 1Hz. I'm getting confused.
I've found the CLKPR in the datasheet, so I can adjust to make it do what I want. But still..
Does your LED _blink_ or _toggle_ in 1Hz?
By accident I put my led on PORTB = 0x20, same as the piezo, so my clock ticks! :)
Posted by abcminiuser: Fri. Jul 11, 2008 - 02:47 AM
1
2
3
4
5
Total votes: 0
Nice balancing robot Paul! Thanks for the offer for the PWM code. It's not a matter of myself being unable to write a trivial example, it's finding the motivation to write the tutorial around it!
Oh, and G'day cmetom! Make those crazy Canadians see the true culture of us Aussies :).
agising: The code is designed for an AVR running off its internal 1MHz RC oscillator, and should toggle at 1Hz. The Butterflies' bootloader sets the RC oscillator to 2MHz, so you're seeing twice the toggle rate (.5Hz).
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Posted by JohanEkdahl: Fri. Jul 11, 2008 - 09:35 AM
1
2
3
4
5
Total votes: 0
Quote:
should toggle at 1Hz.
Quote:
twice the toggle rate (.5Hz).
:shock:
Last time I checked, twice the rate of 1 Hz was 2 Hz.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
agising: The code is designed for an AVR running off its internal 1MHz RC oscillator, and should toggle at 1Hz. The Butterflies' bootloader sets the RC oscillator to 2MHz, so you're seeing twice the toggle rate.
Dean
I've just done a few rounds with the 16 bit Timer1 on a Mega168 and think that there are a few gotcha's that are worth mentioning. I was using the input capture pin to measure pulse width so the timer was in NORMAL mode, what could be easier?
1) On the mega168 the TCNT1 register is in the extended I/O memory area (it's at 0x84 and 0x85). The code examples shown in the data sheet use in and out instructions, these examples are wrong for the 168 and who knows how many more chips.
The registers still need to be written in reverse order to use the TEMP register properly.
2) The input capture interrupt is tricky! I was using the rising edge on ICP1 for an interrupt and it had a few 'bounces'. When an ISR is executed the interrupts are disabled automatically and you'd think that any rising edges will be ignored until it is re-enabled. Thinking, big mistake, that the ISR is long enough because I had included a short delay to bypass the bounces, I couldn't understand the random behaviour of my pulse width measurement. It took the best part of 4 days to track down the fact that the input capture flag CAN be set in the ISR and as soon as it terminates and interrupts are re-enabled, back it goes to the ISR for a quick rerun.
Now in all fairness, this is mentioned in the data sheet but there's a lot to read before you find it. I now set ICF1 as the last instruction before leaving the Timer1 ISR.
I am following this tutorial and it has been a fantastic insight into the AVR timers. Got through the first few with flying colours but hitting a brickwall on Part Four.
I am actually using a Butterfly which has the ATmega169V. In the doc for the ATmega169V (http://www.atmel.com/dyn/resources/prod_documents/doc2514.pdf)...approx page 95 onwards...I am trying to find the appropriate registers and what have you, but being such a noob, I am somewhat lost!
Can someone please tell me which registers etc I need to be using with the Butterfly to get the CTC functionality as per Step 04?
WGM12 ... I think this is correct
OCR1A ... ?
TIFR ... ?
OCF1A ... ?
Posted by abcminiuser: Mon. Jul 21, 2008 - 08:05 AM
1
2
3
4
5
Total votes: 0
TIFR becomes TIFR1 in the MEGA169, and still contains the OCF1A flag. OCR1A stays the same, and WGM12 lives in TCCR1B.
Really the only change is the TIFR register which gaves the "1" suffix as the entire TIFR1 register is for timer 1, rather than being shared with timer 0 or other timers.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
TIFR becomes TIFR1 in the MEGA169, and still contains the OCF1A flag. OCR1A stays the same, and WGM12 lives in TCCR1B.
Really the only change is the TIFR register which gaves the "1" suffix as the entire TIFR1 register is for timer 1, rather than being shared with timer 0 or other timers.
- Dean :twisted:
Thanks Dean, I'll give it a whirl first thing in the morning at work and if I have any troubles I'll post another reply.
Posted by abcminiuser: Sun. Aug 3, 2008 - 09:30 AM
1
2
3
4
5
Total votes: 0
Quote:
In the part five you wrote "TIMSK" instead "TIMSK1"?
TIMSK is valid for the MEGA16, the chip I've written the examples on. Newer AVRs add the USART number to the end of the registers to differentiate between then on multi-USART AVRs, and so you're going to need to add in the USART number as I specify in the tutorial and re-iterate above.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
if i used OCR1A as TOP would it "always" at 50% duty cycle?
could you explain about "changing frequency" in Fast PWM and Phase Correct PWM mode? im a liltle confuse about that. the datasheet said that
Quote:
When changing the TOP value the program must ensure that the new TOP value is
higher or equal to the value of all of the Compare Registers.
Dean, it might be a good idea to move Part Nine to another thread (or a copy of it). It is one of the most asked about functions of timers and it is difficult to find this on page 11 of the thread.
Posted by JohanEkdahl: Tue. Aug 12, 2008 - 04:53 PM
1
2
3
4
5
Total votes: 0
As this tutorial chain gets a lot of discussion and questions I'd think that moving all the tutorials to a new thread which is then locked would make sense. The locked thread could contain links to this question-and-discussion thread. And as Dean the author is also the mod here he can easily add to, re-arrange or otherwise modify the tutorials, and announce it in the Q'n'D thread.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
Where I can update it and people can see it better. I've also made this tutorial into a formatted PDF document (a task unto itself) and attached it to the first post.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
I am using the ATINY12 to build a simple device which will produce two alternating frequencies to control a liquid mixing process. Any one think they can help me here? :roll:
I am using the ATINY12 to build a simple device which will produce two alternating frequencies to control a liquid mixing process. Any one think they can help me here? :roll:
I am using the ATINY12 to build a simple device which will produce two alternating frequencies to control a liquid mixing process. Any one think they can help me here? :roll:
Please do not ask for help in the tutorial forum. This should have been asked in the AVR forum.
If you make a double post by mistake, click the X button to delete one of them.
If you think education is expensive, try ignorance.
Posted by scheerluck: Fri. Sep 26, 2008 - 01:10 PM
1
2
3
4
5
Total votes: 0
Wow, that was amazing! Where can I donate? :)
I'm just starting out and just trying to remember all those acronyms had my head spinning. Couldn't ever remember which ones I needed for which flag on which timer in which mode on which register. This tutorial has helped a TON.
Thank you for this clear tutorial Dean. Very helpful thing for a person who's just started (like me).
This really opens a lot of doors for me. The idea of writing a book is not a bad one. If ever, make sure you get it translated into Polish. Here in poland there are no (little) good books on it. Most writers get only as far as rewriting the datasheets while making heaps of mistakes. So the polish market is yours =D
I have two questions. I could see that to some extent they were answered in this thread already but werent exactly what i needed. (I have to admit to getting only as far as 9th page of this thread, so excuse me if i'm repeating any questions)
1)In case i want to read a 16 bit counter (for ex. reading: TCNT1), do i have to stop it first so as to make sure i don't get to read a New LSB and an old MSB (or the other way around) as the reading could happen in between the update of LSB and MSB? (as it happens in case of enabled interrupts)
2)My Atmega8 datasheet says that clearing all bits of TCCR1B (the prescaller) stops the counter. Is that the only way to stop it? Do i have to set up the prescaller each time again wanting to switch the timer back on?
Posted by abcminiuser: Sun. Sep 28, 2008 - 01:40 AM
1
2
3
4
5
Total votes: 0
Quote:
Wow, that was amazing! Where can I donate? Smile
On my site (http://www.fourwalledcubicle.com) if you're so inclined. No one appreciates donations more than a full time university student!
Quote:
1)In case i want to read a 16 bit counter (for ex. reading: TCNT1), do i have to stop it first so as to make sure i don't get to read a New LSB and an old MSB (or the other way around) as the reading could happen in between the update of LSB and MSB? (as it happens in case of enabled interrupts)
The AVR timer has an internal buffer for the 16-bit timers. It is locked when reading the low byte, and unlocked when reading the high byte. For this reason, you should always read out the LSB before the MSB of the timer to ensure that the bytes correlate to the same data point -- if using GCC and one of the 16-bit psudoregisters such as TCNT1, this sequence is maintained by the compiler. This is the same for writing, and again the GCC compiler will take care of the sequence for you if you use the 16-bit psudoregister name.
Quote:
2)My Atmega8 datasheet says that clearing all bits of TCCR1B (the prescaller) stops the counter. Is that the only way to stop it? Do i have to set up the prescaller each time again wanting to switch the timer back on?
Yes, that's the only way to stop it - once given a clock source via the prescaler, the timer is activated. It would be nice if they put in a start-stop bit so that the timer can be stopped and started without having to preserve the prescaler settings, but as it stands that's your only option.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Posted by Ali_dehbidi: Tue. Nov 4, 2008 - 11:17 AM
1
2
3
4
5
Total votes: 0
thanks for tutorial.
but i have found some bugs!
you need to use 15624 instead of 15625 in ctc modes because you are counting from 0 and 0-15624 is equal 15625 and in software ctc mode i think you should use 49911 instead of 49910 again because of 0.
and there is another utility that make calculations easier and it's an avr calculator you can get it at: http://www.b9.com/elect/avr/kavr...
Took me a bit to read (and re-read) through it all but I've found that all your tutorials are extremely easy to follow. I've been afraid of trying to get into timers until i had to after skimming through some other explanations, but I UNDERSTAND now :twisted: , props to you, keep up the good work. :D
First of, thanks for this tutorial. However, I still have a little problem.
I would like a clock of 250Khz. My sys clock is 1Mhz. According to the formula in the datasheet (attiny 2313 in that case), f = f_sys / (2 N (1 + OCR0A)). Thus prescaler of 1 and OCR0A = 2. I set the
First of, thanks for this tutorial. However, I still have a little problem.
I would like a clock of 250Khz. My sys clock is 1Mhz. According to the formula in the datasheet (attiny 2313 in that case), f = f_sys / (2 N (1 + OCR0A)). Thus prescaler of 1 and OCR0A = 2. I use the CTC mode. Here is the code:
void init_timer(void) {
// timer setting: clear timer on compare match
TCCR0A = (1 << WGM01);
// clock source without prescaling.
TCCR0B = (1 << CS00);
// count to maximum value of
OCR0A = 1;
// turn on interrupts
sei();
// clear compare match flag
TIFR |= (1 << OCF0A);
// enable compare match interrupt
TIMSK |= (1 << OCIE0A);
}
ISR(TIMER0_COMPA_vect) {
// toggle clock output pin
USICR |= (1 << USITC);
}
However, the measured frequency is around 17Khz... It seems this is only possible when OCR0A = 31. This means that I cannot set a TOP (maximum) value smaller than 31. How is that possible? I don't really understand this. Anyone can help me?
Posted by abcminiuser: Sun. Jan 11, 2009 - 12:42 PM
1
2
3
4
5
Total votes: 0
The ISR will have a certain amount of overhead - about 9 cycles or so IIRC. That means that regardless of the TOP value, if it is smaller than the time the ISR takes to complete, it will have no effect.
31 cycles for an ISR sounds a bit excessive, however. Are you compiling with -Os to compile for size?
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
I must be missing something here - on my calculator 250KHz is just one quarter of 1MHz. That means you have just 4 cycles to get the pin state changed. There is no way on earth you are going to achieve that using even the tightest ISR hand crafter in assembly. In fact you pretty much just want the main() code to sit in the tightest loop possible doing nothing other than toggling the pin state - there'd be no CPU time left for doing anything else. So if you want to generate 250KHz and you cannot achieve this with hardware assist then you most definitely need to clock the CPU at a faster speed. But doesn't the tiny2313 have the capability for the timer to do the pin toggling for you in silicon?
Yeah, it's what I thought... It's weird because at first, we think with this timer thing we can achieve whatever clock we want under the condition that the output clock is smaller that the sys clock. Actually, it's not the case.
There is an upper bound. Maybe it could be a good idea to update the tutorial by giving the upper limit for a clock generated by a timer.
huh... I played with my source code but when I set the prescaler to 1 and OCR0A to 249, it doesn't work anymore. The clock is not generated.
According to the formula, it should be 1Mhz/(2 * N * (1 + OCR0A)) = 2Khz. So the code toggle at 2Khz which should give a 1Khz clock.... but it doesn't do anything....
The source code is the same as in my previous post, except with OCR0A = 249;
The source code is the same as in my previous post,
But that's not a program, it's just a snippet - how do you expect anyone to help if they cannot build/examine the same program that you are trying to use.
Again, in the simulator this is working correctly. Your ISR takes about 27 cycles to complete, so any value of OCRA less than that and the ISR will run continuously (the next interrupt will be queued before the previous one ends).
mmmh, thanks for testing this in a simulator. I think the only possibility left is a hardware bug. I'll try to change the uC to another 2313 or maybe a 45 for instance and see if it's working.
Another possibility is the tool I use to measure the frequency... I'm using a multimeter with a max freq of 10Mhz. However, if you increase OCR0A, the frequency decreases. Thus it shouldn't be a problem with the multimeter...
I'm interested in this simulation thing. Could you please explain me how it works and what tools you use?
I'm developing under Linux. Do these tools also exist with Linux? Could you pinpoint me a tutorial or some documentations? I'm kind of new with AVR development.
I'm interested in this simulation thing. Could you please explain me how it works and what tools you use?
I'm developing under Linux.
I'm afraid those two paragraphs are oxymoronic. The simulator is a great component within AVR Studio. The IDE from Atmel that not only includes their own assembler but that can be used as a "wrapper" for building GCC projects (when WinAVR is also installed). Sadly for you this is ONLY available as a Windows program.
Now (if you search) you may find that some people have had success running it in Linux using Wine and I guess that if your plan is only to use it for the simulator (and not interfacing to real programmers/debuggers) then it will probably work sufficiently for you.
Another option is to use either Vmware Server or Sun's VirtualBox to run a virtual Windows machine within your Linux host - but the problem there is that you would need a licenced copy of M$ Windows to install it into the virtual machine.
Thanks for your answer. I only need a simulator to add to my linux environment. I checked the forum and read some posts about AVR Studio and Wine. I think I'll go with this solution.
Dean, thank you. This is an excellent tutorial and has given me a great understanding of timers. The step-by-step and explanation of each line of code that you add is invaluable.
My project(s) are coming, and when I get either somewhere or really stuck I'll post to AVR freaks what I've been up to.
Also hello to the homeland, I live in Canada but I'm from Australia.
Hi Dean!
Thaks for a great tutorial. It really saved me!
One question though, I've implemented the simple code for toggle led once each second on my butterfly and the LED BLINKS in 1Hz. In the code we calculated it to TOGGLE in 1Hz. I'm getting confused.
I've found the CLKPR in the datasheet, so I can adjust to make it do what I want. But still..
Does your LED _blink_ or _toggle_ in 1Hz?
By accident I put my led on PORTB = 0x20, same as the piezo, so my clock ticks! :)
Once again, great tutorial!
Nice balancing robot Paul! Thanks for the offer for the PWM code. It's not a matter of myself being unable to write a trivial example, it's finding the motivation to write the tutorial around it!
Oh, and G'day cmetom! Make those crazy Canadians see the true culture of us Aussies :).
agising: The code is designed for an AVR running off its internal 1MHz RC oscillator, and should toggle at 1Hz. The Butterflies' bootloader sets the RC oscillator to 2MHz, so you're seeing twice the toggle rate (.5Hz).
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
:shock:
Last time I checked, twice the rate of 1 Hz was 2 Hz.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
I wrote the tutorial and so what I say goes. You are wrong.
- Dean :twisted:
PS: Just kidding! Heck of a brain fart for a post made in the middle of the day.
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Gr8
Thank you very much!
Awesome tutorial Dean! :D
Dean
I've just done a few rounds with the 16 bit Timer1 on a Mega168 and think that there are a few gotcha's that are worth mentioning. I was using the input capture pin to measure pulse width so the timer was in NORMAL mode, what could be easier?
1) On the mega168 the TCNT1 register is in the extended I/O memory area (it's at 0x84 and 0x85). The code examples shown in the data sheet use in and out instructions, these examples are wrong for the 168 and who knows how many more chips.
The registers still need to be written in reverse order to use the TEMP register properly.
2) The input capture interrupt is tricky! I was using the rising edge on ICP1 for an interrupt and it had a few 'bounces'. When an ISR is executed the interrupts are disabled automatically and you'd think that any rising edges will be ignored until it is re-enabled. Thinking, big mistake, that the ISR is long enough because I had included a short delay to bypass the bounces, I couldn't understand the random behaviour of my pulse width measurement. It took the best part of 4 days to track down the fact that the input capture flag CAN be set in the ISR and as soon as it terminates and interrupts are re-enabled, back it goes to the ISR for a quick rerun.
Now in all fairness, this is mentioned in the data sheet but there's a lot to read before you find it. I now set ICF1 as the last instruction before leaving the Timer1 ISR.
Note that it needs to be set not cleared....
Cheers
Klave
Hi Dean/everyone,
I am following this tutorial and it has been a fantastic insight into the AVR timers. Got through the first few with flying colours but hitting a brickwall on Part Four.
I am actually using a Butterfly which has the ATmega169V. In the doc for the ATmega169V (http://www.atmel.com/dyn/resources/prod_documents/doc2514.pdf)...approx page 95 onwards...I am trying to find the appropriate registers and what have you, but being such a noob, I am somewhat lost!
Can someone please tell me which registers etc I need to be using with the Butterfly to get the CTC functionality as per Step 04?
WGM12 ... I think this is correct
OCR1A ... ?
TIFR ... ?
OCF1A ... ?
Thanks in advance!
Cheers,
Scott.
TIFR becomes TIFR1 in the MEGA169, and still contains the OCF1A flag. OCR1A stays the same, and WGM12 lives in TCCR1B.
Really the only change is the TIFR register which gaves the "1" suffix as the entire TIFR1 register is for timer 1, rather than being shared with timer 0 or other timers.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Thanks Dean, I'll give it a whirl first thing in the morning at work and if I have any troubles I'll post another reply.
Hi,
In the part five you wrote "TIMSK" instead "TIMSK1"?
Many thanks..
TIMSK is valid for the MEGA16, the chip I've written the examples on. Newer AVRs add the USART number to the end of the registers to differentiate between then on multi-USART AVRs, and so you're going to need to add in the USART number as I specify in the tutorial and re-iterate above.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
This is a fantastic tutorial.
Thanks for taking the time to write it.
Please let me know if you ever write a book
if i used OCR1A as TOP would it "always" at 50% duty cycle?
could you explain about "changing frequency" in Fast PWM and Phase Correct PWM mode? im a liltle confuse about that. the datasheet said that
kurro
Dean, it might be a good idea to move Part Nine to another thread (or a copy of it). It is one of the most asked about functions of timers and it is difficult to find this on page 11 of the thread.
Regards,
Steve A.
The Board helps those that help themselves.
As this tutorial chain gets a lot of discussion and questions I'd think that moving all the tutorials to a new thread which is then locked would make sense. The locked thread could contain links to this question-and-discussion thread. And as Dean the author is also the mod here he can easily add to, re-arrange or otherwise modify the tutorials, and announce it in the Q'n'D thread.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
I've moved the PWM section to it's own new thread:
https://www.avrfreaks.net/index.p...
Where I can update it and people can see it better. I've also made this tutorial into a formatted PDF document (a task unto itself) and attached it to the first post.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
I am using the ATINY12 to build a simple device which will produce two alternating frequencies to control a liquid mixing process. Any one think they can help me here? :roll:
I am using the ATINY12 to build a simple device which will produce two alternating frequencies to control a liquid mixing process. Any one think they can help me here? :roll:
Please do not ask for help in the tutorial forum. This should have been asked in the AVR forum.
If you make a double post by mistake, click the X button to delete one of them.
If you think education is expensive, try ignorance.
Wow, that was amazing! Where can I donate? :)
I'm just starting out and just trying to remember all those acronyms had my head spinning. Couldn't ever remember which ones I needed for which flag on which timer in which mode on which register. This tutorial has helped a TON.
Thanks.
Thank you for this clear tutorial Dean. Very helpful thing for a person who's just started (like me).
This really opens a lot of doors for me. The idea of writing a book is not a bad one. If ever, make sure you get it translated into Polish. Here in poland there are no (little) good books on it. Most writers get only as far as rewriting the datasheets while making heaps of mistakes. So the polish market is yours =D
I have two questions. I could see that to some extent they were answered in this thread already but werent exactly what i needed. (I have to admit to getting only as far as 9th page of this thread, so excuse me if i'm repeating any questions)
1)In case i want to read a 16 bit counter (for ex. reading: TCNT1), do i have to stop it first so as to make sure i don't get to read a New LSB and an old MSB (or the other way around) as the reading could happen in between the update of LSB and MSB? (as it happens in case of enabled interrupts)
2)My Atmega8 datasheet says that clearing all bits of TCCR1B (the prescaller) stops the counter. Is that the only way to stop it? Do i have to set up the prescaller each time again wanting to switch the timer back on?
Greetings
On my site (http://www.fourwalledcubicle.com) if you're so inclined. No one appreciates donations more than a full time university student!
The AVR timer has an internal buffer for the 16-bit timers. It is locked when reading the low byte, and unlocked when reading the high byte. For this reason, you should always read out the LSB before the MSB of the timer to ensure that the bytes correlate to the same data point -- if using GCC and one of the 16-bit psudoregisters such as TCNT1, this sequence is maintained by the compiler. This is the same for writing, and again the GCC compiler will take care of the sequence for you if you use the 16-bit psudoregister name.
Yes, that's the only way to stop it - once given a clock source via the prescaler, the timer is activated. It would be nice if they put in a start-stop bit so that the timer can be stopped and started without having to preserve the prescaler settings, but as it stands that's your only option.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Thanks for the tutorial Dean. This is one of the best tutorials I have seen for any subject.
thanks for tutorial.
but i have found some bugs!
you need to use 15624 instead of 15625 in ctc modes because you are counting from 0 and 0-15624 is equal 15625 and in software ctc mode i think you should use 49911 instead of 49910 again because of 0.
and there is another utility that make calculations easier and it's an avr calculator you can get it at:
http://www.b9.com/elect/avr/kavr...
I love Digital
and you who involved in it!
Thanks for this tutorial. It is great!! It taught me so much!
Dean, your tutorial rocks and your USB stuff rocks as well.
I've been trying to get my head around the timer stuff for ages now, and this just makes it sorta clear.
Now I only need to find a tutorial on how to make a simple IR transmitter. *Starts doing the search thing again*
Code, justify, code - Pitr Dubovich
Took me a bit to read (and re-read) through it all but I've found that all your tutorials are extremely easy to follow. I've been afraid of trying to get into timers until i had to after skimming through some other explanations, but I UNDERSTAND now :twisted: , props to you, keep up the good work. :D
Thanks for this tutorial. I'm planning on making a intervalometer for my camera and this has just about put me there :)
Thanks for the helpful tutorial !
Microcontroller & Electronic Books from Amazon
Hi,
First of, thanks for this tutorial. However, I still have a little problem.
I would like a clock of 250Khz. My sys clock is 1Mhz. According to the formula in the datasheet (attiny 2313 in that case), f = f_sys / (2 N (1 + OCR0A)). Thus prescaler of 1 and OCR0A = 2. I set the
[code]
Hi,
First of, thanks for this tutorial. However, I still have a little problem.
I would like a clock of 250Khz. My sys clock is 1Mhz. According to the formula in the datasheet (attiny 2313 in that case), f = f_sys / (2 N (1 + OCR0A)). Thus prescaler of 1 and OCR0A = 2. I use the CTC mode. Here is the code:
However, the measured frequency is around 17Khz... It seems this is only possible when OCR0A = 31. This means that I cannot set a TOP (maximum) value smaller than 31. How is that possible? I don't really understand this. Anyone can help me?
Thanks in advance!
The ISR will have a certain amount of overhead - about 9 cycles or so IIRC. That means that regardless of the TOP value, if it is smaller than the time the ISR takes to complete, it will have no effect.
31 cycles for an ISR sounds a bit excessive, however. Are you compiling with -Os to compile for size?
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
yes, I'm using the -Os flag...
So what would be the solution? Increase the system clock?
I must be missing something here - on my calculator 250KHz is just one quarter of 1MHz. That means you have just 4 cycles to get the pin state changed. There is no way on earth you are going to achieve that using even the tightest ISR hand crafter in assembly. In fact you pretty much just want the main() code to sit in the tightest loop possible doing nothing other than toggling the pin state - there'd be no CPU time left for doing anything else. So if you want to generate 250KHz and you cannot achieve this with hardware assist then you most definitely need to clock the CPU at a faster speed. But doesn't the tiny2313 have the capability for the timer to do the pin toggling for you in silicon?
Yeah, it's what I thought... It's weird because at first, we think with this timer thing we can achieve whatever clock we want under the condition that the output clock is smaller that the sys clock. Actually, it's not the case.
There is an upper bound. Maybe it could be a good idea to update the tutorial by giving the upper limit for a clock generated by a timer.
Anyway, thank you guys for your answers!
huh... I played with my source code but when I set the prescaler to 1 and OCR0A to 249, it doesn't work anymore. The clock is not generated.
According to the formula, it should be 1Mhz/(2 * N * (1 + OCR0A)) = 2Khz. So the code toggle at 2Khz which should give a 1Khz clock.... but it doesn't do anything....
The source code is the same as in my previous post, except with OCR0A = 249;
Any idea why it is not working properly?
so, no answer since my last post. I discovered that with OCR0A <= 27, I have a clock around 17KHz. However, with OCR0A > 27, no clock anymore...
This just drives me crazy...
But that's not a program, it's just a snippet - how do you expect anyone to help if they cannot build/examine the same program that you are trying to use.
I took that code, added a simple main() and changed to set OCR0A to 99 and it worked just fine. It hits the ISR every 100 clocks.
Regards,
Steve A.
The Board helps those that help themselves.
Ok, here is my full code. I thought it wouldn't be a problem to post a snippet but it seems it's related. Sorry about that.
So when I set OCR0A higher than 27, the clock at the SPI pin stops toggling...
The target is an attiny2313, I'm trying to set up the SPI.
Here is the code:
The main:
Thanks for your help!
Again, in the simulator this is working correctly. Your ISR takes about 27 cycles to complete, so any value of OCRA less than that and the ISR will run continuously (the next interrupt will be queued before the previous one ends).
Regards,
Steve A.
The Board helps those that help themselves.
mmmh, thanks for testing this in a simulator. I think the only possibility left is a hardware bug. I'll try to change the uC to another 2313 or maybe a 45 for instance and see if it's working.
Another possibility is the tool I use to measure the frequency... I'm using a multimeter with a max freq of 10Mhz. However, if you increase OCR0A, the frequency decreases. Thus it shouldn't be a problem with the multimeter...
I'm interested in this simulation thing. Could you please explain me how it works and what tools you use?
I'm developing under Linux. Do these tools also exist with Linux? Could you pinpoint me a tutorial or some documentations? I'm kind of new with AVR development.
Thanks again for your help!
I'm afraid those two paragraphs are oxymoronic. The simulator is a great component within AVR Studio. The IDE from Atmel that not only includes their own assembler but that can be used as a "wrapper" for building GCC projects (when WinAVR is also installed). Sadly for you this is ONLY available as a Windows program.
Now (if you search) you may find that some people have had success running it in Linux using Wine and I guess that if your plan is only to use it for the simulator (and not interfacing to real programmers/debuggers) then it will probably work sufficiently for you.
Another option is to use either Vmware Server or Sun's VirtualBox to run a virtual Windows machine within your Linux host - but the problem there is that you would need a licenced copy of M$ Windows to install it into the virtual machine.
Cliff
Hi Cliff,
Thanks for your answer. I only need a simulator to add to my linux environment. I checked the forum and read some posts about AVR Studio and Wine. I think I'll go with this solution.
It's a pity not to have native tools for linux!
Thanks again!
Well there's also simulavr but it's not maintained so only has limited support for early AVRs
Thank you very much for this tutorial :)
Jan Kießling
74HC Overview
Flowchart CAD
schematic CAD
Hey,
a very good tutorial indeed. helped in grasping many concepts abt timers.
But am facing a problem on execution of
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << 0); // Toggle the LED
}
when i do make all, following warning is displayed:
warning: return type defaults to `int'
In function `ISR':
warning: control reaches end of non-void function
Plz help me out with this as i have been trying to work out with this code for quite a long time...
#include
i have included the avr/interrupt.h file.
But still the problem persists.
Pages