Go Down

Topic: Can't find old topic on clock compensation (Read 4905 times) previous topic - next topic

#60
Feb 01, 2013, 06:19 am Last Edit: Feb 01, 2013, 06:25 am by Nick Gammon Reason: 1
Just to prove it to myself, I made this amended sketch:

Code: [Select]

#include <avr/sleep.h>
#include <avr/power.h>

const byte tick = 3;

// interrupt on Timer 2 compare "A" completion - does nothing
EMPTY_INTERRUPT (TIMER2_COMPA_vect);

void setup()
{
 pinMode (tick, OUTPUT);
 
 // clock input to timer 2 from XTAL1/XTAL2
 ASSR = _BV (AS2);  

 // set up timer 2 to count up to 32 * 1024  (32768)
 TCCR2A = _BV (WGM21);                             // CTC
 TCCR2B = _BV (CS20) | _BV (CS21) | _BV (CS22);    // Prescaler of 1024                                  
 OCR2A =  31;              // count to 32 (zero-relative)                  

 // enable timer interrupts
 TIMSK2 |= _BV (OCIE2A);
 
 // disable ADC
 ADCSRA = 0;  
 
 // turn off everything we can
 power_adc_disable ();
 power_spi_disable();
 power_twi_disable();
 power_timer0_disable();
 power_timer1_disable();
 power_usart0_disable();
 
 // full power-down doesn't respond to Timer 2
 set_sleep_mode (SLEEP_MODE_PWR_SAVE);  

 // get ready ...
 sleep_enable();
 
 }  // end of setup

void loop()
 {

 // turn off brown-out enable in software
 MCUCR = _BV (BODS) | _BV (BODSE);
 MCUCR = _BV (BODS);
 
 // sleep, finally!
 sleep_cpu ();  

 // we awoke! pulse the clock hand
 digitalWrite (tick, ! digitalRead (tick));
 
 }  // end of loop


With the 32.768 KHz crystal the LED (on pin 3 toggles every second). Now as this is under software control, you could do anything you want in the main loop, instead of the digitalWrite (eg. update a display).

The current consumption, when the LED is not lit, was 1.46 uA, which is pretty low.

(edit) And 1.1 uA at 3.3V power supply.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

randomizer


Just to prove it to myself, I made this amended sketch:


Okay, I am seriously upset/confused right now.

When I use your code (with the EMPTY_INTERRUPT), changing the value of OCR2A changes the frequency of the blinking. As expected.

If I change EMPTY_INTERRUPT to an ISR, move the digitalWrite up into the ISR, and comment out all the sleepy-stuff, changing OCR2A has no effect at all. Zip. Nada. Using the exact same TCCR2A/B values. The frequency is always the base frequency of the prescaler, as if OCR2A is 0.

What am I not seeing here?

Post the amended sketch, don't just describe it.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

randomizer

Code: [Select]


#include <avr/sleep.h>
#include <avr/power.h>

const byte tick = 11;

// interrupt on Timer 2 compare "A" completion - does nothing
ISR(TIMER2_COMPA_vect) {
  digitalWrite (tick, ! digitalRead (tick));
}

void setup()
{
  pinMode (tick, OUTPUT);
 
  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = _BV (AS2); 

  // set up timer 2 to count up to 32 * 1024  (32768)
  TCCR2A = _BV (WGM21);                             // CTC
  TCCR2B = _BV (CS20) | _BV (CS21) | _BV (CS22);    // Prescaler of 1024                                 
  OCR2A =  15;              // count to 32 (zero-relative)                 

  // enable timer interrupts
  TIMSK2 |= _BV (OCIE2A);
/* 
  // disable ADC
  ADCSRA = 0; 
 
  // turn off everything we can
  power_adc_disable ();
  power_spi_disable();
  power_twi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_usart0_disable();
 
  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE); 
 
  // get ready ...
  sleep_enable();
  */
  }  // end of setup

void loop()
  {
/*
  // turn off brown-out enable in software
  MCUCR = _BV (BODS) | _BV (BODSE);
  MCUCR = _BV (BODS);
 
  // sleep, finally!
  sleep_cpu (); 

  // we awoke! pulse the clock hand
  digitalWrite (tick, ! digitalRead (tick));
  */
  }  // end of loop


Always blinks at 15.99 Hz, regardless of ACR2A.
Thanks!

To save fetching out the board with the extra crystal, I tried on my Uno this slight variation:

Code: [Select]

const byte tick = 11;

// interrupt on Timer 2 compare "A" completion
ISR(TIMER2_COMPA_vect)
 {
 digitalWrite (tick, ! digitalRead (tick));
 }

void setup()
{
 pinMode (tick, OUTPUT);
 
 // clock input to timer 2 from XTAL1/XTAL2
 ASSR = _BV (AS2);  

 // set up timer 2 to count up to 32 * 1024  (32768)
 TCCR2A = _BV (WGM21);                             // CTC
 TCCR2B = _BV (CS20) | _BV (CS21) | _BV (CS22);    // Prescaler of 1024                                  
 OCR2A =  63;              // count to 64 (zero-relative)                  

 // enable timer interrupts
 TIMSK2 |= _BV (OCIE2A);
 }  // end of setup

void loop() { }


This gave a frequency of 122 Hz as predicted by the theory:

Code: [Select]
1 / (1/16e6 * 1024 * 64) / 2 = 122.0703125

You divide by 2 because it takes two pulses to complete one cycle. Changing OCR2A changed the frequency.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

randomizer

I've still got the problem. Changing the prescaler changes the frequency; changing OCR2A changes absolutely nothing. I guess there's something screwy inside the chip, and I'll just work around that in my code.

Are you measuring the right pin?

Sometimes I found that where the OCR2A line was affected thing. Try moving that line earlier up.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

randomizer

Well! I tried moving the OCR2A line up; nothing changed. I added the TCCR2A = 0 and TCCR2B = 0 lines at the top and it works! Which is strange, because in other non-working sketches I've tried it hasn't worked. Must've been a combination of that and moving the OCR2A line.

Adding those lines stops the timer. I think in some modes the OCR2A changes are buffered, so it makes some sense to stop it first.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up