Accessing 16bit Timer/OCR Registers

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

Hello,

I have 2 questions related to accessing 16bit Timer values and setting OCR values on the ATMega128.

I was reading the recommended procedure for accessing the 16 bit Timer values on the ATMega128 data sheet, and they give the following recommended code excerpt:

unsigned int TIM16_ReadTCNTn( void )
{
unsigned char sreg;
unsigned int i;

sreg = SREG; // Save global interrupt flag 
__disable_interrupt();  // Disable interrupts 
i = TCNTn;  // Read TCNTn into i
SREG = sreg;  // Restore global interrupt flag 
return i;
}

My question is... should this same procedure be followed for accessing or setting 16bit OCR registers? I have found instances where I set the value of an OCR in my main() loop with a statement like:

OCR1A = 5000;

and later discover that the value actually stored in OCR1A was something different, like 247, for example. I detected this by reading the OCR1A value into another variable, and then setting a break point to stop the code if the accessed value was ever different from what was expected. This does not happen very often, but enough to make me try to track down what the problem was in my code. So I have finally isolated my problem to be my OCR registers sometimes taking on values other than what I was setting them to. Should global interrupts always be disabled prior to accessing or setting any 16bit register on the ATMega128? Also, must you first save the SREG value before disabling global interrupts, as the recommended code excerpt suggests? Is it not enough to just disable global interrupts, access the register, and then re-enable? By saving the SREG value, performing an operation, and then reloading the SREG value, could you lose any information on incoming interrupts during that period?

Any comments would be appreciated. Thank you very much!

- James

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

jdowns wrote:
My question is... should this same procedure be followed for accessing or setting 16bit OCR registers?

You should follow this procedure for any 16-bit register access that uses the 8-bit temporary High Byte Register (TEMP). If an interrupt handler performs a 16-bit register access that uses the TEMP register, it can cause an interrupted access to be corrupted. The same TEMP register is shared among all 16-bit registers within each 16-bit timer.

Note that reading a 16-bit OCR register does not use the TEMP register; writing a 16-bit OCR register does.

Now, if your interrupt handlers don't access 16-bit timer registers, you can get away with not disabling interrupts during 16-bit register access the use the TEMP register.

Don

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

Don,

Thank you very much for that extremely useful information! I *did* have interrupts that were accessing 16-bit timers, so perhaps that was when the write to my OCR registers was being corrupted. Thank you for explaining how these registers are interconnected, as well. It was useful to know, for instance, that I can read the OCR value without using the TEMP register. You've just saved me a lot of time in further debugging!

Thanks again,
James