ATmega 328p Timer2 not working

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,

 

I know there've been hundreads of topics regarding this but I've spent a lot of time already and have no idea what's wrong. My goal is to run timer2 on my arduino uno (without using arduino ide) every second and use interrupt to do something. I went through so many articles, copied the code from different sources, I keep looking at the documentation but it still doesn't work. The problem is that the program stops working and when I check the serial port for messages, the only one I get is the first one - "cli". If I remove line

TIMSK2 = (1 << OCIE2A);

the program runs successfuly and the built in diode changes its state every second (see while loop). The timer is not running then, obviously. Here's the code, maybe you'll spot something...

#define UART_BAUD_RATE 9600
#define F_CPU 16000000UL

#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "uart.h"

ISR(TIMER2_COMPA_vect)
{
	uart_puts("Hello, World!\n");
}

void initTimer2()
{
	cli();
	uart_puts("cli\n");

	TCNT2 = 0; // set counter to 0
	uart_puts("counter = 0\n");

	TCCR2A |= (1 << WGM21); // ctcmode
	uart_puts("ctcmode\n");

	TIMSK2 = (1 << OCIE2A); // enable interrupt on match
	uart_puts("interrupt on match\n");

	OCR2A = 15624; // set ocr2a to match value 15625
	uart_puts("max value\n");

	TCCR2B |=  ((1 << CS20) | (1 << CS21) | (1 << CS22)); // set prescaler to 1024
	uart_puts("prescaler\n");

	sei();
	uart_puts("sei\n");
}

int main(void)
{
	DDRB = 0xFF;
	uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
	initTimer2();

	while (1)
	{
		PORTB = (1 << PORTB5);
		_delay_ms(1000);
		PORTB = (0 << PORTB5);
		_delay_ms(1000);
	}
}

 

Last Edited: Sun. Jan 12, 2020 - 10:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Aranha wrote:

OCR2A = 15624; // set ocr2a to match value 15625

So how will this value fit into an 8 bit register?

jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

NB: In Mega328, Timer2 is an 8 bit counter/timer. All of the registers are 8 bit, including the counter/timer and all of the compare registers. It has no capture function but if it did, that would also be 8 bit. 8-bit registers can only accept values from 0 to 255 (when interpreted as an unsigned integer).

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

I've spent a lot of time already and have no idea what's wrong.

Did you thoroughly read the datasheet for timer2?  I find it very helpful to print that section...then go through each timer2 register & mark up the bits for the way you want to set it.  When you are done marking, you'll have a list of all the settings you need to put in place. This works wonders for any datasheets that are not full of typos blush

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Agree 100%. Printing short sections of a datasheet helps me to understand. I can study the printed paper and add pencil notes. Most importantly, I can do this away from the PC.
.
Yes, it costs paper, ink and pencils.
But your time is worth money too.
Solving a problem pays for the paper. Most importantly, you UNDERSTAND how the chip works.
.
The same applies to many software problems. I wasted a lot of time by checking code on the PC screen last week.
Yesterday, I printed one piece of paper with the problem code. Checking the paper copy revealed the problem within 5 minutes.
.
I bet that other members have had a similar experience.
.
David.

Last Edited: Mon. Jan 13, 2020 - 07:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys !

 

Thanks for responses.

 

As for your advices to print the section I'm currently working on - I don't do that but I do go through the list of registers and write down every register value I need.

 

I haven't played with electronics for a couple of months but that's no excuse for forgetting about the fact that timer2 is 8bit. Thanks for that.

 

So if I want to be able to use a sleep mode where only timer2 can generate wake up calls, i can't achieve 1 sec interval, assuming my atmega runs on 16mhz, right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ISR(TIMER2_COMPA_vect)
{
	uart_puts("Hello, World!\n");
}

Never a great idea to hold for 10's of milliseconds in an ISR. Far better to either just toggle an LED or something or simply just log the fact that the ISR occurred by setting a flag then have other, non interrupt code later report the state of the flag.

 

Also how is uart_puts() implemented anyway? If it use transmit interrupts then it's not going to work when called from an ISR anyway. (because ISRs are entered in the CLI state).

 

BTW as Jim noted this does not do what you think:

	OCR2A = 15624; // set ocr2a to match value 15625

It actually sets OCR2A to be 0x08.

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

Hey clawson,

 

I am aware of the fact that ISR routines should be as small as possible. It was just for debugging purposes - yes, I could've used a built in LED but I wanted to specifically know which part is failing thus so many uart_puts calls. uart_puts that I found doesn't use interrupts and it's not going to be there in the final version of my project, it's jut for debugging purposes.

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

The thing that  confuses me is:

Aranha wrote:
when I check the serial port for messages, the only one I get is the first one - "cli"
yet the execution sequence here is:

int main(void)
{
	DDRB = 0xFF;
	uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
	initTimer2();
void initTimer2()
{
	cli();
	uart_puts("cli\n");

	TCNT2 = 0; // set counter to 0
	uart_puts("counter = 0\n");

	TCCR2A |= (1 << WGM21); // ctcmode
	uart_puts("ctcmode\n");

So it's very difficult to see why that would stop at just "cli". The whole of that routine runs in the CLI state (at power on then enforced by the call to cli() at the top of the function). I can see no reason why it would not also show:

cli
counter = 0
ctcmode
etc.

if it's not showing those subsequent outputs then I would concentrate on determining why that is - nothing to do with the ISR as that cannot start to operate until the IE flag is set and sei() is performed.

 

That's why I asked about the implementation of uart_puts(). If it were asynchronous then I could understand something happening to prevent it completing triggerd in the foreground. But if it's synchronous I see no way the output of the following strings could be defeated?

Last Edited: Mon. Jan 13, 2020 - 10:37 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I asked that question myself a lot in my head but couldn't find the answer.

 

I'll check the uart implementation later on when I get back home from work. Maybe my memory is wrong and the implementation actually IS using interrupts - I just got the first one from the internet and used it after one quick look at the code itself.

 

By the way - do you happen to know why, when I use arduino ide's serial port monitor, every time I launch it, i get that first message, as if the uC was restarted but my simple c# application that just reads a line from that serial port, only reads the output once and then when i restart the application (without doing anything to the uC), it doesn't show anything new? Does the uC keep track of previous messages somehow?

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

Aranha wrote:
By the way - do you happen to know why...

Instead of continuing to pose new stuff, why don't you address the questions posed to you?  In particular

 

ki0bk wrote:
So how will this value fit into an 8 bit register?
ka7ehk wrote:
NB: In Mega328, Timer2 is an 8 bit counter/timer. All of the registers are 8 bit, including the counter/timer and all of the compare registers.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I did answer these two:

I haven't played with electronics for a couple of months but that's no excuse for forgetting about the fact that timer2 is 8bit. Thanks for that.

 

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

Aranha wrote:
I did answer these two:

What about the one I quoted?!?

 

What does a couple months have to do with an AVR timer?  I don't know which question that answers.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.