Seemingly simple RTC problem.

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

Greetings all,

I am putting together a small RTC project... an alarm clock of sorts, based on ATMega328P. It looked like getting the precision timer looked would be the hardest part, so I'm tackling it first. It seems that I was right, for I am having problems getting an LED to blink in one second interval, just as a start.

I've done my searching, read the relevant datasheet bits top to bottom, so I figured I'd pose the question here to see if someone can check my math.

I picked up a 32,768Hz crystal, placed it on pins XTAL1+2, kept the chip on its internal RC @ 1Mhz. I used Timer 2 in CTC mode instead of overflow. Set the clock source to external, set the clock divide to clk/256 so figure that's 32,768/256 = 128Hz. Set the compare register to 127, since 0 is counted, that should give 128Hz/128 = 1Hz. Seems like I have my bases covered...

...except the LED blinks at 2-3Hz or so, by visual inspection. Tried different crystals from the same order, same results. Added caps on either side and that caused more harm than good. (Most of my reading has told me that except for zeroing in on seconds/year or so level drift, no caps is fine for 32,768 xtals.)

Any ideas what I'm missing? I know I have the CTC set up right because changing the value of OCR2A in code changes the blink interval accordingly.

Here's the code:

ISR(TIMER2_COMPA_vect)
{
	// Reset timer immediately
	TCNT2 = 0;

	// RGB LED connected on PB2, PB1, PB0, active low
	// Cycle a 0 from PB2 -> PB1 -> PB0 -> PB2 -> etc
	// Creates flashing R,G,B LED
	PORTD >>= 1; 
	if((PORTD & 0b00011111) == 0b00011111)
		PORTD = 0xFB;
}

int main(void)
{
	// Port D as output, see ISR for output scheme
	DDRD = 0xFF;
	PORTD = 0xFB; 

	ASSR |= (1 << AS2); // Set external oscillator. (!Corruption of TCNT2, OCR2A, etc possible?)

	OCR2A = 127; // 128 ticks = 1Hz @ 128Hz (32,768 Hz / 256)

	//	TCCR2B = 0b00000110; // Clock / 256
	TCCR2B |= (1 << CS22) | (1 << CS21); // Clock / 256

	TCCR2A |= (1 << WGM21); // CTC Mode, instead of overflow
	
	TIMSK2 |= (1 << OCIE2A); // Enable Output Compare A interrupt, as set above

	TCNT2 = 0;

	sei();


    while(1)
    {
		;
    }
}

I have tried other things in the while loop, delays and sleep_mode, no avail (kind of a long shot anyway).

I'm quite out of ideas, so many thanks in advance for any help or insight you can provide,

-Matt B

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
   TCNT2 = 0;

You don't want to do this in the ISR. The whole point of CTC mode is that it automatically resets to 0 on compare match.

You are not following the procedure outlined in the datasheet. Read the steps necessary under the "Asynchronous Operation of Timer/Counter 2" section).

Regards,
Steve A.

The Board helps those that help themselves.

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

What is the precise frequency of the led ?
Can you measure it (tie a photodiode to the mic-input of your computer, and record it with audacity), or count it (count the blinks during 1 minute).

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

Quote:

I used Timer 2 in CTC mode instead of overflow...

Fair enough. Note that on that particular AVR model and timer, there is a /128 prescaler available --such that 32kHz watch crystal overflowing at /128 is one second.

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

@Koshchi Thanks, but commenting out the line did not help. I'd imagine it's a clock cycle or two wasted, will help for precision once I get this nailed down, but not the source of this particular problem.

@theusch I have tried prescalar /1024 with 32 ticks to overflow, /256 with 128 ticks to overflow (as shown), and /128 with overflow mode. Same behavior.

@Kun.io :
The weirdest thing happened when I went to plug my Arduino into the circuit to get an accurate count per minute... the ATMega328P LED started binking at 1Hz as desired. Removing the common power leads and the thing returns to ~2-3Hz. Multimeter says 4.97V without arduino+USB, 5.04V with. Maybe it's my 7805 that is causing the problem? Seems odd to be so sensitive to a couple of millivolts of supply power. Will keep trying power supply options and report back.

Thanks!

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

Quote:

Seems odd to be so sensitive to a couple of millivolts of supply power.

Inded. It could well be crystal selection, stray capacitance, or the like.

How have you connected your crystal? "Straight on"? Does it follow the guidelines for attaching watch crystals, as outlined in migration app notes?

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

Thanks for the reco theusch, the migration app notes are informative.

Crystal is connected straight on, with the least amount of distance possible between chip and crystal. No caps atm. However, it's on a solder-less breadboard, so there's bound to a good amount of stray capacitance. I am hoping it is passable accuracy for testing, and perhaps when I move to PCB I can design with stray capacitance in mind.

So far I've found any use of 7805s produces the same result, the frequency increases to 2-3Hz: way off. It might be the lack of caps on either side of the regulator, so I am tacking a few stabilizing caps to my next digikey order. For the time being, I'm using a 5V wall wort and no 7805. The timing looks stable at 1Hz, but I am whipping up a program to test the drift over a day or so.

Thanks again!

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

MattB33 wrote:
... It might be the lack of caps on either side of the regulator ...

You found the problem already, but I just want to mention that a 7805 without two 100nF will cause noise.
Some crystals are not very stable anyway. The most common problem is that they oscillate at 2e or 3e or 4e overtone frequency.

The crystal can probably do without caps, as you wrote. But the avr chip, and the 7805 need their 100nf (badly).

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

The 2-3Hz thing could be caused by MCU resetting.

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

Problem solved with two 100nF caps on the two power inputs to the 328p, and one 22uF on the 7805. Not sure which of these is strictly necessary, but I have no problems designing with both for the time being.

Just wanted to write in and thank you all for the input, and post the solution for anyone who runs into similar issues.

Now on to accuracy testing...

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

Read up the 7805 data sheet. It needs 100nF caps too.

Pleased that you have it working.

David.